Python 如何从PySide访问QML\QtQuick控件?
我试图从python文件访问FileDialog控件,该文件启动QQmlApplication引擎以检索文件路径属性。我已经在.qml文件中设置了一个信号,但是我无法通过python文件中的id访问文件对话框来设置插槽。application.py中的findChild方法返回None。代码如下: application.pyPython 如何从PySide访问QML\QtQuick控件?,python,qml,pyside2,Python,Qml,Pyside2,我试图从python文件访问FileDialog控件,该文件启动QQmlApplication引擎以检索文件路径属性。我已经在.qml文件中设置了一个信号,但是我无法通过python文件中的id访问文件对话框来设置插槽。application.py中的findChild方法返回None。代码如下: application.py import sys from PySide2.QtGui import QGuiApplication from PySide2.QtQml import QQmlAp
import sys
from PySide2.QtGui import QGuiApplication
from PySide2.QtQml import QQmlApplicationEngine, QQmlFileSelector
sys_argv = sys.argv
sys_argv += ['--style', 'material']
app = QGuiApplication(sys_argv)
window = QQmlApplicationEngine()
window.load("QML/main.qml")
fileDialog = window.findChild(QQmlFileSelector, "fileDialog")
print(fileDialog)
app.exec_()
第1.qml页
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Dialogs 1.2
Page {
width: 600
height: 400
header: Label {
text: qsTr("Prepare Data")
horizontalAlignment: Text.AlignHCenter
font.pixelSize: Qt.application.font.pixelSize * 2
padding: 10
}
Button {
text: qsTr("Load data")
anchors.centerIn: parent
onClicked: fileDialog.visible = true
padding: 10
}
signal folderSelected()
FileDialog {
id: fileDialog
selectFolder: true
title: qsTr("Select the data directory")
folder: shortcuts.home
onAccepted: {
parent.folderSelected()
}
}
}
main.qml
import QtQuick 2.0
import QtQuick.Controls 2.12
import QtQuick.Controls.Material 2.12
ApplicationWindow{
visible: true
title: qsTr("Main window")
width: 1000
height: 800
Material.theme: Material.Light
Material.accent: Material.Orange
SwipeView {
id: swipeView
anchors.fill: parent
Page1 {
}
Page2 {
}
Page3 {
}
}
}
在推动对QML的引用如何从QML更新某些python对象一节中的解释中,该方法是Qt推荐的方法,也是现在应该使用的方法。使用当前的方法,您需要建立一个在许多情况下可能有问题的objectname
所以解决方案是创建一个QObject,我们导出到QML并更新qproperty,这将发出一个信号,我们连接到一个插槽,在那里我们可以执行我们想要的逻辑。另一方面,FileDialog返回url,因此属性必须是QUrl:
main.qml
import os
import sys
from PySide2 import QtCore, QtGui, QtQml
class FileManager(QtCore.QObject):
file_url_Changed = QtCore.Signal(QtCore.QUrl)
def __init__(self, parent=None):
super(FileManager, self).__init__(parent)
self._file_url = QtCore.QUrl()
def get_file_url(self):
return self._file_url
def set_file_url(self, file_url):
if self._file_url != file_url:
self._file_url = file_url
self.file_url_Changed.emit(self._file_url)
file_url = QtCore.Property(QtCore.QUrl, fget=get_file_url, fset=set_file_url, notify=file_url_Changed)
@QtCore.Slot(QtCore.QUrl)
def on_file_url_changed(file_url):
print(file_url.toLocalFile())
if __name__ == '__main__':
sys.argv += ['--style', 'material']
app = QtGui.QGuiApplication(sys.argv)
file_manager = FileManager()
file_manager.file_url_Changed.connect(on_file_url_changed)
engine = QtQml.QQmlApplicationEngine()
engine.rootContext().setContextProperty("file_manager", file_manager)
file = os.path.join(os.path.dirname(os.path.realpath(__file__)), "QML", "main.qml")
engine.load(QtCore.QUrl.fromLocalFile(file))
if not engine.rootObjects():
sys.exit(-1)
sys.exit(app.exec_())
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Dialogs 1.2
Page {
width: 600
height: 400
header: Label {
text: qsTr("Prepare Data")
horizontalAlignment: Text.AlignHCenter
font.pixelSize: Qt.application.font.pixelSize * 2
padding: 10
}
Button {
text: qsTr("Load data")
anchors.centerIn: parent
onClicked: fileDialog.visible = true
padding: 10
}
FileDialog {
id: fileDialog
selectFolder: true
title: qsTr("Select the data directory")
folder: shortcuts.home
onAccepted: {
file_manager.file_url = fileDialog.fileUrl // <---
}
}
}
Page1.qml
import os
import sys
from PySide2 import QtCore, QtGui, QtQml
class FileManager(QtCore.QObject):
file_url_Changed = QtCore.Signal(QtCore.QUrl)
def __init__(self, parent=None):
super(FileManager, self).__init__(parent)
self._file_url = QtCore.QUrl()
def get_file_url(self):
return self._file_url
def set_file_url(self, file_url):
if self._file_url != file_url:
self._file_url = file_url
self.file_url_Changed.emit(self._file_url)
file_url = QtCore.Property(QtCore.QUrl, fget=get_file_url, fset=set_file_url, notify=file_url_Changed)
@QtCore.Slot(QtCore.QUrl)
def on_file_url_changed(file_url):
print(file_url.toLocalFile())
if __name__ == '__main__':
sys.argv += ['--style', 'material']
app = QtGui.QGuiApplication(sys.argv)
file_manager = FileManager()
file_manager.file_url_Changed.connect(on_file_url_changed)
engine = QtQml.QQmlApplicationEngine()
engine.rootContext().setContextProperty("file_manager", file_manager)
file = os.path.join(os.path.dirname(os.path.realpath(__file__)), "QML", "main.qml")
engine.load(QtCore.QUrl.fromLocalFile(file))
if not engine.rootObjects():
sys.exit(-1)
sys.exit(app.exec_())
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Dialogs 1.2
Page {
width: 600
height: 400
header: Label {
text: qsTr("Prepare Data")
horizontalAlignment: Text.AlignHCenter
font.pixelSize: Qt.application.font.pixelSize * 2
padding: 10
}
Button {
text: qsTr("Load data")
anchors.centerIn: parent
onClicked: fileDialog.visible = true
padding: 10
}
FileDialog {
id: fileDialog
selectFolder: true
title: qsTr("Select the data directory")
folder: shortcuts.home
onAccepted: {
file_manager.file_url = fileDialog.fileUrl // <---
}
}
}
导入QtQuick 2.9
导入QtQuick.Controls 2.2
导入QtQuick.Dialogs 1.2
页面{
宽度:600
身高:400
标题:标签{
文本:qsTr(“准备数据”)
水平对齐:Text.AlignHCenter
font.pixelSize:Qt.application.font.pixelSize*2
填充:10
}
钮扣{
文本:qsTr(“加载数据”)
anchors.centerIn:父对象
onClicked:fileDialog.visible=true
填充:10
}
文件对话框{
id:fileDialog
selectFolder:true
标题:qsTr(“选择数据目录”)
文件夹:shortcuts.home
不接受:{
file\u manager.file\u url=fileDialog.fileUrl//谢谢,效果很好!但是,例如,如何将其转换为整个表单?是否必须创建一个新的QObject,然后将其设置为表单中每个组件的上下文属性?@dkalev否,FileManager可以有其他QProperty,因此您只能使用单个对象