【问题标题】:Python Tkinter: Why is my if...elif statement not working with a StringVar()?Python Tkinter:为什么我的 if...elif 语句不能与 StringVar() 一起使用?
【发布时间】:2021-09-18 12:15:01
【问题描述】:

我知道这段代码需要改进,但首先我不明白为什么 sample_choice a tk.StringVar() 似乎没有传递给我的 if...elif 块。我正在尝试对代码执行的操作是根据组合框中的选择显示某些标签,该组合框将其当前状态保存在 sample_choice 中。似乎在第一次执行此函数后,即使在主循环中调用了该函数,程序也永远不会循环回该函数,并且永远不会到达 if...elif 块以对组合框中新选择的值执行操作.我想我在这里遗漏了一些非常基本的东西。如果需要更多信息,请告诉我,我将上传此功能所属的课程。提前致谢!

def pin_interface(self):
    
        path = "Images\\Sample.png"
        sample_choice = tk.StringVar()
        samples = ("Sample A", "Sample B")
        pin_index = ("A1:", "A2:", "A3:", "A4:","B1:", "B2:", "B3:", "B4:")
 

        sample_img = ImageTk.PhotoImage(file = path)
        img_label = ttk.Label(self.settings_subframe_2_1, image = sample_img)          
        img_label.image = sample_img
        img_label.grid(row = 0 , column = 0)
        
        
        label_1 = ttk.Label(self.settings_subframe_2_1, text = "Select a Sample:")
        label_1.grid(row = 1, column = 0)
        
        option_1 = ttk.Combobox(self.settings_subframe_2_1, textvariable = sample_choice, values = samples, width = len(samples[0])+1)
        option_1.grid(row = 2, column = 0)
           
        pin_label_a1 = ttk.Label(self.settings_subframe_2_1, text = pin_index[0])
        pin_label_a2 = ttk.Label(self.settings_subframe_2_1, text = pin_index[1])
        pin_label_a3 = ttk.Label(self.settings_subframe_2_1, text = pin_index[2])
        pin_label_a4 = ttk.Label(self.settings_subframe_2_1, text = pin_index[3])
        
        pin_label_b1 = ttk.Label(self.settings_subframe_2_1, text = pin_index[4])
        pin_label_b2 = ttk.Label(self.settings_subframe_2_1, text = pin_index[5])
        pin_label_b3 = ttk.Label(self.settings_subframe_2_1, text = pin_index[6])
        pin_label_b4 = ttk.Label(self.settings_subframe_2_1, text = pin_index[7])
    
        
    
        if sample_choice.get() == samples[0]:
        

                pin_label_b1.grid_forget()
                
                pin_label_b2.grid_forget()
        
                pin_label_b3.grid_forget()
        
                pin_label_b4.grid_forget()
                    
                    
                pin_label_a1.grid(row = 3 , column = 0, sticky = "W")
                
                pin_label_a2.grid(row = 4 , column = 0, sticky = "W")
        
                pin_label_a3.grid(row = 3 , column = 1, sticky = "W")
        
                pin_label_a4.grid(row = 4 , column = 1, sticky = "W")
        
        
        elif sample_choice.get() == samples[1]:
                    
                pin_label_a1.grid_forget()
                
                pin_label_a2.grid_forget()
        
                pin_label_a3.grid_forget()
        
                pin_label_a4.grid_forget()
                
            
                pin_label_b1.grid(row = 3 , column = 0)
                
                pin_label_b2.grid(row = 4 , column = 0)
        
                pin_label_b3.grid(row = 3 , column = 1)
        
                pin_label_b4.grid(row = 4 , column = 1)

【问题讨论】:

  • 您在创建 ComboBox 大约一毫秒后测试它的值。用户实际上不可能做出任何选择。
  • 对,但是这段代码不是使用 Tk 类的 mainloop 方法在循环中运行的吗?我的想法是,用户进行了更改,并且在下一个循环中将获取更改。
  • 如果这段代码循环运行,每次都会创建一个新的组合框和标签。
  • 如果pin_interface 是一个类的函数,只有在通过该类的对象显式调用它时才会调用它。 tkinter 中的Mainloop 告诉 Python 运行 Tkinter 事件循环。此方法侦听事件,例如按钮单击或按键,并阻止在它之后运行的任何代码,直到它被调用的窗口关闭。所以,你的pin_interface函数并不是每毫秒都会被调用一次,它只会在你真正调用它的时候被调用。
  • 要在 if...elif 块中循环,在用户在Combobox 中进行选择后,您可以添加一个button,单击时将调用函数pin_interface(通过按钮command)

标签: python-3.x if-statement tkinter spyder


【解决方案1】:

代码不起作用,因为您甚至在窗口显示之前检查了选择。您应该在用户更改 Combobox 的值后检查选择。

为此,您最好将组合框中的更改事件绑定到一个检查值并采取行动的函数。我建议将 StringVar 作为 tkinter 小部件的属性,以便可以从所有方法访问它:

[...]
self. sample_choice = tk.StringVar() ## Make it an attribute of self

[...]
option_1 = ttk.Combobox(self.settings_subframe_2_1, textvariable = self.sample_choice, values = samples, width = len(samples[0])+1)
option_1.grid(row = 2, column = 0)
option_1 .bind("<<ComboboxSelected>>", self.check_value)

然后,您只需将完整的 if 块移动到 self 的新方法,称为 .check_value()

def check_value(self):
    if self.sample_choice.get() == samples[0]:
         pin_label_b1.grid_forget()
         pin_label_b2.grid_forget()
    [...]

现在,只要您更改组合框的选择,就会执行此方法。

【讨论】:

  • 这对我有用,感谢您的帮助!
猜你喜欢
  • 2020-05-06
  • 2016-12-08
  • 2015-03-27
  • 2022-11-03
  • 1970-01-01
  • 2019-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多