从发布者接收数据后,如何在Tkinter窗口上触发图像更改?

时间:2018-10-05 07:19:55

标签: python tkinter mosquitto paho

基本思路

我正在使用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)))行代码再次开始执行,但是没有图像显示。

一些研究

在经历了thisthis之类的How to change image in Tkinter问题的栈之后,很明显root.mainloop()是一个阻塞调用,并且流程不会进一步执行直到窗口关闭。有人提到,如果要更改图像,则需要为事件分配回调,例如单击按钮并执行panel.configure(image=img2)来更改图像。

但是由于我的设计没有任何按钮,所以我无法遵循按钮回调方法。

那么,从发布者(MQTT)接收数据后,如何在Tkinter窗口上触发更改图像?

我不应该使用Tkinter吗,其他一些软件包更适合此要求?还是我错过了一些非常基本的东西。

请咨询。

0 个答案:

没有答案