【发布时间】:2020-10-13 05:39:26
【问题描述】:
我在 QML 中的 ApplicationWindow 中定义了一个按钮(实际上是一个 MouseArea)。我设法从 PyQt5 连接到它的点击事件。现在我正在尝试显示保存文件对话框,但出现错误:
QWidget: Cannot create a QWidget without QApplication
我的代码如下所示:
from PyQt5.QtCore import QUrl, QObject # pylint: disable-msg=E0611
from PyQt5.QtGui import QGuiApplication, QIcon # pylint: disable-msg=E0611
from PyQt5.QtQml import QQmlApplicationEngine # pylint: disable-msg=E0611
from PyQt5.QtWidgets import QFileDialog # pylint: disable-msg=E0611
def openFile():
options = QFileDialog.Options()
options |= QFileDialog.DontUseNativeDialog
filename = QFileDialog.getOpenFileName(None,"QFileDialog.getOpenFileName()", "","All Files (*);;Python Files (*.py)", options=options)
print(filename)
def run():
app = QGuiApplication(sys.argv)
app.setWindowIcon(QIcon(resource_path("assets\\images\\icon.ico")))
engine = QQmlApplicationEngine()
engine.load(resource_path("qml\\Window.qml"))
engine.quit.connect(app.quit)
if not engine.rootObjects():
return -1
button = engine.rootObjects()[0].findChild(QObject, "openButton")
button.clicked.connect(openFile)
return app.exec_()
if __name__ == '__main__':
sys.exit(run())
我也尝试传递 ApplicationWindow 而不是 None,但随后出现类型错误:
TypeError: getOpenFileName(parent: QWidget = None, caption: str = '', directory: str = '', filter: str = '', initialFilter: str = '', options: Union[QFileDialog.Options, QFileDialog.Option] = 0): argument 1 has unexpected type 'QWindow'
在我看来这没有多大意义,因为QMainWindow 继承了QWidget。
如何显示来自openFile() 函数的对话框?
编辑:为了完整起见,这里是我的 .qml 文件的精简版
import QtQuick.Window 2.2
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.3
import QtQuick 2.3
ApplicationWindow {
id: mainWindow
visible: true
width: 600
height: 400
Item {
anchors.top: titleBar.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
property bool isMainButtonFocused: false
objectName: "openButton"
signal clicked()
Label {
padding: 5
text: "<b><font color='#fefefe'>Hello World</font></b>"
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
font.family: "Helvetica"
font.pointSize: 9
background: Rectangle {
color: mouseAreaOpenFolderButton.containsMouse ? "#777777" : "#333333"
border.width: isMainButtonFocused ? 2 : 1
border.color: "#ffffff"
radius: 5
}
MouseArea {
id: mouseAreaOpenFolderButton
anchors.fill: parent
hoverEnabled: true
onClicked: {
isMainButtonFocused = true
parent.parent.clicked()
}
}
}
}
}
【问题讨论】:
-
首先,将 QML 应用程序逻辑从 QML 中移出是一个非常糟糕的主意。一个更糟糕的想法是混合使用 QtQuick 和 QWidgets。你为什么不改用FileDialog?至于问题——错误很明显——你必须使用
QApplication而不是QGuiApplication。有关更多信息,请参阅this 讨论。 -
好吧,我不想使用 FileDialog,因为我想在 Python 中检索结果,因为我需要从那里读出它。但是我得出的结论是,这将是最简单的方法...