简体   繁体   English

Python tkinter:主线程不在主循环中?

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

I am developing a GUI for mine MQTT app.我正在为我的 MQTT 应用程序开发一个 GUI。 I have a problem with this function:我对这个 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()

In particular I have a problem when I add the following lines for the button:特别是当我为按钮添加以下行时,我遇到了问题:

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

Without them is all ok.没有他们一切都好。 I want to clarify that I made run this cose in this form:我想澄清一下,我以这种形式运行了这个 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()

I had to change code because I want a background for my_windows that resizes with the window dimensions .我不得不更改代码,因为我想要 my_windows 的背景,它可以使用 window 尺寸调整大小 I saw also other posts on this error:我还看到了有关此错误的其他帖子: 在此处输入图像描述 But I can't understand where am I wrong.但我不明白我错在哪里。 Can someone help me?有人能帮我吗? Any help will be appreciated.任何帮助将不胜感激。

Regards, Kevin问候,凯文

I think the problem of main thread is not in main loop is solved.我认为主线程不在主循环中的问题已经解决。 At this point I have still another problem: 'NoneType' object has no attribute 'get' .此时我还有另一个问题: 'NoneType' object has no attribute 'get' When I try to send a command I obtain this error: [:[enter image description here][1]][1] The function is this, #Implementazione della funzione SEND.当我尝试发送命令时,我收到此错误:[:[在此处输入图像描述][1]][1] function 是这个,#Implementazione della funzione SEND。 che sarà richiamata dal bottone che attiva questo servizio. 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)

Where am I wrong this time?这次我哪里错了? :( [1]: https://i.stack.imgur.com/Z4Mgf.png :( [1]: https://i.stack.imgur.com/Z4Mgf.png

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM