[英]Tkinter: function doesn't print when option menus are dynamically linked
我正在尝试创建 2 个相互依赖的OptionMenu
,以使第一个上的选择将为第二个提供不同的选项。
我能够使用trace
将这两个链接在一起。 两个OptionMenu
都链接到一个命令,每当做出选择时,都会在终端上打印一条消息。
虽然这适用于第一个OptionMenu
,但在第二个进行选择时我无法打印任何内容。 请注意,如果两个OptionMenus
没有动态链接到彼此(即,如果它们被构造为单独的小部件),则打印对它们都非常有用。
关于可能是什么问题的任何想法?
这是说明问题的代码。
import tkinter as tk
from tkinter import *
from tkinter import ttk
from tkinter import messagebox
from PIL import ImageTk, Image
import os
#____________________________________________________________________________________________
#This will be the main window
window = tk.Tk()
window.geometry('700x700')
window.title("daq")
#____________________________________________________________________________________________
#Lower frame
frame_main = Frame(window)
frame_main.place(rely=0.10, relx=0.0, relwidth=1.0)
#Create a tabcontrol
tabControl = ttk.Notebook(frame_main)
tabControl.grid(column=0, row=1)
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Digitizer tab
tab_Digitizer = ttk.Frame(tabControl)
tabControl.add(tab_Digitizer, text=' Digitizer ')
digitizer_tab_dummy_label = Label(tab_Digitizer, text="")
digitizer_tab_dummy_label.grid(column=0, row=0)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Channel settings
frame_channel_registers = Frame(tab_Digitizer)
frame_channel_registers.grid(column=0, row=4)
#Channel settings - general
frame_general_channel_registers = Frame(frame_channel_registers)
frame_general_channel_registers.grid(column=0, row=2, padx=25, sticky=W)
#Channel settings - PSD
frame_PSD_channel_registers = Frame(frame_channel_registers)
frame_PSD_channel_registers.grid(column=0, row=4, padx=25, sticky=W)
#Charge sensitivity
def charge_sensitivity_selection(event):
print ("~!@#$%^&*()_+")
#print ("Charge sensitivity :", var_charge_sensitivity.get() )
pass
lbl_charge_sensitivity = Label(frame_PSD_channel_registers, text="Charge sensitivity")
lbl_charge_sensitivity.grid(column=0, row=3, padx=25, sticky=W)
var_charge_sensitivity = StringVar(frame_PSD_channel_registers)
charge_sensitivity = OptionMenu(frame_PSD_channel_registers, var_charge_sensitivity, '', command=charge_sensitivity_selection)
charge_sensitivity.grid(column=1, row=3, sticky=W)
#ADC range
def update_options(*args):
adc_range=opt_ADC_range[var_ADC_range.get()]
var_charge_sensitivity.set(adc_range[0])
menu = charge_sensitivity['menu']
menu.delete(0, 'end')
for adc in adc_range:
menu.add_command(label=adc, command=lambda sens=adc: var_charge_sensitivity.set(sens) )
def ADC_range_selection(event):
print ("ADC range :", var_ADC_range.get() )
pass
lbl_ADC_range = Label(frame_general_channel_registers, text="ADC range")
lbl_ADC_range.grid(column=0, row=1, padx=25, sticky=W)
opt_ADC_range = {'0.5':['1.25', '5', '20', '80', '320', '1280'], '2':['5', '20', '80', '320', '1280', '5120']}
var_ADC_range = StringVar(frame_general_channel_registers)
var_ADC_range.trace('w', update_options)
ADC_range = OptionMenu(frame_general_channel_registers, var_ADC_range, *opt_ADC_range.keys(), command = ADC_range_selection)
var_ADC_range.set('2')
ADC_range.grid(column=1, row=1, sticky=W)
#This keeps the window open - has to be at the end
window.mainloop()
如果您注释掉var_ADC_range.trace('w', update_options)
行,会发生以下情况:
charge_sensitivity_selection
function 被称为~!@#$%^&*()_+
打印这意味着update_options
function 会覆盖选择“充电灵敏度”菜单中的条目时将调用的命令。 这发生在以下行中:
menu.add_command(label=adc, command=lambda sens=adc: var_charge_sensitivity.set(sens) )
可以尝试用 function object 替换上面一行中的lambda
表达式,如下所示:
...
charge_sensitivity.grid(column=1, row=3, sticky=W) # <- your code
class run_on_charge_sens_selection(object): # <- the function object
def __init__(self, sens):
self.sens = sens
def __call__(self):
# this function is called on menu selection
var_charge_sensitivity.set(self.sens)
charge_sensitivity_selection(self.sens)
#ADC range # <- again your code
def update_options(*args):
adc_range=opt_ADC_range[var_ADC_range.get()]
var_charge_sensitivity.set(adc_range[0])
menu = charge_sensitivity['menu']
menu.delete(0, 'end')
for adc in adc_range: # and now we use the function object
# instead of the lambda expression
menu.add_command(label=adc, command=run_on_charge_sens_selection(adc))
...
我使用 function object 传递sens
参数,调用 function 时似乎没有event
。
我对tkinter
并没有那么深入,而且我从未使用过trace
,所以很可能有更简单的解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.