Python 2.7 避免GUI冻结
我开发了一个简单的Python应用程序,做了一些工作,然后我决定使用Tkinter添加一个简单的GUI 问题是,当我调用一个名为startprocess的函数并开始做一些处理器很重的事情时,窗口会冻结 我知道这是一个常见的问题,我已经读到我应该使用非常复杂的多线程,因为该函数也会更新GUI,或者将我的代码划分为不同的函数,每个函数工作一段时间。无论如何,下面的代码中是否需要任何修改以避免GUI冻结Python 2.7 避免GUI冻结,python-2.7,tkinter,python-multithreading,Python 2.7,Tkinter,Python Multithreading,我开发了一个简单的Python应用程序,做了一些工作,然后我决定使用Tkinter添加一个简单的GUI 问题是,当我调用一个名为startprocess的函数并开始做一些处理器很重的事情时,窗口会冻结 我知道这是一个常见的问题,我已经读到我应该使用非常复杂的多线程,因为该函数也会更新GUI,或者将我的代码划分为不同的函数,每个函数工作一段时间。无论如何,下面的代码中是否需要任何修改以避免GUI冻结 import threading import tkinter as tk from tkinte
import threading
import tkinter as tk
from tkinter import filedialog
from tkinter import messagebox
import os, datetime, sys, subprocess
import parselog_v1
# diplay messagebox window
def MessageBox(windowLable,msg):
messagebox.showinfo(windowLable, msg)
# check if Dir empty
def checkDirEmpty(work_path):
if os.path.isdir(work_path):
if not os.listdir(work_path):
print ("No Files found in directory")
MessageBox('Log Parser', 'No Files found in directory.')
else:
return True
# launch app in center of screen
def center_window(width=300, height=200):
# get screen width and height
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
# calculate position x and y coordinates
x = (screen_width/2) - (width/2)
y = (screen_height/2) - (height/2)
root.geometry('%dx%d+%d+%d' % (width, height, x, y))
# application frame
class Application(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master)
self.pack()
self.createWidgets()
self.master.title("Log Parser")
def createWidgets(self):
self.Run_Main = tk.Button(self)
self.Run_Main["text"] = "Browse for logs"
self.Run_Main["fg"] = "blue"
self.Run_Main["command"] = self.startProcess
self.Run_Main.pack(side='left',padx=0)
self.QUIT = tk.Button(self)
self.QUIT["text"] = "Quit!"
self.QUIT["fg"] = "red"
self.QUIT["command"] = self.quit
self.QUIT.pack(side='right',padx=5)
def startProcess(self):
global Src_foldername
Src_foldername = filedialog.askdirectory()
Src_foldername = Src_foldername.replace("/", "\\")
print("Source folder: " + Src_foldername)
if checkDirEmpty(Src_foldername):
# process logs
# multithread
print("Processing...")
self.refresh()
threading.Thread(target=parselog_v1.main(Src_foldername))
# scroll text inside application frame
class scrollTxtArea:
def __init__(self, root):
frame = tk.Frame(root)
frame.pack()
self.textPad(frame)
return
class IORedirector(object):
'''A general class for redirecting I/O to this Text widget.'''
def __init__(self, text_area):
self.text_area = text_area
class StdoutRedirector(IORedirector):
'''A class for redirecting stdout to this Text widget.'''
def textPad(self, frame):
# add a frame and put a text area into it
textPad = tk.Frame(frame)
self.text = tk.Text(textPad, height=21, width=68)
self.text.config()
# add a vertical scroll bar to the text area
scroll = tk.Scrollbar(textPad)
self.text.configure(yscrollcommand=scroll.set,background="black", foreground="green")
# pack everything
self.text.pack(side=tk.LEFT, pady=2)
scroll.pack(side=tk.RIGHT, fill=tk.Y)
textPad.pack(side=tk.TOP)
self.text.insert("end", "Begin by selecting log folder..." + "\n")
self.text.configure(state='disabled') # disable text editing
sys.stdout = (self) # to begin logging stdio to GUI
return
def write(self, txt):
self.text.configure(state='normal')
self.text.insert('end', txt)
self.text.configure(state='disabled')
root = tk.Tk()
root.resizable(width=False, height=False)
center_window(500, 300) # launch in center of screen
app = Application(master=root)
scrollFrame = scrollTxtArea(root)
app.mainloop()
root.destroy()
你们用错了线 第一个:target=需要不带和参数的函数名。 您可以将参数分配给args=它必须是tuple,即使只有一个参数
threading.Thread(target=parselog_v1.main, args=(Src_foldername,) )
现在,您的代码以普通函数的形式运行parselog_v1.main,等待结果,并将此结果作为函数名分配给taget=-因此您有如下内容:
result = parselog_v1.main(Src_foldername)
threading.Thread(target=result)
它停止mainloop,因此无法获取鼠标/键盘事件、刷新窗口等,因此看起来像是窗口冻结
第二:正确创建线程后,必须启动它
my_thread = threading.Thread(target=parselog_v1.main, args=(Src_foldername,) )
my_thread.start()
我们无法在没有parselog_v1的情况下运行它。@furas我做了修改,您的建议很有效。非常感谢。