我正在编写一个wxpython程序。
如果您在程序中打开一个文件,它会计算文件中的行数并将其显示在 staticText
小部件中。
相关代码如下:
在类框架
中
def on_select_file(self, event):
'''Event handler for selecting file'''
filepath = getFile() # This is a seperate method which asks the user to select a file and returns the path
threading.Thread(target = methods.count_lines, args = (filepath, self.staticText)).start()
方法.py
def count_lines(filepath, staticText):
with open(filepath) as f:
for i, _ in enumerate(f): pass
staticText.SetLabel(str(i+1))
我正在处理的大多数文件都非常大(3-4 GB),大约有 2500 万行。因此,如果我打开一个大文件,则需要几十秒的时间来计数并显示编号。的线路。但是,如果我选择一个大文件,并且在更新 staticText
小部件之前,打开另一个较小的文件,staticText
小部件会显示新的计数,但一段时间后会显示前一个文件的计数。我理解这是因为前一个线程仍在运行并在结束后更新了小部件。
我尝试通过将标志变量作为参数传递给计数器函数来解决这个问题,以检查小部件是否已更新。然而它似乎不起作用。还有其他方法可以避免这种情况吗?
最佳答案
本质上,创建一个包含当前行计数作为成员的自定义事件类型,并在工作线程中使用 wx.PostEvent() 定期将该类型的事件发布到包含静态文本小部件的类。然后,当主线程恢复并处理其事件循环时,您可以使用接收到的事件报告的行数来设置文本字符串。
这样的事情应该有效:
import time
from threading import *
import wx
import os.path
EVT_LINE_NUMBER_UPDATE_ID = wx.NewId()
class LineNumberUpdateEvent(wx.PyEvent):
def __init__(self, lineNum):
wx.PyEvent.__init__(self)
self.SetEventType(EVT_LINE_NUMBER_UPDATE_ID)
self.lineNumber = lineNum
class WorkerThread(Thread):
def __init__(self, notify_window, filename):
Thread.__init__(self)
self._notify_window = notify_window
self._filename = filename
self.start()
def run(self):
with open(this._filename,"r") as file:
count = 0;
for line in file:
count++
if count % 50 == 0: # post an event every 50 lines
wx.PostEvent(self._notify_window, LineNumberUpdateEvent(count))
wx.PostEvent(self._notify_window, LineNumberUpdateEvent(count)) # last event
class MainFrame(wx.Frame):
def __init__(self, parent, id, filename):
wx.Frame.__init__(self, parent, id, 'Threaded File Loader')
self.status = wx.StaticText(self, -1, '', pos=(0,100))
self.Bind(EVT_LINE_NUMBER_UPDATE_ID, self.OnLineNumberUpdate)
if (os.path.isfile(filename))
self.worker = WorkerThread(self,filename)
def OnLineNumberUpdate(self, event):
self.status.SetLabel(str(event.lineNumber))
这是根据 wx Wiki 上发布的示例改编的:
关于python - 在 wxPython 中使用多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25301052/