我知道 TKinter 在執行緒中運行時不會保存。沒關系,我創建了一個程式,我在執行緒中啟動 tkinter 模塊。在我將主題設定添加到代碼之前,它對我來說很好。
import tkinter as tk
import time
from tkinter import ttk
from _thread import *
import os
import random
raster = {"breite": 5, "hohe": 4}
def placeitems(itemname):
print("placebuttononrightspot")
def none():
pass
def startprozess(name, *mitgabe):
print(name)
if mitgabe == ():
start_new_thread(name, ())
else:
start_new_thread(name, (mitgabe))
#normstyle = ttk.Style()
#pressstyle = ttk.Style()
#normstyle.configure('B1.TButton', foreground='black', background='light gray')
#pressstyle.configure('B2.TButton', foreground='white', background='blue')
def reboot():
os.system('sudo reboot')
def ?3_Website():
print("dosomething")
def Youtube_Website():
print("dosomething")
def pihole():
print("dosomething")
def musiktest(aktion):
print("dosomething")
def screenhauptmenu():
global pos
global screen_width
global screen_height
pos = [False]
pos = pos * raster["breite"] * raster["hohe"]
hauptmenu = tk.Tk()
screen_width = hauptmenu.winfo_screenwidth()
screen_height = hauptmenu.winfo_screenheight()
hauptmenu.geometry(f'{screen_width}x{screen_height} 0 0')
hauptmenu.title(hauptmenu)
hauptmenu.resizable(False, False)
hauptmenu.attributes('-fullscreen', True)
normstyle = ttk.Style()
pressstyle = ttk.Style()
normstyle.configure('B1.TButton', foreground='black', background='light gray')
pressstyle.configure('B2.TButton', foreground='white', background='blue')
#global normstyle
#global pressstyle
global button0onscreenhauptmenu
button0 = ttk.Button(hauptmenu, text="Musikplayer", command = lambda: startprozess(switchscreen, 'screenmusikplayer'), style = 'B2.TButton')
placeitems(button0)
global button1onscreenhauptmenu
button1 = ttk.Button(hauptmenu, text="Einstellungen", command = lambda: startprozess(switchscreen, 'screeneinstellungen'), style="B1.TButton")
placeitems(button1)
global button2onscreenhauptmenu
button2 = ttk.Button(hauptmenu, text="Adminbereich", command = lambda: startprozess(switchscreen, 'screenadminbereich'), style="B1.TButton")
placeitems(button2)
global button3onscreenhauptmenu
button3 = ttk.Button(hauptmenu, text="Energieoptionen", command = lambda: startprozess(switchscreen, 'screenenergieoptionen'), style="B1.TButton")
placeitems(button3)
global button4onscreenhauptmenu
button4 = ttk.Button(hauptmenu, text="Pi neustarten", command = lambda: startprozess(reboot), style="B1.TButton")
placeitems(button4)
global button5onscreenhauptmenu
button5 = ttk.Button(hauptmenu, text="?3 Webplayer", command = lambda: startprozess(?3_Website), style="B1.TButton")
placeitems(button5)
global button6onscreenhauptmenu
button6 = ttk.Button(hauptmenu, text="Youtube", command = lambda: startprozess(Youtube_Website), style="B1.TButton")
placeitems(button6)
global button7onscreenhauptmenu
button7 = ttk.Button(hauptmenu, text="Pi-Hole Dashboard", command = lambda: startprozess(pihole), style="B1.TButton")
placeitems(button7)
global screenhauptmenuoffen
while screenhauptmenuoffen == True:
'''if button0onscreenhauptmenu == True:
button0.configure(style = "B2.TButton")
else:
button0.configure(style = "B1.TButton")
if button1onscreenhauptmenu == True:
button1.configure(style = "B2.TButton")
else:
button1.configure(style = "B1.TButton")
if button2onscreenhauptmenu == True:
button2.configure(style = "B2.TButton")
else:
button2.configure(style = "B1.TButton")
if button3onscreenhauptmenu == True:
button3.configure(style = "B2.TButton")
else:
button3.configure(style = "B1.TButton")
if button4onscreenhauptmenu == True:
button4.configure(style = "B2.TButton")
else:
button4.configure(style = "B1.TButton")
if button5onscreenhauptmenu == True:
button5.configure(style = "B2.TButton")
else:
button5.configure(style = "B1.TButton")
if button6onscreenhauptmenu == True:
button6.configure(style = "B2.TButton")
else:
button6.configure(style = "B1.TButton")
if button7onscreenhauptmenu == True:
button7.configure(style = "B2.TButton")
else:
button7.configure(style = "B1.TButton")'''
hauptmenu.update()
time.sleep(0.1)
hauptmenu.destroy()
def screeneinstellungen():
global pos
global screen_width
global screen_height
pos = [False]
pos = pos * raster["breite"] * raster["hohe"]
einstellungen = tk.Tk()
screen_width = einstellungen.winfo_screenwidth()
screen_height = einstellungen.winfo_screenheight()
einstellungen.geometry(f'{screen_width}x{screen_height} 0 0')
einstellungen.title(einstellungen)
einstellungen.resizable(False, False)
einstellungen.attributes('-fullscreen', True)
normstyle = ttk.Style()
pressstyle = ttk.Style()
normstyle.configure('B1.TButton', foreground='black', background='light gray')
pressstyle.configure('B2.TButton', foreground='white', background='blue')
global button0onscreeneinstellungen
button0 = ttk.Button(einstellungen, text="Hauptmenü", command = lambda: startprozess(switchscreen, 'screenhauptmenu'), style="B2.TButton")
placeitems(button0)
global screeneinstellungenoffen
while screeneinstellungenoffen == True:
if button0onscreeneinstellungen == True:
button0.configure(style = "B2.TButton")
else:
button0.configure(style = "B1.TButton")
einstellungen.update()
time.sleep(0.1)
einstellungen.destroy()
def screenmusikplayer():
print("weiterer screen mit vielen Tasten")
button0onscreenhauptmenu = True
button1onscreenhauptmenu = False
button2onscreenhauptmenu = False
button3onscreenhauptmenu = False
button4onscreenhauptmenu = False
button5onscreenhauptmenu = False
button6onscreenhauptmenu = False
button7onscreenhauptmenu = False
button0onscreeneinstellungen = False
def switchscreen(toscreen):
global screenhauptmenu
global screeneinstellungen
def startupscreenhauptmenu():
global screenhauptmenuoffen
global screeneinstellungenoffen
global screenadminbereichoffen
global screenmusikplayeroffen
global screenenergieoptionenoffen
screenhauptmenuoffen = True
screeneinstellungenoffen = False
screenadminbereichoffen = False
screenmusikplayeroffen = False
screenenergieoptionenoffen = False
startprozess(screenhauptmenu)
def startupscreeneinstellungen():
global screenhauptmenuoffen
global screeneinstellungenoffen
global screenadminbereichoffen
global screenmusikplayeroffen
global screenenergieoptionenoffen
screenhauptmenuoffen = False
screeneinstellungenoffen = True
screenadminbereichoffen = False
screenmusikplayeroffen = False
screenenergieoptionenoffen = False
startprozess(screeneinstellungen)
def startupscreenmusikplayer():
global screenhauptmenuoffen
global screeneinstellungenoffen
global screenadminbereichoffen
global screenmusikplayeroffen
global screenenergieoptionenoffen
screenhauptmenuoffen = False
screeneinstellungenoffen = False
screenadminbereichoffen = False
screenmusikplayeroffen = True
screenenergieoptionenoffen = False
startprozess(screenmusikplayer)
startup = 'startup' str(toscreen)
eval(startup)()
def beginsteuerung():
global screenhauptmenuoffen
screenhauptmenuoffen = True
screenhauptmenu()
if __name__ == '__main__':
beginsteuerung()
如果我在此版本或其他版本中運行此代碼,則會收到錯誤代碼:主執行緒不在主回圈中。我嘗試在主回圈中配置一次主題并在函式中使用全域匯入它,我嘗試在函式中使用相同或不同的變數名對其進行配置。
我希望我的代碼不是那么難讀。我希望你能幫我解決這個問題。謝謝!
uj5u.com熱心網友回復:
我通過撰寫測驗代碼找到了解決方案,因此更容易閱讀。我不知道為什么代碼必須那么復雜,但我想分享我最近幾天的經驗。以下代碼對用戶具有幾乎相同的功能。由于樣式線,第二個代碼不起作用。由于我的代碼中有一個名為“screenmanager”的額外函式,第三個再次起作用
#Code without coloured buttons
#Import some Libraries
import tkinter as tk
import time
from tkinter import ttk
from _thread import *
import os
#Var to tell a screen to close
screenopen = True
#threadstarter
def startprozess(name, *var):
print(name)
time.sleep(1)
if var == ():
start_new_thread(name, ())
else:
start_new_thread(name, (var))
#screen1
def screen():
hauptmenu = tk.Tk()
screen_width = hauptmenu.winfo_screenwidth() / 2
screen_height = hauptmenu.winfo_screenheight()
hauptmenu.geometry(f'400x400 50 50')
hauptmenu.title("hauptmenu")
hauptmenu.resizable(False, False)
hauptmenu.attributes('-fullscreen', True)
button0 = ttk.Button(hauptmenu, text="Reload", command = lambda: [setfalse(), startprozess(screen2)])
button0.place(x = 10, y = 10, heigh = 50, width = 100)
global screenopen
while screenopen == True:
hauptmenu.update()
time.sleep(0.1)
hauptmenu.destroy()
#closeoldscreen and allow new screen to open
def setfalse():
global screenopen
screenopen = False
time.sleep(0.5)
screenopen = True
#screen2
def screen2():
hauptmenu2 = tk.Tk()
screen_width = hauptmenu2.winfo_screenwidth() / 2
screen_height = hauptmenu2.winfo_screenheight()
hauptmenu2.geometry(f'400x400 50 50')
hauptmenu2.title("hauptmenu")
hauptmenu2.resizable(False, False)
hauptmenu2.attributes('-fullscreen', True)
button1 = ttk.Button(hauptmenu2, text="Reload", command = lambda: [setfalse(), startprozess(screen)])
button1.place(x = 10, y = 10, heigh = 50, width = 100)
button2 = ttk.Button(hauptmenu2, text="do", command = lambda: startprozess(dosome))
button2.place(x = 110, y = 10, heigh = 50, width = 100)
global screenopen
while screenopen == True:
hauptmenu2.update()
time.sleep(0.1)
hauptmenu2.destroy()
#rando function to simulate something
def dosome():
print("This is some code")
screen()
然后我添加了一些行來為按鈕定義 2 種樣式
#code with coloured buttons which doesn't work
#import some Libraries
import tkinter as tk
import time
from tkinter import ttk
from _thread import *
import os
#var to tell screen to close
screenopen = True
#threadstarter
def startprozess(name, *var):
print(name)
time.sleep(1)
if var == ():
start_new_thread(name, ())
else:
start_new_thread(name, (var))
#screen1
def screen():
hauptmenu = tk.Tk()
screen_width = hauptmenu.winfo_screenwidth() / 2
screen_height = hauptmenu.winfo_screenheight()
hauptmenu.geometry(f'400x400 50 50')
hauptmenu.title("hauptmenu")
hauptmenu.resizable(False, False)
hauptmenu.attributes('-fullscreen', True)
style1 = ttk.Style()
style2 = ttk.Style()
style1.configure('B1.TButton', foreground='black', background='light gray')
style2.configure('B2.TButton', foreground='white', background='blue')
button0 = ttk.Button(hauptmenu, text="Reload", command = lambda: [setfalse(), startprozess(screen2)], style="B2.TButton")
button0.place(x = 10, y = 10, heigh = 50, width = 100)
global screenopen
while screenopen == True:
hauptmenu.update()
time.sleep(0.1)
hauptmenu.destroy()
#close old screen and allow new screen to open
def setfalse():
global screenopen
screenopen = False
time.sleep(0.5)
screenopen = True
#screen2
def screen2():
hauptmenu2 = tk.Tk()
screen_width = hauptmenu2.winfo_screenwidth() / 2
screen_height = hauptmenu2.winfo_screenheight()
hauptmenu2.geometry(f'400x400 50 50')
hauptmenu2.title("hauptmenu")
hauptmenu2.resizable(False, False)
hauptmenu2.attributes('-fullscreen', True)
style1 = ttk.Style()
style2 = ttk.Style()
style1.configure('B1.TButton', foreground='black', background='light gray')
style2.configure('B2.TButton', foreground='white', background='blue')
button1 = ttk.Button(hauptmenu2, text="Reload", command = lambda: [setfalse(), startprozess(screen)], style="B2.TButton")
button1.place(x = 10, y = 10, heigh = 50, width = 100)
button2 = ttk.Button(hauptmenu2, text="do", command = lambda: startprozess(dosome), style="B1.TButton")
button2.place(x = 110, y = 10, heigh = 50, width = 100)
global screenopen
while screenopen == True:
hauptmenu2.update()
time.sleep(0.1)
hauptmenu2.destroy()
#random function to simulate something
def dosome():
print("This is some code")
screen()
這是我在第二個代碼之前創建的第三個代碼,我想知道它為什么會起作用,但是通過上面的第二個代碼,我終于知道我必須在原始代碼中更改什么
#code with coloured buttons with 'screenmanager' which works again
#import some Libraries
import tkinter as tk
import time
from tkinter import ttk
from _thread import *
import os
#var to tell screen to close
screenopen = True
#symbol var for screenmanager to switch between screens easy
screenvar = False
#threadstarter
def startprozess(name, *var):
print(name)
time.sleep(1)
if var == ():
start_new_thread(name, ())
else:
start_new_thread(name, (var))
#the new screenmanager
def screenmanager():
global screenopen
global screenvar
screenopen = False
time.sleep(2)
screenopen = True
if screenvar == False:
startprozess(screen)
screenvar = True
else:
startprozess(screen2)
screenvar = False
#screen1
def screen():
hauptmenu = tk.Tk()
screen_width = hauptmenu.winfo_screenwidth() / 2
screen_height = hauptmenu.winfo_screenheight()
hauptmenu.geometry(f'400x400 50 50')
hauptmenu.title("hauptmenu")
hauptmenu.resizable(False, False)
hauptmenu.attributes('-fullscreen', True)
style1 = ttk.Style()
style2 = ttk.Style()
style1.configure('B1.TButton', foreground='black', background='light gray')
style2.configure('B2.TButton', foreground='white', background='blue')
button0 = ttk.Button(hauptmenu, text="Reload", command = lambda: [setfalse(), startprozess(screenmanager)], style="B2.TButton")
button0.place(x = 10, y = 10, heigh = 50, width = 100)
global screenopen
while screenopen == True:
hauptmenu.update()
time.sleep(0.1)
hauptmenu.destroy()
#closeoldscreen and allow new to open
def setfalse():
global screenopen
screenopen = False
time.sleep(0.5)
screenopen = True
#screen2
def screen2():
hauptmenu2 = tk.Tk()
screen_width = hauptmenu2.winfo_screenwidth() / 2
screen_height = hauptmenu2.winfo_screenheight()
hauptmenu2.geometry(f'400x400 50 50')
hauptmenu2.title("hauptmenu")
hauptmenu2.resizable(False, False)
hauptmenu2.attributes('-fullscreen', True)
style1 = ttk.Style()
style2 = ttk.Style()
style1.configure('B1.TButton', foreground='black', background='light gray')
style2.configure('B2.TButton', foreground='white', background='blue')
button1 = ttk.Button(hauptmenu2, text="Reload", command = lambda: [setfalse(), startprozess(screenmanager)], style="B2.TButton")
button1.place(x = 10, y = 10, heigh = 50, width = 100)
button2 = ttk.Button(hauptmenu2, text="do", command = lambda: startprozess(dosome), style="B1.TButton")
button2.place(x = 110, y = 10, heigh = 50, width = 100)
global screenopen
while screenopen == True:
hauptmenu2.update()
time.sleep(0.1)
hauptmenu2.destroy()
#random function to simulate something
def dosome():
print("This is some code")
screen()
最后但并非最不重要的一點是,我不確定它為什么會這樣作業,但我認為當我直接在 threadstarter 呼叫新螢屏時,我會為新螢屏提供一些變數,這些變數將在錯誤訊息主執行緒中結束,而不是在第二個主回圈中代碼。最終有人知道第二個代碼中的真正錯誤是什么。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/497229.html
