rabbitmq 如何用线程更新tkinter gui标签?

0g0grzrc  于 2023-03-08  发布在  RabbitMQ
关注(0)|答案(1)|浏览(146)

我是Python tkinter的新手。我已经为我的gui编写了以下代码。我想用从rabbitmq接收到的正文消息更新我的标签1。但是一旦我的gui得到填充,我就面临着问题,即使我在正文中接收到不同的消息,但是它不能更新。一旦我关闭GUI,它就会有新的价值。我想我的gui tkinter窗口是常数和标签应刷新在正文中接收新消息。

import tkinter
from PIL import ImageTk, Image as PILImage
import datetime as dt
from tkinter import *
import pika

connection = pika.BlockingConnection(
    pika.ConnectionParameters(host='localhost'))
channel = connection.channel()

channel.queue_declare(queue='hello')

def callback(ch, method, properties, body):
    global myval
    print(" [x] Received %r" % body)
   
    window=Tk()
    window.attributes('-fullscreen',True)
    window.bind("<F11>", lambda event: window.attributes("-fullscreen",
                                        not window.attributes("-fullscreen")))
    window.bind("<Escape>", lambda event: window.attributes("-fullscreen",False))
    top_left=Frame(window,width=200,height=200)
    top_middle=Frame(window,width=550,height=200)
    top_right=Frame(window,width=250,height=200)
    middle_left=Frame(window,width=200,height=300)
    middle_middle=Frame(window,width=300,height=300)
    middle_right=Frame(window,width=300,height=300)
    bottom_left=Frame(window,width=0,height=200)
    bottom_middle=Frame(window,width=300,height=200)
    bottom_right=Frame(window,width=300,height=200)
    top_left.grid(row=0,column=0)
    top_middle.grid(row=0,column=1)
    top_right.grid(row=0,column=2,sticky=E+W)
    middle_left.grid(row=1,column=0,padx=100,pady=100)
    middle_middle.grid(row=1,column=1) 
    middle_right.grid(row=1,column=2)
    bottom_left.grid(row=2,column=0)
    bottom_middle.grid(row=2,column=1)
    bottom_right.grid(row=2,column=2)
    dte=Label(top_left, text="Date: "f"{dt.datetime.now():%a,%d/ %m/ %Y}",fg="black",font=("Arial Bold ",12 ))
    dte.place(x=0,y=40)
    lbl=Label(top_middle, text="Welcome to Smartcards Division",fg='#3333ff',font=("Arial Bold Italic",24 ))
    lbl.place(x=0,y=30)
    logo_path="logo.jpg"
    logo = ImageTk.PhotoImage((PILImage.open(logo_path)).resize((280,100),PILImage.ANTIALIAS))
    logo_panel = Label(top_right,image = logo)
    logo_panel.place(x=10,y=30)
    string_clsname=str(body.decode())
    lblxt=StringVar()
    lbl1=Label(middle_left, textvariable=lblxt,fg='#ff6600',font=("Arial Bold Italic",16))
    lblxt.set("Hello "+string_clsname+" Sir")
    lbl1.place(x=0,y=100)
    path = "NewPicture_Copy.jpg"
    image = ImageTk.PhotoImage((PILImage.open(path)).resize((250,250),PILImage.ANTIALIAS))
    panel = Label(middle_middle,image = image,borderwidth=5, relief="ridge")
    panel.pack()
    lbl2=Label(bottom_middle, text="\u00a9"+"2020-Smartcards Division",fg='black',font=("Helvetica",8))
    lbl2.place(x=0,y=0)
    window.title('Image Classification')
    window.mainloop()

channel.basic_consume(
    queue='hello', on_message_callback=callback, auto_ack=True)
print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()
wooyq4lh

wooyq4lh1#

在基础级别,您需要:

  • 独立的执行线索,

用于单独的任务(必须同时运行)。

  • 线程之间相互通信的方式;

同时避免竞争条件
(like修改一个线程中的变量,
而另一线程正在读取它)。
这里你可以使用互斥锁/锁,消息传递等。

import tkinter as tk

from collections import deque
from threading import Thread

from random import randint
from time import sleep

# Starting out (this is the main/gui thread).

root = tk.Tk()

label = tk.Label(root, text="Original text")
label.pack()

# Means of communication, between the gui & update threads:
message_queue = deque()

# Create a thread, that will periodically emit text updates.
def emit_text():  # The task to be called from the thread.
    while True:  # Normally should check some condition here.
        message_queue.append(f"Random number: {randint(0, 100)}")
        sleep(1)  # Simulated delay (of 1 sec) between updates.

# Create a separate thread, for the emitText task:
thread = Thread(target=emit_text)
# Cheap way to avoid blocking @ program exit: run as daemon:
thread.setDaemon(True)
thread.start()  # "thread" starts running independently.

# Moving on (this is still the main/gui thread).

# Periodically check for text updates, in the gui thread.
# Where 'gui thread' is the main thread,
# that is running the gui event-loop.
# Should only access the gui, in the gui thread/event-loop.
def consume_text():
    try:
        label["text"] = message_queue.popleft()
    except IndexError:
        pass  # Ignore, if no text available.
    # Reschedule call to consumeText.
    root.after(ms=1000, func=consume_text)

consume_text()  # Start the consumeText 'loop'.

root.mainloop()  # Enter the gui event-loop.

另见:
queue.Queue
"collections. deque是一个可选的
具有快速原子append()和popleft()的无界队列
不需要锁定的操作。"
collections.deque
threading.Thread

相关问题