pyqt5 + pywinauto 调用getOpenFileName卡死(闪退)问题

最近在一个项目中遇到pyqt5界面调用getOpenFileName后卡死闪退,以下是一些记录。

运行环境

python 3.10

pyqt5 5.15.11

pywinauto 0.6.9

项目介绍

项目中实现界面按钮选择本地软件,然后使用pywinauto库连接该软件,并获取该软件界面信息。

代码实现

1. ui文件转换后的py文件代码,界面中仅包含一个按钮

from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(623, 468)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setObjectName("pushButton")
        self.gridLayout.addWidget(self.pushButton, 0, 0, 1, 1)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 623, 23))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton.setText(_translate("MainWindow", "PushButton"))

2. 连接软件线程

from PyQt5.QtCore import QThread, pyqtSignal

import pywinauto


class ConnectExeLogic(QThread):
    exe_status = pyqtSignal(bool)

    def __init__(self):
        super(ConnectExeLogic, self).__init__()
        self.exe_path = ''  # 软件路径
        self.exe_window = None

    def run(self):
        print(self.exe_path)
        try:
            self.exe_window = pywinauto.application.Application().connect(path=self.exe_path)
        except pywinauto.application.ProcessNotFoundError:
            self.exe_status.emit(False)
        else:
            self.exe_status.emit(True)

2. 界面初始化

from UI.test import Ui_MainWindow
from Logic.ConnectExe import ConnectExeLogic

from PyQt5 import QtWidgets


class WindowMarkAssis(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(WindowMarkAssis, self).__init__(parent)
        self.setupUi(self)
        self.logic_connect_exe = ConnectExeLogic()
        self.pushButton.clicked.connect(lambda: self.start_connect_exe())

    def start_connect_exe(self):
        exe_path = QtWidgets.QFileDialog.getOpenFileName(self, '选择软件', '', 'Exe (*.exe)')[0]
        if exe_path == '':
            self.statusbar.showMessage('未选择软件', 3000)
            return False
        self.logic_connect_exe.exe_path = exe_path
        self.logic_connect_exe.start()

问题描述

运行上述代码,通过点击按钮选择软件,界面会卡死然后闪退。

问题分析

在界面初始化文件中,导入了ConnectExeLogic类,在该类的文件中导入了pywinauto库。所以界面初始化完成就导入了pywinauto库,再点击按钮调用getOpenFileName则会导致界面卡死闪退。

问题解决

思路:在调用getOpenFileName后再导入pywinauto库连接软件

代码修改:在选择完软件后启动的连接线程中导入pywinauto库

from PyQt5.QtCore import QThread, pyqtSignal


class ConnectExeLogic(QThread):
    exe_status = pyqtSignal(bool)

    def __init__(self):
        super(ConnectExeLogic, self).__init__()
        self.exe_path = ''  # 分析软件路径
        self.exe_window = None

    def run(self):
        print(self.exe_path)
        import pywinauto
        try:
            self.exe_window = pywinauto.application.Application().connect(path=self.exe_path)
        except pywinauto.application.ProcessNotFoundError:
            self.exe_status.emit(False)
        else:
            self.exe_status.emit(True)

经过如上修改后的项目代码,可实现项目要求,解决了界面卡死闪退问题。

进一步查看pywinauto库的源代码,发现界面卡死与库中几行代码相关,感兴趣的可以自行测试。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值