python - Tkinter GUI 和 Signal.py - ValueError:信号仅在主线程中有效
问题描述
今天是个好日子
我目前正在尝试使用 Python 中的 MQTT 将 IoT 通信集成到KAAIoT,该 Python 发送从电机驱动器的保持寄存器读取的数据。该脚本在带有 Tkinter GUI 的 Raspberry pi 上运行以进行一些控制,但现在我想通过 IoT 接口监视和控制一些事情。
我测试了此处提供的示例脚本,并设法发送和接收一些垃圾数据,酷豆,但在尝试将其集成到应用程序时出现问题。
尝试 1:实现到主类中的代码。
结果:已建立连接,但由于主循环中的循环,GUI 未加载
代码示例在这里
尝试 2:在线程中运行“主”代码。
结果:错误
文件“/usr/lib/python3.7/signal.py”,第 47 行,信号处理程序 = _signal.signal(_enum_to_int(signalnum), _enum_to_int(handler)) ValueError: signal only works in main thread <---- ----
因此,如果我理解正确,信号模块需要 Tkinter 用于显示 GUI 的主线程,但如果它使用它,它会抑制 GUI。主线程的使用也在Signals and Threads 下进行了说明。
问题:是否可以以某种方式同时集成 GUI 和 MQTT?任何修复或工作替代方案将不胜感激。
解决方案
您可以在单独的函数中移动 MQTT 内容并使用线程来执行此函数:
import threading
...
class MainView(tk.Frame):
def __init__(self, *args, **kwargs):
...
clock()
self.listener = SignalListener()
threading.Thread(target=self.client_task, daemon=True).start()
def client_task(self):
client = mqtt.Client(client_id=''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(6)))
data_collection_client = DataCollectionClient(client)
data_collection_client.connect_to_server()
client.on_message = on_message
# Start the loop
client.loop_start()
fuelLevel, minTemp, maxTemp = 100, 95, 100
# Send data samples in loop
while self.listener.keepRunning:
payload = data_collection_client.compose_data_sample(fuelLevel, minTemp, maxTemp)
result = data_collection_client.client.publish(topic=data_collection_client.data_collection_topic, payload=payload)
if result.rc != 0:
print('Server connection lost, attempting to reconnect')
data_collection_client.connect_to_server()
else:
print(f'--> Sent message on topic "{data_collection_client.data_collection_topic}":\n{payload}')
time.sleep(3)
fuelLevel = fuelLevel - 0.3
if fuelLevel < 1:
fuelLevel = 100
data_collection_client.disconnect_from_server()
推荐阅读
- pm2 - 使用 PM2 调试 Node.js 时,是否有 CLI 选项来避免使用集群模块为每个线程打开命令提示符?
- python - 在数据框中,如何将带有列表的列(所有行的长度相同)分解为同一行的不同列
- c++ - 常量成员初始化
- azure - 使用 Azure 自动化帐户,跨存储将文件从一个文件共享复制到另一个文件共享
- c# - 向“切换”发送垃圾邮件时,C#/WPF 处理活动的故事板动画
- excel - 高效编码
- powershell - 函数与方法中的命令输出
- plsql - 为什么我的“插入后”触发器在创建触发器后不考虑所有其他插入?
- mysql - 将行复制到另一个表但有条件
- javascript - JavaScript 提交按钮在以编程方式触发时返回 isTrusted true