簡體   English   中英

Python tkinter:主線程不在主循環中?

[英]Python tkinter: main thread is not in main loop?

我正在為我的 MQTT 應用程序開發一個 GUI。 我對這個 function 有疑問:

   from tkinter import *
from tkinter import ttk
from tkinter import messagebox
from PIL import  ImageTk, Image
import paho.mqtt.client as mqtt
import json

broker = "192.168.1.9"
client = mqtt.Client("DoIP_project")
m_decode = ''

def on_log(client, userdata, level, buf):
    print("log: "+buf)

def on_connect(client, userdata, flags, rc):
    if rc==0:
        print("Connected OK")
        connection_status.config(text="Connection status: CONNECTED")
    else:
        print("Bad connection Returned code = ", rc)
        connection_status.config(text="Connection status: BAD CONNECTION with error" + rc)

def on_disconnect(client, userdata, flags, rc=0):
    print("DisConnected result code "+str(rc))
    connection_status.config(text="Connection status: DISCONNECTED" + rc)

def on_message(client, userdata, msg):
    topic=msg.topic
    global m_decode
    m_decode=str(msg.payload.decode("utf-8")+msg.topic)
    print("message received", m_decode)
    #testo_receive.configure(text=m_decode)
    testo_receive.config(text="Messaggio ricevuto: " + (m_decode))
    
    #Implementazione del salvataggio di dati su file di testo.
    file = open("documento_test_diagnosi.txt", 'a')
    file.write(m_decode)
    file.write("\n")
    file.close()

#Implementazione della funzione SEND, che sarà richiamata dal bottone che attiva questo servizio.
def publish_message(client, msg_entry):
    msg=msg_entry.get()
    msg_entry.delete('0', 'end')
    
    client.publish("diagnostic_request/topic", msg)
    
def cambia():
        testo_receive.configure(text=msg_entry.get())


def resizer2(e):
    global bg3, resized_bg3, new_bg3
    bg3 = Image.open("WUT_banner_Automotive_1080x335.4532699.png")
    resized_bg3 = bg3.resize((e.width, e.height), Image.ANTIALIAS)
    new_bg3 = ImageTk.PhotoImage(resized_bg3)
    new_canvas1.create_image(0,0, image=new_bg3, anchor="nw")

def open_window():
    global new_canvas1
    new_window = Tk()
    new_window.title("Diagnostic panel")
    new_window.geometry("700x400")
    bg = ImageTk.PhotoImage(file="WUT_banner_Automotive_1080x335.4532699.png")
    new_canvas1 = Canvas(new_window, width = 700, heigh =335)
    new_canvas1.pack(fill="both", expand=True)
    new_canvas1.create_image(0,0, image=bg, anchor="nw")

    #connection status
    global connection_status
    connection_status = Label(new_window, text="Connection status... ", width=30, heigh=2, background="green", relief="raised")
    connection_status.place(x=80, y=100)

    #label in cui scrivere il messaggio diagnostico
    msg_entry = ttk.Entry(new_window, width=40).place(x=350, y=200)
    info_label = Label(new_window, text="Inserire una richiesta diagnostica: ",  width=34, background="white",relief="groove").place(x=80, y=201)

    #Send button
    msg_button = ttk.Button(new_window, text="Send")
    msg_button.place(x=600, y=198)
    msg_button['command'] = lambda: publish_message(client, msg_entry)
    msg_button.bind('<Return>', lambda event: publish_message(client, msg_entry))
    
    
    #Receive window
    global testo_receive
    testo_receive = Label(new_window, text="In attesa di ricevere un messaggio... ",  width=34, heigh=3, background="white",relief="groove").place(x=80, y=300)
   
    client.on_connect = on_connect
    client.ondisconnect=on_disconnect
    client.on_log = on_log
    client.on_message=on_message
    print("Connecting to broker ", broker)
    client.connect(broker)
    client.loop_start()
    client.subscribe("diagnostic_response/topic")
    
    new_window.bind('<Configure>', resizer2)
    new_window.mainloop()

#Funzione che adatta lo sfondo alle dimensioni della finestra (funzione collegata alla main window).
def resizer(e):
    global bg1, resized_bg, new_bg
    bg1 = Image.open("WUT_banner_Automotive_1080x335.4532699.png")
    resized_bg = bg1.resize((e.width, e.height), Image.ANTIALIAS)
    new_bg = ImageTk.PhotoImage(resized_bg)
    my_canvas.create_image(0,0, image=new_bg, anchor="nw")

#Funzione che adatta lo sfondo alle dimensioni della finestra (funzione collegata alla Services Window).  
def resizer1(e):
    global bg2, resized_bg2, new_bg2
    bg2 = Image.open("WUT_banner_Automotive_1080x335.4532699.png")
    resized_bg2 = bg2.resize((e.width, e.height), Image.ANTIALIAS)
    new_bg2 = ImageTk.PhotoImage(resized_bg2)
    new_canvas.create_image(0,0, image=new_bg2, anchor="nw")

def log_ok():
    global new_canvas
    user = e1.get()
    password = e2.get()

    if(user == "" and password == ""):
        messagebox.showinfo("", "Inserisci le credenziali per accedere.")

    elif(user == "admin" and password == "admin"):
        messagebox.showinfo("", "Login success.")
        root.destroy()
        #Se il login è ok, apri la finestra successiva.
        s = Tk()
        s.title("Services window")
        s.geometry("700x400")
        bg = ImageTk.PhotoImage(file="WUT_banner_Automotive_1080x335.4532699.png")
        new_canvas = Canvas(s, width = 700, heigh =335)
        new_canvas.pack(fill="both", expand=True)
        new_canvas.create_image(0,0, image=bg, anchor="nw")

        Button(s, text="Diagnostic request", command = lambda: [ s.destroy(),open_window() ] , heigh = 5, width = 15, bg = "yellow").place(x=100, y=200)

        #Aggiungere bottoni per effettuare altre operazioni, come ACQUISIZIONE.

        s.bind('<Configure>', resizer1)
        s.mainloop()



root = Tk()
root.title("Home")
root.geometry("700x400")

#Operazioni per settare lo sfondo della schermata principale.
bg = ImageTk.PhotoImage(file="WUT_banner_Automotive_1080x335.4532699.png")
my_canvas = Canvas(root, width = 700, heigh =335)
my_canvas.pack(fill="both", expand=True)
my_canvas.create_image(0,0, image=bg, anchor="nw")

#Aggiunta di loghi alla schermata Home
photo = PhotoImage(file="logo_kienton.png")
Label(root, image = photo).place(x=600, y=230)
photo2 = PhotoImage(file="logo_dieti.png")
Label(root, image = photo2).place(x=600, y=430)

#Aggiunta dei parametri di logIN.
global e1
global e2

Label(root, text = "Username", width=20, heigh=2).place(x=80, y=300)
Label(root, text = "Password", width=20, heigh=2).place(x=80, y=420)
e1 = Entry(root)
e1.place(x=300, y=302, width=200, heigh=30)
e2 = Entry(root)
e2.place(x=300, y=422, width=200, heigh=30)
e2.config(show="*")
Button(root, text="Login", command = log_ok, heigh = 3, width = 13).place(x=80, y=520)


root.bind('<Configure>', resizer)

root.mainloop()

特別是當我為按鈕添加以下行時,我遇到了問題:

msg_button['command'] = lambda: publish_message(client, msg_entry)
    msg_button.bind('<Return>', lambda event: publish_message(client, msg_entry))

沒有他們一切都好。 我想澄清一下,我以這種形式運行了這個 cose:

def open_window():
    new_window = Tk()

    msg_entry = ttk.Entry(new_window, width=40)
    msg_entry.grid(row=1, column=0)
    global testo_receive
    testo_receive = Label(new_window, text="In attesa di ricevere un messaggio... ",  width=34, background="white",relief="groove")
    testo_receive.grid(row=2, column=0)

    global connection_status
    connection_status = Label(new_window, text="Connection status... ", width=40, background="white", relief="raised", pady=5)
    connection_status.grid(row=7, column=0)

    msg_button = ttk.Button(new_window, text="Send")
    msg_button.grid(row=1, column=1)
    msg_button['command'] = lambda: publish_message(client, msg_entry)
    msg_button.bind('<Return>', lambda event: publish_message(client, msg_entry))

    q_button = ttk.Button(new_window, text="Quit")
    q_button.grid(row=1, column=2)
    q_button['command'] = lambda: new_window.close()


    client.on_connect = on_connect
    client.ondisconnect=on_disconnect
    client.on_log = on_log
    client.on_message=on_message

    print("Connecting to broker ", broker)

    client.connect(broker)
    client.loop_start()
    client.subscribe("mangoh")

    new_window.mainloop()

我不得不更改代碼,因為我想要 my_windows 的背景,它可以使用 window 尺寸調整大小 我還看到了有關此錯誤的其他帖子: 在此處輸入圖像描述 但我不明白我錯在哪里。 有人能幫我嗎? 任何幫助將不勝感激。

問候,凱文

我認為主線程不在主循環中的問題已經解決。 此時我還有另一個問題: 'NoneType' object has no attribute 'get' 當我嘗試發送命令時,我收到此錯誤:[:[在此處輸入圖像描述][1]][1] function 是這個,#Implementazione della funzione SEND。 che sarà richiamata dal bottone che attiva questo servizio。

def publish_message(client, msg_entry):
    msg=msg_entry.get()
    msg_entry.delete('0', 'end')
    
    client.publish("diagnostic_request/topic", msg)

這次我哪里錯了? :( [1]: https://i.stack.imgur.com/Z4Mgf.png

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM