1

ログ ウィンドウ (textctrl ボックス) に書き込む必要があるいくつかの異なるスレッドを使用する wxpython アプリケーションを作成しました。このため、このチュートリアルに従いました

http://www.blog.pythonlibrary.org/2010/05/22/wxpython-and-threads/

wx.CallAfter と PubSub を使用しました。

これは私の元のコードでした

from wx.lib.pubsub import Publisher

Publisher().subscribe(self.messenger, "update")

wx.CallAfter(Publisher().sendMessage, "update", "Thread finished!")

def messenger(self, msg):
    self.logtxtctrl.WriteText(msg.data)

このコードは見事に機能し、pyinstaller を使用してコードの exe を作成するのは簡単だと思いました。

私はなんて間違っていたのでしょう。

いくつかのコメントを読んだ後、pubSub API には 2 つのバージョンがあるようです。

http://wiki.wxpython.org/WxLibPubSub

コードを次のように調整しました

from wx.lib.pubsub import setuparg1

from wx.lib.pubsub import pub

pub.subscribe(self.messenger, "update")

wx.CallAfter(pub.sendMessage, "update", data="Program success")

def messenger(self, data):
    self.logtxtctrl.WriteText(data)

このコードは機能するようになりましたが、再び pyinstaller を使用しようとしましたが、まだ運がありません。

だから私は次の記事を読みます

pubsub を pyinstaller で動作させるには?

http://www.pyinstaller.org/ticket/312

どちらも非常に便利で、フック ファイルとさまざまな仕様ファイルを変更するさまざまなバリエーションをすべて試しましたが、まだ動作しません。

これらの投稿はほぼ 2 年前のもので、pubsub を追加すれば解決すると思っていました。

どのフックが必要なのか、スペックファイルに何が必要なのか、それを機能させるために必要なその他の要素のプロセスを誰か説明してもらえますか?

解決策がない場合、他にどのようにウィジェットとスレッドセーフな通信を行うことができますか?

4

1 に答える 1

0

試す

from wx.lib.pubsub import setupkwargs
from wx.lib.pubsub import pub

私はあなたが探していることを正確に行うプログラムを持っています。私が使用する関連するコードは以下のとおりです。LoggerWriteText を使用するのではなく、などの関数を作成することをお勧めします。これにより、変更が行われる際の苦痛が軽減されます。

class Frame(wx.Frame):
    def __init__(self, *args, **kwargs):
        super(Frame, self).__init__(*args, **kwargs)
        self.InitUI()
        self.SetSize((380,340))
        self.Show()
        self.count = 0
        self.threads = []
        pub.subscribe(self.__StatusChanged, 'status.changed')

    def __StatusChanged(self, asset, time, status):
        if status:
            msg = 'Online'
        else:
            msg = 'Offline'
        self.Logger('{}: {} - {}\n'.format(time, asset, msg))

    def Logger(self, msg):
        self.txtresults.AppendText(msg)

class PingAssets(threading.Thread):
    def __init__(self, threadNum, asset, window):
        threading.Thread.__init__(self)
        self.threadNum = threadNum
        self.window = window
        self.asset = asset
        self.signal = True
        self.status = None

    def run(self):
        while self.signal:
            logging.debug("Thread {} started run sequence.".format(self.threadNum))
            start_time = datetime.now().strftime(self.fmt)
            try:
                newstatus = onlinecheck.check_status(self.asset)
                if newstatus != self.status or self.verbose:
                    self.status = newstatus
                    pub.sendMessage('status.changed', asset=self.asset,
                                    time=start_time, status=self.status)
于 2013-08-20T15:43:38.983 に答える