Python / Tkinter IntVar不更新Label

时间:2013-11-13 23:25:47

标签: tkinter

帮助!

我创建了一个模仿机顶盒的简单GUI。所有功能都在工作,除了一个。

当输入从“电视”更改为“广播”时,我希望显示“频道”的标签恢复为1。

与标签关联的IntVar是self.chan_value。我试图设置radiobuttons选项命令= self.chan_value.set(1),但是当我按下radiobuttons时仍然没有任何反应。

使用self.chan_value.set(1)似乎在连接到通道输入框的函数调用时工作正常,但我没有运气让无线电按钮工作。

我尝试过定义一个方法:

def chan_resetter(self):   
     self.chan_value.set(1)

但这似乎与设置命令不同。 这是我的代码。问题出在“输入框架”部分,有两个单选按钮tv_rb和radio_rb

import tkinter
import tkinter.messagebox


class MySetTopBox:


    def __init__(self):


        self.main_window = tkinter.Tk()

        # frames
        self.power_frame = tkinter.Frame(self.main_window)
        self.input_frame = tkinter.Frame(self.main_window)

        # (channel frames)
        self.top_frame = tkinter.Frame(self.main_window)
        self.mid_frame = tkinter.Frame(self.main_window)

        self.volume_frame = tkinter.Frame(self.main_window)
        self.quit_frame = tkinter.Frame(self.main_window)



        # channel frame

        # top frame
        self.desc_label = tkinter.Label(self.top_frame, text='CHANNEL:')
        self.chan_value = tkinter.StringVar()
        self.chan_value.set(1)
        self.chan_label = tkinter.Label(self.top_frame, textvariable = self.chan_value)        

        self.desc_label.pack(side='left')
        self.chan_label.pack(side='left')

        # mid frame
        self.change_button = tkinter.Button(self.mid_frame, text='Change Channel', command= self.channel_function)
        self.chan_entry = tkinter.Entry(self.mid_frame, width = 10)

        self.chan_entry.pack(side='left') 
        self.change_button.pack(side='left')



        # input frame 

        chan_resetter = self.chan_value.set(1)

        self.input_var = tkinter.IntVar()
        self.input_var.set(1)

        self.input_label = tkinter.Label(self.input_frame, text='INPUT')
        self.tv_rb = tkinter.Radiobutton(self.input_frame, text='TV', variable=self.input_var, value = 1, command= chan_resetter, indicatoron=0, width=5, padx=20)
        self.radio_rb = tkinter.Radiobutton(self.input_frame, text='RADIO', variable=self.input_var, value = 2, command= chan_resetter, indicatoron=0, width=5, padx=20)

        self.input_label.pack()
        self.tv_rb.pack(side='left')
        self.radio_rb.pack(side='left')



        # volume frame
        self.volume_var = tkinter.IntVar()
        self.volume_var.set(5)

        self.volume_label = tkinter.Label(self.volume_frame, text='VOLUME')
        self.volume_scale = tkinter.Scale(self.volume_frame, from_=0, to_=10, variable=self.volume_var)

        self.volume_label.pack(side='top')
        self.volume_scale.pack(side='left')        



        # quit frame

        self.quit_button = tkinter.Button(self.quit_frame, text='Quit', command= self.main_window.destroy)
        self.quit_button.pack(side='left') 

        self.power_var = tkinter.IntVar()
        self.power_var.set(2)



        # power frame
        self.casey_label = tkinter.Label(self.power_frame, text="Casey's Set Top Box")
        self.power_label = tkinter.Label(self.power_frame, text='POWER')
        self.on_rb = tkinter.Radiobutton(self.power_frame, text='ON', variable=self.power_var, value=1,command=self.default_function())
        self.off_rb = tkinter.Radiobutton(self.power_frame, text='OFF', variable=self.power_var, value=2)

        self.casey_label.pack(side='top')
        self.power_label.pack()
        self.on_rb.pack(side='left')
        self.off_rb.pack(side='left')      



        # pack frames

        self.power_frame.pack()
        self.input_frame.pack()
        self.top_frame.pack()
        self.mid_frame.pack()
        self.volume_frame.pack()
        self.quit_frame.pack()


        tkinter.mainloop()



    def default_function(self):
        self.input_var.set(1)
        self.chan_value.set(1)
        self.volume_var.set(5)     
        #include messagebox? 'you have turned the power off'



    def channel_function(self):
        new_chan = int(self.chan_entry.get())
        input_current = self.input_var.get()
        power_off = self.power_var.get()
        if power_off ==2:
            tkinter.messagebox.showinfo('Error', 'Turn Set Top Box power ON first') 

        elif input_current == 1 and new_chan > 30:
            tv_error = 'ERROR: TV channels range from 1 to 30'
            tkinter.messagebox.showinfo('Error', tv_error)

        elif input_current == 2 and new_chan > 12:
            radio_error = 'ERROR: Radio channels range from 1 to 12'
            tkinter.messagebox.showinfo('Error', radio_error)

        else:
            self.chan_value.set(new_chan)


    def volume_function(self):
        vol_entered = self.volume_var.get()
        self.volume_var.set(vol_entered) 



my_stb = MySetTopBox()

print (my_stb.input_var.get())
print (my_stb.chan_value.get())
print (my_stb.volume_var.get())

1 个答案:

答案 0 :(得分:0)

使用lambda功能

command=lambda:self.chan_value.set(1)

self.tv_rb = tkinter.Radiobutton(self.input_frame, text='TV', variable=self.input_var, value = 1, command=lambda:self.chan_value.set(1), indicatoron=0, width=5, padx=20)

或以这种方式创建函数chat_resetter

def chan_resetter():
   self.chan_value.set(1)

self.tv_rb = tkinter.Radiobutton(self.input_frame, text='TV', variable=self.input_var, value = 1, command=chan_resetter, indicatoron=0, width=5, padx=20)

chan_resetter必须在__init__内作为其他说明(相同的缩进) - 它不是MySetTopBox类中的另一个函数,而是__init__的一部分


但你可以将chan_resetter定义为类MySetTopBox

中的另一个函数
def chan_resetter(self):
   self.chan_value.set(1)

然后使用lambda来调用它

command=lambda:chan_resetter(self)

chan_resetter = self.chan_value.set(1)

上面的代码意味着 - 将chan_value设置为1并将结果分配给chan_resetterself.chan_value.set(1)作为结果提供None,以便获得chan_resetter = None

command=self.chan_value.set(1)

上面的代码表示相同 - 运行self.chan_value.set(1)并将结果分配给command,以便获得command=None