I'm trying to create 2 OptionMenu
s that depend on each other in a way that the selection on the first will provide different options for the second.
I was able to link those two together using trace
.
Both OptionMenu
s are linked to a command and whenever a selection is made, a message is printed on the terminal.
Although this works for the first OptionMenu
, I can't get to print anything when making a selection on the second. Note that if I the two OptionMenus
aren't dynamically linked to each other (i.e. if they are constructed as separate widgets) printing works great for both of them.
Any idea on what might be the issue?
Here's a code that illustrates the issue.
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()
If you comment out the line
var_ADC_range.trace('w', update_options)
, the following happens:charge_sensitivity_selection
function is called~!@#$%^&*()_+
printedThis means that the
update_options
function overwrites the command that will be called when an entry within the "Charge sensitivity" menu is selected. This happens in the line:One could try to replace the
lambda
expression in the line above with a function object like this:I use the function object to pass the
sens
parameter, there seems to be noevent
when the function is called.I'm not that deep into
tkinter
and I have never usedtrace
, so most probably there are easier solutions.