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()
大家好
我目前正在尝试使用 python 中的 MQTT 将 IoT 通信集成到 KAAIoT,该 MQTT 发送从电机驱动器的保持寄存器读取的数据。该脚本在 Raspberry pi 上运行,带有 Tkinter GUI 来执行一些控制,但现在我想通过 IoT 接口监视和控制一些东西。
我测试了提供的示例脚本 here 并设法发送和接收一些垃圾数据,Cool beans,但是在尝试将其集成到应用程序中时出现了问题。
尝试 1:实现代码到主 class。
结果:已建立连接,但由于 main
代码示例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()