wxpython线程textctrl延迟 [英] wxpython threading textctrl delay

查看:257
本文介绍了wxpython线程textctrl延迟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对wxpython的textctrl和线程有任何问题.感谢您为解决此问题提供的帮助.

I have any issue with wxpython's textctrl and threading. Would appreciate any help in resolving this issue.

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

My program processes files, as and when each file is processed it is listed within the textctrl as being completed. When working with just a few files the textctrl is responsive and displays itself immediately and does not disappear. Even if these files are large. Did a test on a 700mb file and textctrl worked perfectly.

在许多文件上工作时会发生问题,例如exmaple说20+.在这种情况下,textctrl消失6或7秒钟,然后重新出现并正常运行.

The problem occurs when workin on many files, say 20+ for exmaple. Under these circumstances the textctrl disappears for 6 or 7 seconds, then reappears and works as normal.

我尝试了普通的线程,守护程序线程等.还尝试了使用.join(),这会使情况变得更糟.我想知道这是仅因为我的程序占用大量处理器,还是我做错了什么.

I have tried normal threading, daemon threading etc.. Also tried using .join() which made things even worse. I'm wondering if this is just because my program is very processor intensive, or if I'm just doing something wrong.

下面列出了我的线程代码行.到目前为止,这是迄今为止最快的方法,只是不足以达到我的目的.预先感谢克林顿.

My thread line of code is listed below. So far this is by far the fastest method, just not good enough for my purposes. Thanks in advance, Clinton.

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()

推荐答案

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

Update the GUI using thread-safe methods. In wxPython, there are 3:

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

您还应该查看wxPython Wiki,以获取有关wxPython和线程的信息:

You should also take a look the wxPython wiki for information on wxPython and threading:

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

I also wrote a tutorial on the topic:

更新:这是一个简单的示例,该示例创建40个线程并处理" 40个组成的文件.每个线程完成后,它将更新显示.但是,我看不到您提到的问题.

UPDATE: Here is a simple example that creates 40 threads and "processes" 40 made up files. It updates the display when each thread is done. However, I do not see the issue you speak of.

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()

我正在Windows 7上使用带wxPython 2.8.12.1的Python 2.6运行

I am running on Windows 7 using Python 2.6 with wxPython 2.8.12.1

这篇关于wxpython线程textctrl延迟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆