Как вызвать изменение изображения в окне Tkinter при получении данных от издателя? - PullRequest
0 голосов
/ 05 октября 2018

Базовая идея

Я использую протокол MQTT (брокер: реализация Mosquitto и Client через Eclipse Paho) ​​для получения периодических данных.Я хочу показать изображение после получения определенного числа х в данных и изменить изображение, если я получу другое число у.

С точки зрения непрофессионала, я получаю некоторые данные в формате JSON с интервалом в 10 секунд и хочу отобразить или изменить изображение в соответствии с полученными данными.

Код

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))) снова начинает выполняться, но изображение не отображается.

Некоторые исследования

После прохождения платоры по How to change image in Tkinter вопросам на StackOverflow, например this и this ,стало очевидно, что root.mainloop() является блокирующим вызовом, и поток не будет выполняться дальше, пока окно не будет закрыто.Было упомянуто, что если я хочу изменить изображение, мне нужно назначить обратный вызов для события, например нажать кнопку и сделать panel.configure(image=img2), чтобы изменить изображение.

Но так как мой дизайн неУ меня есть кнопки, я не могу следовать методологии обратного вызова кнопок.

Итак, как я могу инициировать изменение изображения в окне Tkinter при получении данных от издателя (MQTT)?

Если я не использую Tkinter, какой-нибудь другой пакет лучше подходит для этого требования?Или я что-то упустил очень простой.

Пожалуйста, совет.

...