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

PyInstaller打包Tkinter多进程程序时弹出重复主窗口而非Ping窗口

带颜色标识的Ping应用打包后进程异常问题
  • 开发的Ping应用具备颜色标识功能:Ping响应失败时窗口显示红色,成功则显示绿色
  • 程序分为两个文件:
    • main_window.py:主窗口代码,包含URL输入框、Ping参数输入框和启动按钮
    • ping_window.py:Ping窗口代码,负责执行Ping逻辑并更新窗口颜色
  • 运行逻辑:点击主窗口的启动按钮,会创建继承自multiprocessing.Process的NewProcessPingWindow实例,其run()方法启动独立Ping窗口;Ping逻辑放在线程中执行,避免UI冻结
  • 异常现象:在PyCharm中运行正常,但使用pyinstaller --onefile main_window.py打包成exe后,点击按钮无法打开Ping窗口,反而生成主窗口副本,原窗口冻结,问题可重复触发
  • 已尝试的排查:添加了if __name__ == '__main__':语句,在Stack Overflow搜索相关问题,排查两天未解决

主窗口代码(main_window.py)

import sys
import multiprocessing
from PyQt5.QtWidgets import (QApplication, QWidget, QLineEdit, QPushButton, QVBoxLayout, QLabel)
from ping_window import PingWindow

class NewProcessPingWindow(multiprocessing.Process):
    def __init__(self, url, ping_args):
        super().__init__()
        self.url = url
        self.ping_args = ping_args

    def run(self):
        app = QApplication(sys.argv)
        window = PingWindow(self.url, self.ping_args)
        window.show()
        sys.exit(app.exec_())

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

    def initUI(self):
        self.setWindowTitle('Ping Launcher')
        self.setGeometry(100, 100, 300, 150)

        layout = QVBoxLayout()

        self.url_label = QLabel('目标URL/IP:')
        self.url_input = QLineEdit()
        self.url_input.setText('google.com')

        self.ping_args_label = QLabel('Ping参数(如 -n 4):')
        self.ping_args_input = QLineEdit()
        self.ping_args_input.setText('-n 4')

        self.launch_btn = QPushButton('启动Ping窗口')
        self.launch_btn.clicked.connect(self.launch_ping_window)

        layout.addWidget(self.url_label)
        layout.addWidget(self.url_input)
        layout.addWidget(self.ping_args_label)
        layout.addWidget(self.ping_args_input)
        layout.addWidget(self.launch_btn)

        self.setLayout(layout)

    def launch_ping_window(self):
        url = self.url_input.text()
        ping_args = self.ping_args_input.text()
        ping_process = NewProcessPingWindow(url, ping_args)
        ping_process.start()

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

Ping窗口代码(ping_window.py)

import sys
import subprocess
import threading
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel
from PyQt5.QtGui import QPalette, QColor

class PingWindow(QWidget):
    def __init__(self, url, ping_args):
        super().__init__()
        self.url = url
        self.ping_args = ping_args
        self.initUI()
        self.start_ping_thread()

    def initUI(self):
        self.setWindowTitle(f'Ping {self.url}')
        self.setGeometry(200, 200, 300, 100)
        self.layout = QVBoxLayout()
        self.status_label = QLabel(f'正在Ping {self.url}...')
        self.layout.addWidget(self.status_label)
        self.setLayout(self.layout)

    def set_window_color(self, is_success):
        palette = self.palette()
        if is_success:
            palette.setColor(QPalette.Window, QColor(0, 255, 0, 50))
        else:
            palette.setColor(QPalette.Window, QColor(255, 0, 0, 50))
        self.setPalette(palette)

    def ping_target(self):
        while True:
            try:
                # Windows系统的ping命令,Linux/macOS需要换成-c参数
                result = subprocess.run(
                    ['ping'] + self.ping_args.split() + [self.url],
                    stdout=subprocess.PIPE,
                    stderr=subprocess.PIPE,
                    text=True,
                    timeout=10
                )
                success = result.returncode == 0
                self.status_label.setText(f'Ping {self.url} {"成功" if success else "失败"}')
                self.set_window_color(success)
            except subprocess.TimeoutExpired:
                self.status_label.setText(f'Ping {self.url} 超时')
                self.set_window_color(False)
            except Exception as e:
                self.status_label.setText(f'Ping错误: {str(e)}')
                self.set_window_color(False)

    def start_ping_thread(self):
        ping_thread = threading.Thread(target=self.ping_target, daemon=True)
        ping_thread.start()

if __name__ == '__main__':
    from PyQt5.QtWidgets import QApplication
    app = QApplication(sys.argv)
    window = PingWindow('google.com', '-n 4')
    window.show()
    sys.exit(app.exec_())

内容的提问来源于stack exchange,提问作者MIku

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 00:55:08