单击或移动鼠标时,Tkinter GUI 不响应(for 循环)
Tkinter GUI does not response in (for loop) when clicking or moving mouse
我刚刚编写了一个简单的自动化程序来使用 Tkinter GUI 进行测试工作。
其他一切都很好,除非我有移动或单击鼠标等操作,GUI 不会响应,但代码仍然是 运行ning。循环完成后,GUI 进入正常状态。这是我的部分代码(只有for循环,我的代码有点长,例如硬件设置和获取。)
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)
在循环外,我已经初始化了我的文本值和进度条值。我在网上搜索教程并找到了两个解决方案。一种是使用多线程,另一种是使用 after 函数。但是,当我只有 运行 按钮时会发生其他触发事件时使用它们。之后,我只想更新每个 运行 的文本值和进度条值,直到结束。谁能给我一些建议吗?非常感谢。
这里发生的事情是您阻止 GUI 注册事件,因为它太忙于执行您的代码。您想要的是 运行 代码的一次迭代,然后 return 控制返回 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 上调用 mainloop
之前,只需调用 perform_loop
并指定要执行的迭代次数。
我刚刚编写了一个简单的自动化程序来使用 Tkinter GUI 进行测试工作。 其他一切都很好,除非我有移动或单击鼠标等操作,GUI 不会响应,但代码仍然是 运行ning。循环完成后,GUI 进入正常状态。这是我的部分代码(只有for循环,我的代码有点长,例如硬件设置和获取。)
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)
在循环外,我已经初始化了我的文本值和进度条值。我在网上搜索教程并找到了两个解决方案。一种是使用多线程,另一种是使用 after 函数。但是,当我只有 运行 按钮时会发生其他触发事件时使用它们。之后,我只想更新每个 运行 的文本值和进度条值,直到结束。谁能给我一些建议吗?非常感谢。
这里发生的事情是您阻止 GUI 注册事件,因为它太忙于执行您的代码。您想要的是 运行 代码的一次迭代,然后 return 控制返回 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 上调用 mainloop
之前,只需调用 perform_loop
并指定要执行的迭代次数。