基本思路
我正在使用MQTT
协议(代理:Mosquitto和通过Eclipse Paho的Client实现)来获取定期数据。我想在数据中获得特定数字x时显示图像,如果获得另一个数字y则更改图像。
用通俗易懂的术语讲,我正在以10秒的间隔获取JSON格式的一些数据,并且想要相对于接收到的数据显示或更改图像。
代码
from tkinter import *
from PIL import ImageTk, Image
import datetime
import paho.mqtt.client as mqtt
import json
root = Tk()
canvas = Canvas(root, width=500, height=500)
canvas.pack()
def drawImage(payload):
pic = payload['camera']
canvas.delete("all")
img = ImageTk.PhotoImage(Image.open(str(pic) + ".png"))
canvas.create_image(20, 20, anchor=NW, image=img)
root.mainloop()
def on_connect(client, userdata, flags, rc):
print("Connected with result code " + str(rc))
client.subscribe("home/camera")
def on_message(client, userdata, msg):
t = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
payload = json.loads(msg.payload)
print("Data received at: {0} || Topic: {1} || Message: {2}".format(t, msg.topic, str(msg.payload)))
drawImage(payload)
client = mqtt.Client(client_id="cameratester")
client.on_connect = on_connect
client.on_message = on_message
client.connect("127.0.0.1", 1883, 60)
client.loop_forever()
简要说明代码的工作原理:
无论何时接收到新数据,都会调用on_message
,依次调用绘制图像的drawImage
函数。
问题
图像在收到第一条消息时绘制,但是代码似乎挂在那里。我的客户不接受任何其他传入消息。关闭图像窗口后,print("Data received at: {0} || Topic: {1} || Message: {2}".format(t, msg.topic, str(msg.payload)))
行代码再次开始执行,但是没有图像显示。
一些研究
在经历了this和this之类的How to change image in Tkinter
问题的栈之后,很明显root.mainloop()
是一个阻塞调用,并且流程不会进一步执行直到窗口关闭。有人提到,如果要更改图像,则需要为事件分配回调,例如单击按钮并执行panel.configure(image=img2)
来更改图像。
但是由于我的设计没有任何按钮,所以我无法遵循按钮回调方法。
那么,从发布者(MQTT)接收数据后,如何在Tkinter窗口上触发更改图像?
我不应该使用Tkinter吗,其他一些软件包更适合此要求?还是我错过了一些非常基本的东西。
请咨询。