Python 来自不同组件的QML findChild
目标: 我正在为基于Matplotlib的库编写一个用于嵌套示例的Gui前端(Python 来自不同组件的QML findChild,python,qml,pyside2,Python,Qml,Pyside2,目标: 我正在为基于Matplotlib的库编写一个用于嵌套示例的Gui前端(pip install SORINATE,如果您想查看的话) > >我在C++中的经验是: C++ +/>代码程序,在这里,我不创建QC++来寻找一个画布,而是创建了一个C++对象,注册在QML的类型系统中,并将其作为QtQuy控件控件。据我所知,这是推荐的方法:所有的渲染都在QML中完成,并且所有的业务结束逻辑都在C++中。 最佳方法以及我为什么不能这样做:这种方法在这里不起作用。AfAIK只能使用C++实现自定义
pip install SORINATE
,如果您想查看的话)
<> > >我在C++中的经验是:<代码> C++ +/>代码程序,在这里,我不创建QC++来寻找一个画布,而是创建了一个C++对象,注册在QML的类型系统中,并将其作为QtQuy控件控件。据我所知,这是推荐的方法:所有的渲染都在QML中完成,并且所有的业务结束逻辑都在C++中。
最佳方法以及我为什么不能这样做:这种方法在这里不起作用。AfAIK只能使用C++实现自定义QML,而且我需要程序是纯ISH Python(其他人能够维护它)一些JS是可访问的,QML很容易理解和编辑,所以我没有异议(C++是硬的)。
我得到了什么工作:我有一个我想要的工作实现。都在一个文件里。因此,我自然希望将要绘制的画布拆分为一个单独的文件:figure.qml
。问题是,每当从单独的文件加载对象时,我似乎都找不到该名称的对象(下一步是使用加载程序,因为图
相当笨重)
我有一个两个文件的项目,view.qml
是根目录,在Figure.qml
中有一个组件。
问题是,只有在view.qml
中加载带有objectName:“component”
的东西,而不是在component.qml
中加载时,它才起作用
那么,对于另一个.qml
文件中的objectName,如何在Pyside
中查找child
MWE:
main.py
import sys
from pathlib import Path
from matplotlib_backend_qtquick.backend_qtquickagg import FigureCanvasQtQuickAgg
from matplotlib_backend_qtquick.qt_compat import QtGui, QtQml, QtCore
def main():
app = QtGui.QGuiApplication(sys.argv)
engine = QtQml.QQmlApplicationEngine()
displayBridge = DisplayBridge()
context = engine.rootContext()
qmlFile = Path(Path.cwd(), Path(__file__).parent, "view.qml")
engine.load(QtCore.QUrl.fromLocalFile(str(qmlFile)))
win = engine.rootObjects()[0]
if win.findChild(QtCore.QObject, "figure"):
print('success') # This fails
app.exec_()
查看.qml
import QtQuick.Controls 2.12
import QtQuick.Windows 2.12
ApplicationWindow{
Figure {
}
}
import QtQuick.Controls 2.12
import QtQuick 2.12
Component{
Rectangle{
objectName: "figure"
}
}
import QtQuick.Controls 2.12
import QtQuick 2.12
Rectangle{
objectName: "figure"
}
图.qml
import QtQuick.Controls 2.12
import QtQuick.Windows 2.12
ApplicationWindow{
Figure {
}
}
import QtQuick.Controls 2.12
import QtQuick 2.12
Component{
Rectangle{
objectName: "figure"
}
}
import QtQuick.Controls 2.12
import QtQuick 2.12
Rectangle{
objectName: "figure"
}
用于定义QML元素,它不实例化它,因此您无法访问该对象。创建Figure.qml相当于创建一个组件,您正在另一个组件内创建一个组件
解决方案是不使用组件:
图.qml
import QtQuick.Controls 2.12
import QtQuick.Windows 2.12
ApplicationWindow{
Figure {
}
}
import QtQuick.Controls 2.12
import QtQuick 2.12
Component{
Rectangle{
objectName: "figure"
}
}
import QtQuick.Controls 2.12
import QtQuick 2.12
Rectangle{
objectName: "figure"
}
但不建议使用objectName,因为例如,如果您创建多个组件,您将如何识别它是哪个组件?o如果您在时间T之后创建对象,或者使用Loader或Repeater,您将无法应用该逻辑。与其创建QObject,不如创建一个QObject来获取这些对象:
from PySide2 import QtCore
import shiboken2
class ObjectManager(QtCore.QObject):
def __init__(self, parent=None):
super().__init__(parent)
self._qobjects = []
@property
def qobjects(self):
return self._qobjects
@QtCore.Slot(QtCore.QObject)
def add_qobject(self, obj):
if obj is not None:
obj.destroyed.connect(self._handle_destroyed)
self.qobjects.append(obj)
print(self.qobjects)
def _handle_destroyed(self):
self._qobjects = [o for o in self.qobjects if shiboken2.isValid(o)]
不太清楚你在问什么。什么不起作用-删除
objectName
,嵌套项目,还有什么?已更新。问题是,查找文件后,我得到了一个None
。它实际上迫使我将组件
保留在视图.qml
中,我想知道我是否遗漏了一些语义。首先,值得注意的是,QtQuick不处理“文件”,而是处理排列在树中的qml
项。按名称在该树中查找一个项,在QML中该项是synonim forobjectName
,因此该属性始终是必需的(可能您遗漏了该属性)。另一件您可能会错过的事情是选项
,它应该是Qt::findchildren递归地
。“丢失”子级的另一种方法是间接加载它,即使用Loader或类似的方法。@AlexPetrosyan请提供一个@AlexPetrosyan 1)组件是异步加载的,因此您无法找到它,2)您不应该从python访问QML元素,因为它们只会产生这种不便,3)你可以解释一下你的基本目标(更详细地解释一下,我正试图从QML对画布进行Python端渲染),你有一个XY问题,4)提供一个MRE来帮助你。@AlexPetrosyan,嗯,我不理解你,更好地解释你自己。我没有看到更新的答案。我想知道如何使用加载器,但仍然能够获得画布。。。我很高兴有办法,我也很高兴这不需要我记住名字,让一切都保持在顶级水平。