【发布时间】:2021-09-02 05:42:49
【问题描述】:
我有一个处理视频上传到谷歌驱动器的脚本,所以我想用 Tkinter 为我的 python 脚本制作一个 gui。在用户界面上,我希望用户从他/她的计算机中选择要上传的视频。在上传功能上,我还会刷新一个文本区域以向用户提供有关上传过程的信息。
问题是,当用户选择文件并启动上传功能时,gui 冻结并且文本区域没有显示任何信息。
上传功能完成后,一切恢复正常,它只是刷新整个窗口,显示我想看到的文本信息上传完成后
我知道我必须为我的上传功能使用线程,因为它是一项长时间运行的任务,但即使在使用线程之后它仍然冻结直到上传功能完成。
任何帮助将不胜感激:)
from tkinter import *
from tkinter import filedialog
import threading
root = Tk()
root.title("Drive Video Uploader")
root.geometry("400x500")
def main():
creds = None
# The file token.json stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
tokenPath='token.json'
credPath='credentials.json'
if os.path.exists(tokenPath):
creds = Credentials.from_authorized_user_file(tokenPath, SCOPES)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(credPath, SCOPES)
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open(tokenPath, 'w') as token:
token.write(creds.to_json())
service = build('drive', 'v3', credentials=creds)
root.label_0 = Label(root,name="label_0", text="\n").pack()
root.label_1 = Label(root, name="label_1", text="Please select videos to upload drive!").pack()
root.button_1 = Button(root, name="button_1",text="Select Videos", command= lambda: threading.Thread(target=videoSelection(service)).start().pack()
root.label_2 = Label(root,name="label_2", text="\n").pack()
root.text_1 = Text(root, width=50, height=25, name="text_1", state=DISABLED,bg="dark blue", fg="white", bd=4).pack()
root.mainloop()
def videoSelection(service):
selectedVideoPaths = filedialog.askopenfilenames(initialdir= os.getcwd(),
title= "Please select a file:",
filetypes=[("MP4 files","*.mp4")])
textArea = root.nametowidget('text_1')
textArea.configure(state=NORMAL)
textArea.delete("1.0",END)
textArea.configure(state=DISABLED)
for video in selectedVideoPaths:
textArea.configure(state=NORMAL)
textArea.insert(END,"Upload started for: " + video + "\n")
textArea.configure(state=DISABLED)
uploadVideo(service=service,videoFilepath=video)
if __name__ == '__main__':
main()
【问题讨论】:
-
目前videoSelection函数包含GUI和上传代码。您为其创建线程的函数不应包含任何 GUI 代码,而应完全专注于上传视频。
-
我已经将 for 循环从 videoSelection 函数中分离出来,并使其成为另一个函数。还将uploadVideo函数的行改为threading.Thread(target=uploadVideo(service=service,videoFilepath=video)).start()。它没有帮助@scotty3785
-
您应该在自己的线程中运行整个循环。将视频文件路径列表传递给线程并启动线程。我看看能不能一起做个demo。
标签: python multithreading tkinter