pyinstaller exe with pubsub

耗尽温柔 提交于 2020-01-16 01:14:12

问题


I have written a wxpython application that uses several different threads all of which need to write to the log window (textctrl box). Because of this I followed this tutorial

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

And used wx.CallAfter and PubSub.

This was my original code

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)

this code worked brilliantly and thought it would be easy to use pyinstaller to create an exe for my code.

How wrong was I!!

So after reading some comments it seems there are two versions of the pubSub API, so using this

http://wiki.wxpython.org/WxLibPubSub

I tweaked my code to the following

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)

This code now works and again I tried to use pyinstaller and still no luck.

So i then read the following articles

How to get pubsub to work with pyinstaller?

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

Both of which were very useful and I tried all the different variations of changing the hook files and different spec files, I still cannot get it to work.

These posts are almost 2 years ago and I would have thought adding pubsub would be solved.

Can anyone please explain the process of what hooks I need, what to have in a spec file and other elements I need to do to get it to work?

if there is no solution how else can I do thread safe communications to widgets?


回答1:


Try

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

I have a program that does exactly what you're looking for. The relevant pieces of code I use is below. I'd recommend creating a function such as Logger rather than using WriteText, it's saved me some pain down the road as changes come through.

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)


来源:https://stackoverflow.com/questions/18329376/pyinstaller-exe-with-pubsub

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!