我正在使用 tkinter 作為 GUI 框架在 python 中撰寫應用程式。我將串列選單命令保存在 SQL 表中,并遍歷所有選定的行以構建選單。到目前為止,這運行良好,但是單擊選單項時我無法使命令起作用。SQL 表有 4 列 ID、標簽、命令、父級。所以表格的示例行看起來像
1、新建、占位符()、rootFile
當我單擊“新建”命令時,沒有任何反應。如果我用 placeholder() 替換 row[2],它會按預期作業,不幸的是,這不允許我為 SQL 資料庫中存盤的每個選單項指定不同的命令。
import pyodbc #needed for database connectivity
from tkinter import * #imports GUI objects
from tkinter import ttk #imports themed widgets for GUI
from database_connect import SQL_CONNECT
setupSQL = SQL_CONNECT('Server=MILLER2021;','Database=DRAWINGTOOL_DB;') #establish connection to SQL database that contains startup info for applicaton
setupCursor = setupSQL.cursor() #creates a cursor object for the SQL connection for setting up application
root = Tk() #creates top level window widget
root.title("Drawing Tool") #defines the title of root
root.geometry("400x300") #define the size of root
def placeholder():
print("This is an ouptut from a placeholder function")
##Define Menu Bar##
rootMenuBar = Menu(root)
rootFile = Menu(rootMenuBar, tearoff=0)
rootMenuBar.add_cascade(label="File", menu=rootFile) #displays item on menu
setupCursor.execute("SELECT * FROM MENU_COMMANDS WHERE PARENT LIKE 'rootFile'") #selects all commands from SQL database to be added to rootFile menu
for row in setupCursor: #iterate through all rows selected from previous cursor execute query
rootFile.add_command(label=row[1], command=row[2]) #adds new item to the file dropdown
root.config(menu=rootMenuBar) #displays menuBar in root menu
root.mainloop() #keeps code running
uj5u.com熱心網友回復:
使用存盤在資料庫中的函式名稱并在其中查找它們的想法globals()聽起來像是不幸的設計;這種方法遲早會導致安全問題(Unsafe Reflection),因為有很多事情globals()是你不希望人們呼叫的。如果可能的話,最好避免它。
更好的方法是在代碼中直接撰寫的表中查找名稱;就像是:
COMMAND_TABLE = {
'placeholder': placeholder,
...: ...,
}
...
for row in setupCursor:
rootFile.add_command(label=row[1], command=COMMAND_TABLE[row[2]])
(加上查找引發 KeyError 時的適當處理)
除了更安全之外,這也會更靈活,將代碼中的名稱與資料庫中的名稱解耦。例如,如果您決定placeholder將其重命名place_holder并移至另一個模塊,則最終可能會得到如下結果:
COMMAND_TABLE = {
'place_holder': another_module.place_holder,
'placeholder': another_module.place_holder, # old name for compatibility with existing databases
...: ...,
}
uj5u.com熱心網友回復:
第一:當您選擇選單時,command=期望沒有函式的名稱(),然后它將()用于運行此函式。
它必須是真實姓名,而不是"placeholder"來自資料庫的字串。
它可能需要使用globals()才能真正訪問功能placeholder
command = globals()["placeholder"]
最小作業代碼:
def placeholder():
print('test placeholder')
func = globals()["placeholder"]
func()
import tkinter as tk # PEP8: `import *` is not preferred
# --- functions ---
def placeholder():
print("This is an ouptut from a placeholder function")
# --- main ---
root = tk.Tk()
root_menubar = tk.Menu(root) # PEP8: `lower_case_names`
root_file = tk.Menu(root_menubar, tearoff=0)
root_menubar.add_cascade(label="File", menu=root_file)
root_file.add_command(label='Placeholder', command=globals()["placeholder"])
root.config(menu=root_menubar)
root.mainloop()
編輯:
正如@acw1668 在評論中提到的:最好使用.get("placeholder", None)而不是["placeholder"]因為它def placeholder不存在時不會引發錯誤
root_file.add_command(label='Placeholder', command=globals().get("placeholder", None))
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/383484.html
上一篇:Tkinter按鈕放置垂直拉伸
