首页 > 系统相关 >PyQt5 使用 Pyinstaller+multiprocessing 打包多进程应用时,引发的一些问题

PyQt5 使用 Pyinstaller+multiprocessing 打包多进程应用时,引发的一些问题

时间:2024-10-16 12:10:14浏览次数:9  
标签:__ Pyinstaller process self PyQt5 sys 进程 multiprocessing

解决 Pyinstaller 打包 PyQt5+multiprocessing 多进程应用时,引发的一些问题,包括反复启动主进程,以及:AttributeError: 'NoneType' object has no attribute 'write'

本文提供一些解决方案,您可能需要根据自己的实际情况,逐个尝试,直到自己的multiprocessing多进程应用正常运行

一、解决反复启动 GUI 主进程的问题

这个问题的产生原因,只知道是与Windows系统有关,因为Python官方在multiprocessing库中指明,这个方法只影响windows系统,且主要针对生成可执行文件,也就是Windows 下的 exe程序
官方原文:multiprocessing.freeze_support()

问题复现

1. 准备示例程序

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
"""
@ File        : test_multiprocessing.py
@ Author      : yqbao
@ Version     : V1.0.0
@ Description : 
"""
import sys
from multiprocessing import Process
import time
from PyQt5.QtWidgets import QApplication, QPushButton, QVBoxLayout, QWidget


def background_task():
    while True:
        print("后台进程正在运行...")
        time.sleep(3)  # 模拟一些后台工作


class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle('PyQt5 与 Multiprocessing')
        layout = QVBoxLayout()

        self.start_button = QPushButton('启动后台进程')
        self.start_button.clicked.connect(self.start_process)

        layout.addWidget(self.start_button)
        self.setLayout(layout)

    def start_process(self):
        self.process = Process(target=background_task)
        self.process.start()
        print("后台进程已启动。")

    def closeEvent(self, event):
        self.process.terminate()
        self.process.join()
        event.accept()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

运行后,可以得到下面这样的窗口
image

2. 使用下面的两种方式打包

# 方式1,无 -w
pyinstaller -D -y .\test_process.py

# 方式2,有 -w
pyinstaller -D -w -y .\test_process.py

无论那种方式,启动后,若点击“启动后台进程”均无法成功,且主进程会反复启动
image

解决办法

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
"""
@ File        : test_multiprocessing.py
@ Author      : yqbao
@ Version     : V1.0.0
@ Description : 
"""

from multiprocessing import freeze_support

... # 忽略,无变化

if __name__ == '__main__':
    freeze_support()  # 使用冻结

    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

无论那种打包方式,启动后,均正常运行
image

二、解决AttributeError: 'NoneType' object has no attribute 'write'

这个问题,您不一定有,因为这和你的应用程序有关,上文我们已经通过添加freeze_support()来解决主程序 GUI 反复重启的问题,但是某些时候,当你用pyinstaller -D -w -y .\test_process.py这种无控制台窗口模式(也就是黑窗口)时,就会出现这个问题:
如下图:
image

推测产生的原因

推测产生的原因是因为,使用-w无控制台窗口模式时,标准输出被重定向了,导致相关函数无法得到正确初始化,于是反应出来就是NoneType

解决办法

方法1:尝试使用--noconsole 代替 --windowed(-w)

此参数是完全禁用控制台窗口,而不是重定向

方法2:手动重定向输出

```python
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
"""
@ Author      : yqbao
@ Version     : V1.0.0
@ Description :
"""

... # 忽略,您自己的应用程序


if __name__ == "__main__":
    sys.stdout = open('output.txt', 'w')  # 手动重定向
    sys.stderr = open('error.txt', 'w')  # 手动重定向
    freeze_support()

    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

本文章的原文地址
GitHub主页

标签:__,Pyinstaller,process,self,PyQt5,sys,进程,multiprocessing
From: https://www.cnblogs.com/yqbaowo/p/18469347

相关文章

  • PyQt5开发环境搭建和配置
    PyQt5工具可以快速实现简单的界面开发,包括界面设计、布局管理以及业务逻辑实现(信号与槽)。简单说就是使用PyQt5工具可以快速画一个控件摆放整齐、界面整洁有序、布局合理的界面。课程目标可以动手实现简单的GUI程序。系列文章主要以动手实践案例讲解为主。课程对象会一些......
  • 【Python开发技术之PyQt5精品教学】第36课--PyQt5 拖放功能
    PyQt5拖放功能拖放功能对用户来说非常直观。它被应用于许多桌面应用程序,用户可以将对象从一个窗口复制或移动到另一个窗口。基于MIME的拖放数据传输是基于QDrag类实现的。QMimeData对象将数据与对应的MIME类型关联起来。数据被存储在剪贴板中,然后在拖放过程中使用。以下QMi......
  • 【Python开发技术之PyQt5精品教学】第32课--PyQt5 QDialog类
    PyQt5QDialog类QDialog 是一个顶层窗口小部件,主要用于收集用户的响应。它可以配置为 模态 (它会阻塞其父窗口)或 非模态 (对话框窗口可以被绕过)。PyQt API有许多预配置的对话框小部件,例如InputDialog,FileDialog,FontDialog等。示例在下面的示例中,对话框窗口的 WindowMo......
  • 【Python开发技术之PyQt5精品教学】第24课--PyQt5 QTab小部件
    PyQt5QTab小部件如果一个表单具有太多字段无法同时显示,则可以将它们安排在选项卡窗口小部件的每个选项卡下的不同页面中。提供了一个选项卡栏和一个页面区域。第一个选项卡下的页面会显示,其他页面会隐藏。用户可以通过点击所需的选项卡来查看任何页面。以下是QTabWidget类的......
  • 【Python开发技术之PyQt5精品教学】第31课--PyQt5 QCalendar小工具
    PyQt5QCalendar小工具QCalendar小工具是一个有用的日期选择器控件。它提供了基于月份的视图。用户可以通过鼠标或键盘选择日期,默认为今天的日期。还可以指定日历的日期范围。以下是这个类的一些实用方法:序号方法和描述1setDateRange() :设置可选择的较低和较高日期。2setFi......
  • PyQt5/6 PySide2/6 在任务栏托盘区域编程,用于显示文字(图片)信息
    PyQt5/6PySide2/6在任务栏编程,用于显示文字(图片)信息本文使用PyQt5演示,其他库如PySide2/6,稍微改改就能用,因为其核心使用的是Win32gui来获取一些系统信息代码结构本文中全部代码全在test_taskbar.py这一个文件中编码,步骤中有变动的地方会注释标注,无改动的不会重复显示出来,需要......
  • 基于YOLO11/v10/v8/v5深度学习的安检X光危险品检测与识别系统设计与实现【python源码+
    《博主简介》小伙伴们好,我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。✌更多学习资源,可关注公-仲-hao:【阿旭算法与机器学习】,共同学习交流~......
  • 如何用PyQt5创建多个窗口,同时获取多个U盘内的文件的名称,并分别在对应窗口打印文件名,要
    在PyQt5中,你可以使用QThread创建多个线程来并行处理每个U盘的文件名获取任务。每个线程负责扫描一个U盘的文件,同时在主窗口显示结果。以下是一个示例代码,用来创建多个窗口,同时在每个窗口中显示各自的U盘文件名:每个窗口使用QWidget。使用QThread创建后台线程获取U......
  • Python 从入门到实战35(进程-multiprocessing模块)
            我们的目标是:通过这一套资料学习下来,可以熟练掌握python基础,然后结合经典实例、实践相结合,使我们完全掌握python,并做到独立完成项目开发的能力。        上篇文章我们讨论了turtle库绘制图画操作的相关知识。今天学习一下进程的概念和创建方法。1、......
  • 深度学习实战人脸表情识别【源码+模型+PyQt5界面】
    @目录研究背景与意义代码下载链接一、效果演示1.1图像识别1.2视频识别1.3摄像头识别二、技术原理2.1整体技术流程2.2常见七种人脸表情2.3传统人脸定位2.4深度学习人脸定位2.4.1MTCNN2.4.2RetinaFace2.4.3CenterFace2.4.4BlazeFace2.4.5YOLO2.4.6SSD2.4.7CascadeCNN......