Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save cpatdowling/6f78a4e5eb95416e1e6aeb541bc9074f to your computer and use it in GitHub Desktop.
Save cpatdowling/6f78a4e5eb95416e1e6aeb541bc9074f to your computer and use it in GitHub Desktop.
An abuse of python globals() method to dynamically generate sequentially named functions; this was used to automatically populate buttons in a passive, same-thread GUI using tkinter
#credit to StackOverflow user yann-vernier for means of abuse of globals()
#https://stackoverflow.com/questions/49631178/using-for-loop-to-define-multiple-functions-python
import time
import tkinter as tk
from types import FunctionType
from copy import copy
#The GUI will print filenames and some filename feature when button presses are passively detected
flag = False # Global flag to detect button presses
running_variable = "file_0"
button_names = ["file_1", "file_2", "file_3", "file_4"]
#function that returns specially named function with specified arguments
def create_button_function(fn, name):
return FunctionType(copy(fn.__code__),
copy(fn.__globals__), name=name, argdefs=copy(fn.__defaults__),
closure=copy(fn.__closure__))
button_funcs = [] #keep track of button target function handles
button_names = [] #keep track of button names to make populating the GUI easier
for i in range(len(button_names)):
n = "print_" + button_names[i]
def _printfilename():
global flag #reset global flag variable
flag = True #indicate that this button has been pressed for when GUI is next updated
#do some things that you want a button to do
global running_variable
running_variable = button_names[i] #update some value used by the main loop
return(print(n), "| length of filename: ", len(n))
globals()[n] = create_button_function(_printfilname, n)
button_funcs.append(globals()[n])
button_names.append(n)
#initialize GUI app
root = tk.Tk()
root.title("GUI")
app = tk.Frame(root)
app.grid()
#populate the buttons in the app
for j in range(len(button_funcs)):
tk.Button(app, text=button_names[j], command=button_funcs[j]).grid()
loop_idx = 0
while True:
#passively check if button has been pressed to avoid needing additional thread for GUI
if loop_idx % 3 == 0
root.update()
if flag:
print("Button pressed")
flag = False
#do other things that depend on the update from the GUI
print("Current value of running variable is: " + running_variable)
loop_idx += 1
time.sleep(1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment