gpt4 book ai didi

python - 从连接到 QML 的 PyQt5 打开文件对话框

转载 作者:行者123 更新时间:2023-12-04 09:36:56 30 4
gpt4 key购买 nike

我在 MouseArea 中的 QML 中定义了一个按钮(实际上它是一个 ApplicationWindow ) .我设法从 PyQt5 连接到它的 clicked 事件。现在我试图显示一个保存文件对话框,但出现错误:

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()
}
}
}
}
}

最佳答案

错误非常明显:

  • 如果你打算使用像 QFileDialog 这样的 QWidget,那么你必须创建一个 QApplication。
  • 如果您要向父级传递 QWidget,就像 QFileDialog 一样,那么该父级必须是另一个 QWidget,但 ApplicationWindow 不是 QWidget,而是导致该错误的 QWindow。

  • 另一个额外但更重要的错误是你不应该从 Python(或 C++)访问 QML 对象,因为它的生命周期是不同的,所以它可能会出现问题(例如,参见 this answer),而是创建一个 QObject 来实现逻辑和将其公开为项目(使用 qmlRegisterType)或上下文属性(通过 setContextProperty)。
    考虑到上述情况,您应该使用 FileDialog 并将 QObject 作为上下文属性公开:
    # ...
    class Helper(QObject):
    @pyqtSlot(QUrl)
    def read_file(self, url):
    filename = url.toLocalFile()
    print(filename)


    def run():
    app = QGuiApplication(sys.argv)
    app.setWindowIcon(QIcon(resource_path("assets\\images\\icon.ico")))

    engine = QQmlApplicationEngine()
    helper = Helper()
    engine.rootContext().setContextProperty("helper", helper)
    # ...
    import QtQuick.Window 2.2
    import QtQuick.Controls 2.3
    import QtQuick.Layouts 1.3
    import QtQuick 2.3
    import QtQuick.Dialogs 1.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

    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
    fileDialog.visible = true

    }
    }
    }
    }
    FileDialog {
    id: fileDialog
    title: "Please choose a file"
    selectedNameFilter: "All Files (*);;Python Files (*.py)"
    onAccepted: {
    helper.read_file(fileDialog.fileUrls[0])
    }
    }
    }

    关于python - 从连接到 QML 的 PyQt5 打开文件对话框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62530031/

    30 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com