You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyInstaller打包含subprocess.Popen的PyQt5程序后多窗口重复弹出的问题求解

PyInstaller打包含subprocess.Popen的PyQt5程序后多窗口重复弹出的问题求解

我太懂你这种崩溃的感觉了——在PyCharm里调试一切正常,点按钮就乖乖跑子进程打日志,结果打包成exe后,点一下按钮就弹一个新的主窗口,简直没完没了!

问题根源

其实这个坑很多人都踩过:当你用pyinstaller -w参数打包GUI程序时,sys.executable指向的不是系统的Python解释器,而是你打包出来的gui_print_log.exe本身!所以你在start_process里写[sys.executable, 'subprocess_script.py'],本质上是反复启动自己的主程序,自然就会不断弹出新窗口了。

解决方案(完全符合你的要求:用subprocess.Popen、尽量不修改StreamReader)

下面给你两个可行的方案,选哪个看你的需求:

方案1:指定真实的Python解释器路径

直接把sys.executable替换成系统里Python解释器的绝对路径,或者让程序自动检测:

修改gui_print_log.py里的start_process方法:

def start_process(self):
    # 判断当前是否是打包后的环境
    if getattr(sys, 'frozen', False):
        # 打包后,用系统的Python解释器(如果是虚拟环境,换成你虚拟环境的python.exe路径)
        python_exe = "python.exe"
        # 如果你不确定路径,可以从环境变量里找,比如:
        # import os
        # python_exe = os.path.join(os.environ.get('PYTHON_HOME', ''), 'python.exe')
    else:
        # 开发环境下,用原来的sys.executable
        python_exe = sys.executable

    process = subprocess.Popen(
        [python_exe, 'subprocess_script.py'],
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        text=True,
        encoding="utf-8"
    )

    self.stream_reader = StreamReader(process)
    self.stream_reader.append_text.connect(self.append_log)
    self.stream_reader.start()

然后打包后,把subprocess_script.py复制到dist/gui_print_log目录下(和exe同目录),这样子进程就能找到脚本了。

方案2:把子脚本也打包成独立exe

如果不想依赖系统Python,也可以把subprocess_script.py单独打包成exe:

  1. 先打包子脚本:
pyinstaller -D subprocess_script.py
  1. 把生成的dist/subprocess_script/subprocess_script.exe复制到主程序的dist/gui_print_log目录下
  2. 修改主程序的start_process方法:
def start_process(self):
    process = subprocess.Popen(
        ['subprocess_script.exe'],
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        text=True,
        encoding="utf-8"
    )

    self.stream_reader = StreamReader(process)
    self.stream_reader.append_text.connect(self.append_log)
    self.stream_reader.start()

这个方案完全不依赖系统Python,而且你的StreamReader代码完全不需要修改,完美符合你的要求!

验证一下

不管选哪个方案,打包后运行主exe,点击按钮就只会有一个主窗口,子进程的日志会正常输出到文本框里,不会再弹新窗口了。

备注:内容来源于stack exchange,提问作者jyj789

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 18:07:55