![](/img/trans.png)
[英]python | tkinter and threading: “main thread is not in main loop”
[英]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.