单击或移动鼠标时,Tkinter GUI不会响应(for循环)

时间:2017-11-07 06:47:19

标签: for-loop tkinter python-multithreading

我刚刚编写了一个简单的自动化程序来使用Tkinter GUI进行测试工作。 其他一切都很好,除非我有移动或点击鼠标等操作,GUI将无法响应,但代码仍在运行。循环完成后,GUI进入正常状态。这是我的代码的一部分(仅用于循环,我的代码有点长,例如硬件设置和获取。)

    for i in range(0, loop_number):
        power_supply = str(input.iloc[i][0]).split(',')
        channel1 = int(power_supply[0])
        voltage1 = float(power_supply[1])
        current1 = power_supply[2]
        self.power_channel_text.delete(1.0, END)
        self.power_channel_text.insert(1.0, channel1)
        self.voltage_text.delete(1.0, END)
        self.voltage_text.insert(1.0, voltage1)
        self.current_compliance_text.delete(1.0, END)
        self.current_compliance_text.insert(1.0, current1)

        Aardvark = str(input.iloc[i][2]).split(',')
        register_values = []
        start_address = Aardvark[0]
        for n in range(0, len(Aardvark[1].split(' '))):
            register_values.append(int(Aardvark[1].split(' ')[n], 16))
        self.aardvark_write_Address_text.delete(1.0, END)
        self.aardvark_write_Address_text.insert(1.0, start_address)
        self.aardvark_i2c_write_value_text.delete(1.0, END)
        self.aardvark_i2c_write_value_text.insert(1.0, str(Aardvark[1]))

        temp = str(input.iloc[i][3]); save_path = str(input.iloc[i][4])
        self.temperature_text.delete(1.0, END)
        self.temperature_text.insert(1.0, temp)
        self.save_path_text.delete(1.0, END)
        self.save_path_text.insert(1.0, save_path)
        part = str(input.iloc[i][5]); Label = str(input.iloc[i][6])  
        self.progress_bar['value'] = 5 + step * (i + 1)
        self.root.update_idletasks()
        time.sleep(5)

在循环之外,我已经初始化了我的文本值和进度条值。我在网上搜索教程,找到了两个解决方案。一个是使用多线程,另一个是使用后功能。但是,当我只有运行按钮时会发生其他触发事件时使用它们。之后,我只想更新每次运行的文本值和进度条值。请问有人能给我一些建议吗?非常感谢你。

1 个答案:

答案 0 :(得分:2)

这里发生的事情是您阻止GUI注册事件,因为它太忙于执行代码。你想要的是运行代码的一次迭代,然后在再次尝试之前将控制权返回给GUI 5毫秒,而不是只是睡眠整个线程。请尝试以下方法:

def perform_loop(self, remaining):
    if remaining < 0: return

    power_supply = str(input.iloc[i][0]).split(',')
    channel1 = int(power_supply[0])
    voltage1 = float(power_supply[1])
    current1 = power_supply[2]
    self.power_channel_text.delete(1.0, END)
    self.power_channel_text.insert(1.0, channel1)
    self.voltage_text.delete(1.0, END)
    self.voltage_text.insert(1.0, voltage1)
    self.current_compliance_text.delete(1.0, END)
    self.current_compliance_text.insert(1.0, current1)

    Aardvark = str(input.iloc[i][2]).split(',')
    register_values = []
    start_address = Aardvark[0]
    for n in range(0, len(Aardvark[1].split(' '))):
        register_values.append(int(Aardvark[1].split(' ')[n], 16))
    self.aardvark_write_Address_text.delete(1.0, END)
    self.aardvark_write_Address_text.insert(1.0, start_address)
    self.aardvark_i2c_write_value_text.delete(1.0, END)
    self.aardvark_i2c_write_value_text.insert(1.0, str(Aardvark[1]))

    temp = str(input.iloc[i][3]); save_path = str(input.iloc[i][4])
    self.temperature_text.delete(1.0, END)
    self.temperature_text.insert(1.0, temp)
    self.save_path_text.delete(1.0, END)
    self.save_path_text.insert(1.0, save_path)
    part = str(input.iloc[i][5]); Label = str(input.iloc[i][6])  
    self.progress_bar['value'] = 5 + step * (i + 1)
    self.root.update_idletasks()
    self.root.after(5, lambda x: self.perform_loop(remaining - 1))

然后在GUI上调用perform_loop之前,使用您想要执行的迭代次数调用mainloop