如何解决Tkinter:选项菜单动态链接时不打印功能
我正在尝试创建 2 个相互依赖的 OptionMenu
,第一个的选择将为第二个提供不同的选项。
我能够使用 trace
将这两个链接在一起。
两个 OptionMenu
都链接到一个命令,无论何时做出选择,都会在终端上打印一条消息。
虽然这适用于第一个 OptionMenu
,但在第二个进行选择时我无法打印任何内容。请注意,如果 I 两个 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,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,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,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,sticky=W)
opt_ADC_range = {'0.5':['1.25','5','20','80','320','1280'],'2':['5','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,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
函数 - -> 您会看到打印的
~!@#$%^&*()_+
这意味着 update_options
函数会覆盖选择“电荷灵敏度”菜单中的条目时将调用的命令。这发生在行中:
menu.add_command(label=adc,command=lambda sens=adc: var_charge_sensitivity.set(sens) )
可以尝试用这样的函数对象替换上面一行中的 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))
...
我用函数对象传递了sens
参数,调用函数的时候好像没有event
。
我对 tkinter
不是很深入,而且我从未使用过 trace
,所以很可能有更简单的解决方案。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。