0

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

3 に答える 3

3

スレッドセーフな方法を使用して GUI を更新します。wxPython には、次の 3 つがあります。

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

wxPython とスレッド化に関する情報については、wxPython wiki も参照してください。

このトピックに関するチュートリアルも書きました。

更新:これは、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()

wxPython 2.8.12.1でPython 2.6を使用してWindows 7で実行しています

于 2013-08-28T17:58:47.190 に答える
0

CPU を集中的に使用するだけでなく、IO を集中的に使用する可能性があります。また、IO 集約型のアプリケーションは、特にページングなどの他の重要な目的にも IO ユニットを使用している場合、パフォーマンスに非常に大きな影響を与える可能性があります。一度に 5 ~ 10 個を提供し、残りをキューに入れることをお勧めします。

于 2013-08-28T18:01:16.333 に答える