我正在尝试编写一个执行以下操作的PyQt5应用程序:
我的问题是我没有找到一种方法让QfileDialog自动打开(2),当主窗口关闭时不会导致应用程序挂起。代码的基本示例可以在下面找到:
import sys
from PyQt5.QtWidgets import (QApplication, QMainWindow, QMenuBar, QWidget,
QHBoxLayout, QCalendarWidget, QScrollArea, QFileDialog, QAction, QFrame)
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import Qt
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.openAction = QAction(QIcon('/usr/share/icons/breeze/places/64/folder-open.svg'), 'Open', self)
self.openAction.triggered.connect(self.openDialog)
self.menubar = QMenuBar(self)
fileMenu = self.menubar.addMenu('&File')
fileMenu.addAction(self.openAction)
self.event_widgets = EventWidgets(self)
self.setMenuBar(self.menubar)
self.setCentralWidget(self.event_widgets)
def openDialog(self):
ics_path = QFileDialog.getOpenFileName(self, 'Open file', '/home/michael/')
class EventWidgets(QWidget):
def __init__(self, parent):
super(EventWidgets, self).__init__(parent)
self.initUI()
def initUI(self):
self.calendar = QCalendarWidget(self)
self.frame = QFrame()
self.scrollArea = QScrollArea()
self.scrollArea.setWidget(self.frame)
horizontal_box = QHBoxLayout()
horizontal_box.addWidget(self.calendar)
horizontal_box.addWidget(self.scrollArea)
self.setLayout(horizontal_box)
if __name__ == '__main__':
app = QApplication(sys.argv)
app_window = MainWindow()
app_window.showMaximized()
app_window.openDialog()
sys.exit(app.exec_())
代码已经在KDE Neon和Arch Linux上测试过,两者都有同样的问题。
我可以通过手动处理主窗口的关闭事件来解决这个问题 - 即将此功能添加到MainWindow:
def closeEvent(self, event):
sys.exit()
但我不确定a)为什么这是必要的b)如果这是最佳实践。
答案 0 :(得分:1)
我在macOS Sierra上尝试了你的代码,它可以正常工作。不过,我会提出一种不同的方法来解决你的问题。
您可以做的是在showEvent()
类中实现MainWindow
函数,该函数在窗口小部件显示时执行(使用.show()
或.showMaximized()
)和触发您的自定义广告位以打开QFileDialog
。执行此操作时,您可以使用单次计时器以最小延迟触发插槽:这背后的原因是,如果您只是在showEvent()
内打开对话框,您将看到对话框窗口但不是它下方的MainWindow
(因为QFileDialog
阻止了UI,直到用户执行某些操作)。单发计时器为QFileDialog
的开启添加了一些延迟,并允许MainWindow
在模态对话框后面呈现。这是一个可能的解决方案(不是我对您的代码进行了一些小的更改,您应该能够轻松获取):
import sys
from PyQt5 import QtCore
from PyQt5 import QtWidgets
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.openAction = QtWidgets.QAction('Open', self)
self.openAction.triggered.connect(self.openDialog)
menuBar = self.menuBar()
fileMenu = menuBar.addMenu('&File')
fileMenu.addAction(self.openAction)
self.event_widgets = EventWidgets(self)
self.setCentralWidget(self.event_widgets)
def showEvent(self, showEvent):
QtCore.QTimer.singleShot(50, self.openDialog)
@QtCore.pyqtSlot()
def openDialog(self):
ics_path = QtWidgets.QFileDialog.getOpenFileName(self, 'Open file', '/Users/daniele/')
class EventWidgets(QtWidgets.QWidget):
def __init__(self, parent):
super(EventWidgets, self).__init__(parent)
self.calendar = QtWidgets.QCalendarWidget(self)
self.frame = QtWidgets.QFrame()
self.scrollArea = QtWidgets.QScrollArea()
self.scrollArea.setWidget(self.frame)
horizontal_box = QtWidgets.QHBoxLayout()
horizontal_box.addWidget(self.calendar)
horizontal_box.addWidget(self.scrollArea)
self.setLayout(horizontal_box)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
app_window = MainWindow()
app_window.showMaximized()
sys.exit(app.exec_())