Tkinter GUI and Signal.py - ValueError: signal only works in main thread

Tkinter GUI and Signal.py - ValueError: signal only works in main thread

大家好

我目前正在尝试使用 python 中的 MQTT 将 IoT 通信集成到 KAAIoT,该 MQTT 发送从电机驱动器的保持寄存器读取的数据。该脚本在 Raspberry pi 上运行,带有 Tkinter GUI 来执行一些控制,但现在我想通过 IoT 接口监视和控制一些东西。

我测试了提供的示例脚本 here 并设法发送和接收一些垃圾数据,Cool beans,但是在尝试将其集成到应用程序中时出现了问题。

尝试 1:实现代码到主 class。
结果:已建立连接,但由于 main

中的循环,GUI 未加载

代码示例Here

尝试 2:运行线程中的“主要”代码。
结果:错误

File "/usr/lib/python3.7/signal.py", line 47, in signal handler = _signal.signal(_enum_to_int(signalnum), _enum_to_int(handler)) ValueError: signal only works in main thread <--------

因此,如果我理解正确,信号模块需要 Tkinter 用于显示 GUI 的主线程,但如果它使用它,它会抑制 GUI。主线程的使用也在信号和线程下进行了解释 here

问题:是否可以通过某种方式集成 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()