我用Tkinter做了一个简单的GUI来订阅和接收来自mqtt代理的消息。我自己写的,因为一些消息解压缩问题,应该没关系。问题是,当我连接并订阅一个主题时,客户端需要保持运行,所以我在一个线程中运行它,以避免冻结GUI。但是因为线程一直在运行,所以我不能重新运行订阅操作。
如果你尝试一次,它就可以正常工作(请注意,它最初是在一个类中,但我只尝试发布相关的方法):
def main_window(self):
self.root.title("MQTT Subscriber Test")
self.root.geometry("350x150")
# Topic subscription
title = tk.Label(self.root, text="Enter topic to subscribe:")
title.pack(**self.padding, anchor=tk.W)
topic_entry = tk.Entry(self.root, textvariable=self.topic)
self.root.update()
topic_entry.pack(**self.padding, **self.ipadding, anchor=tk.W, fill=tk.X)
# subscribe button
subscribe_button = tk.Button(self.root, text="Connect",
command=threading.Thread(target=self.subscribe_to_topic).start)
subscribe_button.pack(**self.padding, anchor=tk.W)
def subscribe_to_topic(self):
# ToDo: better condition for unsubscribe action
if self.subbed_topic != "":
self.client.unsubscribe_from_topic(self.subbed_topic)
self.client.disconnect_from_broker()
self.subbed_topic = self.get_topic
self.open_output_window()
self.client.operate(self.subbed_topic)
main_window()
设置接口,按下订阅按钮时调用subscribe_to_topic()
。
这一次运行正常,但我不能重新按下按钮,我得到错误:RuntimeError: threads can only be started once
所以我试着将线程的启动切换到方法本身,如下所示:
def main_window(self):
self.root.title("MQTT Subscriber Test")
self.root.geometry("350x150")
# Topic subscription
title = tk.Label(self.root, text="Enter topic to subscribe:")
title.pack(**self.padding, anchor=tk.W)
topic_entry = tk.Entry(self.root, textvariable=self.topic)
self.root.update()
topic_entry.pack(**self.padding, **self.ipadding, anchor=tk.W, fill=tk.X)
# subscribe button
subscribe_button = tk.Button(self.root, text="Connect",
command=self.subscribe_to_topic))
subscribe_button.pack(**self.padding, anchor=tk.W)
def subscribe_to_topic(self):
# ToDo: better condition for unsubscribe action
if self.subbed_topic != "":
self.client.unsubscribe_from_topic(self.subbed_topic)
self.client.disconnect_from_broker()
self.subbed_topic = self.get_topic
self.open_output_window()
threading.Thread(target=self.client.operate(self.subbed_topic).start()
但这会再次冻结GUI。从这一点上,我找不到任何其他线程来解决我的问题。
1条答案
按热度按时间uoifb46i1#
我注意到的一件事是,您正在调用函数,而不是将函数传递给线程。
在本例中,该函数被调用
target=self.client.operate(self.subbed_topic)
,但没有传递给线程试着像这样重构最后一行,然后再试一次?