我是 tkinter 的新手。當我試圖創建一個回圈時for i in range(100),GUI“崩潰”,這意味著我無法操作 GUI,直到回圈結束(即使我沒有在文本中插入任何內容)。在我檢查了一些資訊后,我嘗試了執行緒。它確實有效。但...
from tkinter import *
import time
from threading import Thread
class Application(Frame):
def __init__(self):
self.root = Tk()
self.root.title('tkinter')
self.root.geometry('400x300 400 100')
self.createWidget()
self.root.mainloop()
def createWidget(self):
self.text = Text(self.root, width=40, height=15, relief=SOLID, borderwidth=1)
self.text.grid(row=0, column=0)
self.button = Button(self.root, text="click", relief=SOLID, borderwidth=1, command=self.button_click)
self.button.grid(row=1, column=0)
pass
def button_click(self):
t1 = Thread(target=self.loop)
t1.start()
def loop(self):
for i in range(100):
self.text.insert(END, chars=str(i) '\n')
time.sleep(1)
self.root.update()
self.text.see(END)
if __name__=="__main__":
Application()
但是每次遇到回圈都不可能使用執行緒(太難了,在某些情況下必須順序執行)。有什么有用/簡單的方法來處理它嗎?
uj5u.com熱心網友回復:
如果您正在尋找一種以給定速度插入文本的方法,那么可以使用 tkinter 來實作after。
該代碼試圖闡明after.
該程序可以通過按 Escape 鍵來中斷。這將cancel_after毫不拖延地完成文本插入。
import tkinter as tk
data = dir(tk) # or str.split('\n')
root = tk.Tk()
text = tk.Text(root, undo = 1, wrap = tk.NONE)
text.pack()
def insert_text():
global delay
d = data.pop(0)
text.insert(tk.END, f"{d}\n")
if len(data) > 0:
delay = root.after(500, insert_text)
# cancel timed input
def stop(event):
root.after_cancel(delay)
for d in data:
text.insert(tk.END, f"{d}\n")
root.bind("<Escape>", stop)
# start output
delay = root.after(50, insert_text)
root.mainloop()
uj5u.com熱心網友回復:
我已經找到了一種更好的方法來定位介面,而不是更新由其他回圈或 tkinter 回圈實踐中的多執行緒引起的問題。只要視窗類中的函式操作函式MainWindows是用子執行緒打開的,無論子執行緒打開的這個函式中有多少回圈或多執行緒(執行緒池),都不會影響GUI更新,并且可以實時滾動日志。
from tkinter import *
import time
import requests
from threading import Thread
from concurrent.futures import ThreadPoolExecutor
class MainWindows(Frame):
def __init__(self, master):
super().__init__(master=master)
self.master=master
self.createWidget()
self.pack()
pass
def createWidget(self):
self.text = Text(self, width=50, height=20, relief=SOLID, borderwidth=1, fg="gray")
self.text.pack()
self.button = Button(self, text="click", command=self.thread)
self.button.pack()
pass
def thread_show_info(self, i):
self.text.insert(END, chars=str(i) '\n')
self.text.see(END)
time.sleep(1)
def threadpool_show_info(self):
with ThreadPoolExecutor(10) as t:
for q in range(1, 1000):
t.submit(self.thread_show_info, i=q)
def thread(self):
t1 = Thread(target=self.threadpool_show_info)
t1.start()
if __name__=="__main__":
root = Tk()
root.title('test')
root.geometry('400x300 450 100')
a = MainWindows(master=root)
root.mainloop()
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/411591.html
標籤:
