我剛剛用 Tkinter GUI 做了一個簡單的專案,但是當我啟動它并輸入用戶名時,它的視窗停止回應,直到requests行程instaloader完成,然后就可以了。我可以做一個“請稍候”以避免不回應的事情嗎?或者如果我遷移到另一個 GUI 會變得更好嗎?
from tkinter import *
import instaloader
from PIL import ImageTk, Image
import requests
from io import BytesIO
def insta(username):
L = instaloader.Instaloader()
profile = instaloader.Profile.from_username(L.context, username)
label2.config(text=profile.full_name)
label3.config(text=profile.biography)
url=profile.get_profile_pic_url()
response = requests.get(url)
img_data = response.content
img = ImageTk.PhotoImage(Image.open(BytesIO(img_data)))
panel = Label(image=img)
panel.place(x=150,y=100)
label4.config(text="Done")
window = Tk()
window.geometry("600x600")
window.maxsize(600, 600)
window.minsize(600, 600)
window.title("Instagram Profile Downloader")
# label
label = Label(window, text="Enter UserName to Download Profile Image:",
fg="black", bg="#f4b265")
label.place(x=180, y=20)
label2 = Label(window, text="")
label2.place(x=100, y=70)
label3 = Label(window, text="")
label3.place(x=100, y=100)
label4 = Label(window, text="", fg="red")
label4.place(x=380, y=50)
# button
def butt():
if input.get() == "":
label4.config(text="Please Enter Username")
return
else:
insta(input.get())
button = Button(window, text="Download", fg="white",
bg="#095e95", command=butt)
button.place(x=310, y=47)
# input
input = Entry(window)
input.place(x=180, y=50)
window.mainloop()
uj5u.com熱心網友回復:
Tkinter 的東西在主執行緒中運行,所以當你在主執行緒中呼叫一些需要時間的東西時,GUI 將在該函式運行時被阻塞。為了解決這個問題,您需要使用執行緒來確保對 insta 的呼叫與運行 tkinter 的主執行緒分開運行,但還需要確保您不在該其他執行緒上呼叫 tkinter 函式,因為 tkinter 僅在主執行緒中作業. 這是您如何實作它的示例:
import threading
class InstaThread:
def __init__(self, username):
self.profile = None
self.img_data = None
# Disable the button while instaloader is running
button["text"] = "Loading..."
button["state"] = DISABLED
self.thread = threading.Thread(target=self.insta, args=(username,))
self.thread.start()
self.check_thread()
# Check periodically if the function has alread run
def check_thread(self):
if self.thread.is_alive():
window.after(100, self.check_thread)
else:
label2.config(text=self.profile.full_name)
label3.config(text=self.profile.biography)
panel = Label(window)
img = ImageTk.PhotoImage(Image.open(BytesIO(self.img_data)))
# Also updated this so that the image would really show in the panel
panel.image = img
panel.config(image = img)
panel.place(x=150,y=100)
label4.config(text="Done")
# Reset button
button["text"] = "Download"
button["state"] = NORMAL
# Function that will be running in other thread and updating the profile and img_data varibles of this class
def insta(self, username):
L = instaloader.Instaloader()
self.profile = instaloader.Profile.from_username(L.context, username)
url=self.profile.get_profile_pic_url()
response = requests.get(url)
self.img_data = response.content
現在在 Butt 函式中,您只需要呼叫InstaThread(input.get())而不是insta(input.get())像這樣,當您單擊按鈕時,它將禁用并在函式運行時說 Loading 并且 GUI 的其余部分將繼續正常作業
我的另一個建議是為您的 GUI 創建一個類,以便您將所有內容放在一個地方,并且可以在類中的任何位置訪問它,這樣您就不必為按鈕和標簽設定全域變數。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/489893.html
