打开QFileDialog后Qt5应用程序未在QMainWindow.close()上终止

2024-05-14 23:27:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个不太复杂但也不平凡的Qt5 python应用程序(完整的东西在这里:https://gitlab.com/rulrich/pydatagrab但是请参见下面的一个简单示例

我的问题如下:

我有一个QMainWindow,在构造函数中我可以做很多事情,但也可以:

        self.exitAct = QAction("Exit", self, shortcut="Ctrl+Q", triggered=self.close)
        ...
        self.fileMenu = QMenu("File", self)
        self.fileMenu.addAction(self.exitAct)

此外,我在构造函数中调用一个文件对话框

          options = QFileDialog.Options()
          fileName, _ = QFileDialog.getOpenFileName(self, 'QFileDialog.getOpenFileName()', '',
                                                    'Images (*.png *.jpeg *.jpg *.bmp *.gif *.yaml)',
                                                    options=options)

当我按Ctrl+Q或单击文件->;退出会发生同样的情况:GUI消失,没有错误。但这一过程保持活跃,不会终止。在Linux上,当我在shell中启动它时,用Ctrl+C(SIGINT)终止进程甚至不起作用(非常奇怪),我必须用kill(SIGTERM)终止它

我的应用程序中没有任何特殊的“关闭”方法或功能。这是直接的QMainWindow.close()

起初,我100%不清楚从哪里开始寻找问题。然而,在这个问题和回答的帮助下,我发现是QFileDialog本身导致了这种行为。如果我将其取出,应用程序将正常运行

最小复制代码如下所示:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import sys, os

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

class MainWindow(QMainWindow):

     def __init__(self, fileName=None):
         
          super().__init__()

          self.exitAct = QAction("Exit", self, shortcut="Ctrl+Q", triggered=self.close)
          self.fileMenu = QMenu("File", self)
          self.fileMenu.addAction(self.exitAct)
          self.menuBar().addMenu(self.fileMenu)

          self.openFile()

    
     def openFile(self):
          options = QFileDialog.Options()
          fileName, _ = QFileDialog.getOpenFileName(self, 'QFileDialog.getOpenFileName()', '',
                                                    'Images (*.png *.jpeg *.jpg *.bmp *.gif *.yaml)',
                                                    options=options)
          # load some data ...
          # ...
                        

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

=====================================================================

print(app.allWidgets())的输出(修复问题后):

[<PyQt5.QtWidgets.QMenu object at 0x7fb8e6ae49d0>, <PyQt5.QtWidgets.QScrollBar object at 0x7fb8e6ae4b80>, <PyQt5.QtWidgets.QWidget object at 0x7fb8e6ae4c10>, <PyQt5.QtWidgets.QMenu object at 0x7fb8e6ae4ca0>, <PyQt5.QtWidgets.QWidget object at 0x7fb8e6ae4d30>, <PyQt5.QtWidgets.QPushButton object at 0x7fb8e6ae4160>, <PyQt5.QtWidgets.QScrollBar object at 0x7fb8e6ae4dc0>, <PyQt5.QtWidgets.QLineEdit object at 0x7fb8ee6ea790>, <PyQt5.QtWidgets.QMenu object at 0x7fb8e6ae4790>, <PyQt5.QtWidgets.QLineEdit object at 0x7fb8ee6eae50>, <PyQt5.QtWidgets.QFrame object at 0x7fb8e6ae4e50>, <PyQt5.QtWidgets.QScrollArea object at 0x7fb8ee6ea5e0>, <PyQt5.QtWidgets.QLabel object at 0x7fb8ee6ea670>, <PyQt5.QtWidgets.QLabel object at 0x7fb8e6ae40d0>, <PyQt5.QtWidgets.QToolButton object at 0x7fb8e6ae4ee0>, <PyQt5.QtWidgets.QWidget object at 0x7fb8e6ae4f70>, <PyQt5.QtWidgets.QLineEdit object at 0x7fb8ee6eac10>, <PyQt5.QtWidgets.QFrame object at 0x7fb8e6af5040>, <PyQt5.QtWidgets.QScrollBar object at 0x7fb8e6af50d0>, <PyQt5.QtWidgets.QWidget object at 0x7fb8e6af5160>, <PyQt5.QtWidgets.QLineEdit object at 0x7fb8ee6ea9d0>, <PyQt5.QtWidgets.QWidget object at 0x7fb8e6ae4af0>, <__main__.MainWindow object at 0x7fb8ee6ea160>, <PyQt5.QtWidgets.QLabel object at 0x7fb8e6ae4040>, <PyQt5.QtWidgets.QComboBox object at 0x7fb8ee6ea430>, <PyQt5.QtWidgets.QFrame object at 0x7fb8e6af51f0>, <PyQt5.QtWidgets.QListView object at 0x7fb8e6af5280>, <PyQt5.QtWidgets.QScrollBar object at 0x7fb8e6af5310>, <PyQt5.QtWidgets.QWidget object at 0x7fb8e6af53a0>, <__main__.DataArea object at 0x7fb8ee6ea550>, <PyQt5.QtWidgets.QScrollBar object at 0x7fb8e6af5430>, <PyQt5.QtWidgets.QWidget object at 0x7fb8e6af54c0>, <PyQt5.QtWidgets.QWidget object at 0x7fb8e6af5550>, <PyQt5.QtWidgets.QWidget object at 0x7fb8e6af55e0>, <PyQt5.QtWidgets.QScrollBar object at 0x7fb8e6af5670>, <PyQt5.QtWidgets.QMenuBar object at 0x7fb8e6ae4a60>, <PyQt5.QtWidgets.QLabel object at 0x7fb8ee6eadc0>, <PyQt5.QtWidgets.QWidget object at 0x7fb8e6af5700>, <PyQt5.QtWidgets.QFrame object at 0x7fb8e6af5790>, <PyQt5.QtWidgets.QListView object at 0x7fb8e6af5820>, <PyQt5.QtWidgets.QComboBox object at 0x7fb8ee6eab80>, <PyQt5.QtWidgets.QWidget object at 0x7fb8e6af58b0>, <PyQt5.QtWidgets.QListView object at 0x7fb8e6af5940>, <PyQt5.QtWidgets.QWidget object at 0x7fb8e6af59d0>, <PyQt5.QtWidgets.QLabel object at 0x7fb8ee6eaaf0>, <PyQt5.QtWidgets.QWidget object at 0x7fb8e6af5a60>, <PyQt5.QtWidgets.QComboBox object at 0x7fb8ee6ea4c0>, <PyQt5.QtWidgets.QScrollBar object at 0x7fb8e6af5af0>, <PyQt5.QtWidgets.QScrollBar object at 0x7fb8e6af5b80>, <PyQt5.QtWidgets.QWidget object at 0x7fb8e6af5c10>, <PyQt5.QtWidgets.QWidget object at 0x7fb8e6af5ca0>, <PyQt5.QtWidgets.QWidget object at 0x7fb8e6af5d30>, <PyQt5.QtWidgets.QLabel object at 0x7fb8ee6eaca0>, <PyQt5.QtWidgets.QWidget object at 0x7fb8e6af5dc0>, <PyQt5.QtWidgets.QLabel object at 0x7fb8ee6ea820>, <PyQt5.QtWidgets.QLabel object at 0x7fb8ee6ea940>, <PyQt5.QtWidgets.QScrollBar object at 0x7fb8e6af5e50>, <PyQt5.QtWidgets.QScrollBar object at 0x7fb8e6af5ee0>, <PyQt5.QtWidgets.QComboBox object at 0x7fb8ee6ea700>, <PyQt5.QtWidgets.QListView object at 0x7fb8e6af5f70>, <PyQt5.QtWidgets.QWidget object at 0x7fb8e6ae41f0>, <PyQt5.QtWidgets.QWidget object at 0x7fb8e6afc040>, <PyQt5.QtWidgets.QMenu object at 0x7fb8e6ae48b0>]

进一步简化MRE:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import sys, os

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

class MainWindow(QMainWindow):

     def __init__(self, fileName=None):         
          super().__init__()
          key = QShortcut(QKeySequence("Ctrl+Q"), self)
          key.activated.connect(self.close)
          self.openFile()

    
     def openFile(self):
          fileName, _ = QFileDialog.getOpenFileName(self, 'QFileDialog.getOpenFileName()', '',
                                                    'Images (*.png *.jpeg *.jpg *.bmp *.gif *.yaml)')#)
          #,options=QFileDialog.DontUseNativeDialog)
                        

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

->;行为没有改变


Tags: fromimportselfobjectsyspyqt5atoptions
1条回答
网友
1楼 · 发布于 2024-05-14 23:27:07

似乎这个问题可能与QTBUG-59184有关,它会影响Qt5打开的本机GTK文件对话框。这个bug仍然没有解决,并且具有关键的优先级,所以希望它能够很快得到修复。同时,解决方法是使用内置的Qt文件对话框,该对话框可以通过options指定,如下所示:

QFileDialog.getOpenFileName(parent, caption, options=QFileDialog.DontUseNativeDialog)

或者像这样:

dialog = QFileDialog(parent, caption)
dialog.setOption(QFileDialog.DontUseNativeDialog, True)

相关问题 更多 >

    热门问题