wxpython线程textctrl延迟

问题描述 投票:0回答:4

我对 wxpython 的 textctrl 和线程有任何问题。如果您能帮助解决此问题,我们将不胜感激。

我的程序处理文件,当处理每个文件时,它会在 textctrl 中列出为已完成。当仅处理几个文件时,textctrl 会响应并立即显示自身并且不会消失。即使这些文件很大。对 700mb 文件进行测试并且 textctrl 完美运行吗?

处理多个文件时会出现此问题,例如 20+。在这种情况下,textctrl 会消失 6 或 7 秒,然后重新出现并正常工作。

我尝试过普通线程、守护线程等。还尝试使用 .join() ,这让事情变得更糟。我想知道这是否只是因为我的程序非常占用处理器资源,或者我只是做错了什么。

下面列出了我的线程代码行。到目前为止,这是最快的方法,但对于我的目的来说还不够好。预先感谢,克林顿。

def Worker(self, e, _file):

    match = ''

    with open(_file, 'r') as f:
        data = f.read()

    for char in data:
        if char in self.key:
            match += chr(self.key.index(char))

    open(_file, 'w').close()

    with open(_file, 'w') as f:
        f.write(match)

    wx.CallAfter(self.ListFilesEncrypt, e, _file)

if __name__ == '__main__':
    for _file in self.file2process:
        self.filenum += 1
        Thread(target=self.Worker, args=(e, _file,)).start()
multithreading wxpython textctrl
4个回答
3
投票

使用线程安全方法更新 GUI。在wxPython中,有3:

  • wx.CallAfter
  • wx.CallLater
  • wx.PostEvent

您还应该查看 wxPython wiki,了解有关 wxPython 和线程的信息:

我还写了一个关于该主题的教程:

更新: 这是一个简单的示例,创建 40 个线程并“处理”40 个组成的文件。当每个线程完成时,它会更新显示。不过,我没有看到你所说的问题。

import random
import time
import wx

from threading import Thread
from wx.lib.pubsub import Publisher

########################################################################
class TestThread(Thread):
    """Test Worker Thread Class."""

    #----------------------------------------------------------------------
    def __init__(self, fname, sleepAmt):
        """Init Worker Thread Class."""
        Thread.__init__(self)
        self.fname = fname
        self.sleepAmt = sleepAmt
        self.start()    # start the thread

    #----------------------------------------------------------------------
    def run(self):
        """Run Worker Thread."""
        # This is the code executing in the new thread.
        time.sleep(self.sleepAmt)
        msg = "%s finished in %s seconds!" % (self.fname, self.sleepAmt)
        wx.CallAfter(Publisher().sendMessage, "update", msg)


########################################################################
class MyForm(wx.Frame):

    #----------------------------------------------------------------------
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, "Tutorial")

        panel = wx.Panel(self, wx.ID_ANY)
        self.updateText = wx.TextCtrl(panel, style=wx.TE_MULTILINE)
        self.btn = btn = wx.Button(panel, label="Start Thread")

        btn.Bind(wx.EVT_BUTTON, self.onButton)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.updateText, 1, wx.ALL|wx.EXPAND, 5)
        sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5)
        panel.SetSizer(sizer)

        # create a pubsub receiver
        Publisher().subscribe(self.updateDisplay, "update")

    #----------------------------------------------------------------------
    def onButton(self, event):
        """
        Runs the thread
        """
        for i in range(40):
            fname = "test%s.txt" % i
            secs = random.choice(range(3, 15))
            TestThread(fname, secs)

    #----------------------------------------------------------------------
    def updateDisplay(self, msg):
        """
        Receives data from thread and updates the display
        """
        data = msg.data + "\n"
        self.updateText.WriteText(data)

#----------------------------------------------------------------------
# Run the program
if __name__ == "__main__":
    app = wx.PySimpleApp()
    frame = MyForm().Show()
    app.MainLoop()

我使用 Python 2.6 和 wxPython 2.8.12.1 在 Windows 7 上运行


0
投票

您的线程应该而不是直接更新文本控件 - 它们应该使用

wx.CallAfter
,或者更好的是为主线程(GIU)设置一个标志来更新控件 - 这听起来像是一个结束线程方法可能是合适的。


0
投票

不仅仅是CPU密集型,还可以是IO密集型。 IO 密集型应用程序会对性能产生非常大的影响,尤其是当您还将 IO 单元用于其他关键目的(例如分页)时。我建议一次提供 5 到 10 个,其余的排队。


0
投票

我正在使用 wxpython 4.1.1 并发现这不再有效。

wxPyDeprecationWarning: wx.lib.pubsub has been deprecated, plese migrate your code to use pypubsub, available on PyPI.
======================================================================
          ***    ATTENTION   ***
This messaging protocol is deprecated. This module, and hence arg1
messaging protocol, will be removed in v3.4 of PyPubSub. Please make
the necessary changes to your code so that it no longer requires this
module. The pypubsub documentation provides steps that may be useful
to minimize the chance of introducing bugs in your application.
======================================================================
© www.soinside.com 2019 - 2024. All rights reserved.