【问题标题】:pyinstaller exe with pubsub带有 pubsub 的 pyinstaller exe
【发布时间】:2013-08-22 04:03:45
【问题描述】:

我编写了一个 wxpython 应用程序,它使用了几个不同的线程,所有这些线程都需要写入日志窗口(textctrl 框)。因此,我遵循了本教程

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 会很容易。

我错了!!

所以在阅读了一些 cmets 之后,似乎有两个版本的 pubSub API,所以使用这个

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,但仍然没有成功。

于是我又看了下面的文章

How to get pubsub to work with pyinstaller?

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

这两者都非常有用,我尝试了更改挂钩文件和不同规范文件的所有不同变体,但仍然无法正常工作。

这些帖子几乎是 2 年前的事了,我原以为添加 pubsub 就可以解决了。

谁能解释一下我需要什么钩子、规范文件中包含什么以及我需要做的其他元素才能使其工作的过程?

如果没有解决方案,我还能如何与小部件进行线程安全通信?

【问题讨论】:

    标签: wxpython pyinstaller


    【解决方案1】:

    试试

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

    我有一个程序可以完全满足您的需求。我使用的相关代码如下。我建议创建一个诸如Logger 之类的函数,而不是使用WriteText,它在更改发生时为我节省了一些痛苦。

    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)
    

    【讨论】:

    • 我会试一试的,非常感谢。希望它能与 pyinstaller 一起使用 - 你能确认一下吗?
    • 我可以。我使用 PyInstaller 分发所有内容。如果它有效或有帮助,我将不胜感激 +1 / 标记为最佳答案。旁注:我还为 PyInstaller github.com/multiphrenic/GooeyPi 创建了一个 GUI 前端。它目前只兼容最新的 PyInstaller 开发版本(2.1),而不是稳定的 2.0。但是,对于大多数用例,我建议使用 2.1,因为那里有许多错误修复。
    • 我刚刚花了几个小时试图让它工作,但我的 wxpython 2.8 当前版本仍然没有运气。因此,我将其删除并获得了开发版本以及 pyinstaller 的开发版本,使用了我相同的脚本并使用了您的 pubsub 导入语句并运行了 pyinstaller。它找到了它,现在我的 exe 可以工作了。感谢您的帮助
    • 顺便说一句,我下载了 gooeypi 的 zip 并在 src 文件夹中打开了一个新的命令提示符窗口并执行了 python gooeypi.py 并收到一条错误消息,说它找不到 .ini 文件,所以我将上一级的那个复制到 src 文件夹中,然后再试一次。它启动了,我给了它 pyinstaller 文件夹的路径,然后将它指向我的代码。它失败了,因为它找不到-dist。不知道我应该在哪里设置这个
    • 感谢您查看此内容。我的代码中有一个小错误,我已修复。如果你不介意,再试一次。如果您看到错误,也许您可​​以在 GitHub 上发布问题(可能比这里更适合)。我真的很感激!
    猜你喜欢
    • 2019-01-02
    • 2019-12-04
    • 2017-10-08
    • 2020-11-18
    • 1970-01-01
    • 1970-01-01
    • 2016-05-17
    • 2019-12-22
    • 2018-12-18
    相关资源
    最近更新 更多