栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何从Python文件更新Qml对象的属性?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何从Python文件更新Qml对象的属性?

有几种方法可以从python / C ++修改QML元素的属性,每种方法都有其优点和缺点。

1.从QML中提取引用

  • 通过findChildren通过另一个对象获取QML对象。
  • 修改或访问属性与
    setProperty()
    property()
    分别或QQmlProperty。

main.qmlqml 用于接下来的2个.py)

import QtQuick 2.11import QtQuick.Window 2.2import QtQuick.Controls 2.2ApplicationWindow {        visible: true    width: Screen.width/2    height: Screen.height/2    Rectangle {        id: rectangle        x: 187        y: 92        width: 200        height: 200        color: "blue"        objectName: "foo_object"    }}

1.1 setProperty(),property()。

import osimport sysfrom PyQt5 import QtCore, QtGui, QtQmlfrom functools import partialdef testing(r):    import random    w = r.property("width")    h = r.property("height")    print("width: {}, height: {}".format(w, h))    r.setProperty("width", random.randint(100, 400))    r.setProperty("height", random.randint(100, 400))def run():    myApp = QtGui.QGuiApplication(sys.argv)    myEngine = QtQml.QQmlApplicationEngine()    directory = os.path.dirname(os.path.abspath(__file__))    myEngine.load(QtCore.QUrl.fromLocalFile(os.path.join(directory, 'main.qml')))    if not myEngine.rootObjects():        return -1    r = myEngine.rootObjects()[0].findChild(QtCore.QObject, "foo_object")    timer = QtCore.QTimer(interval=500)    timer.timeout.connect(partial(testing, r))    timer.start()    return myApp.exec_()if __name__ == "__main__":    sys.exit(run())

1.2 QQmlProperty。

import osimport sysfrom PyQt5 import QtCore, QtGui, QtQmlfrom functools import partialdef testing(r):    import random    w_prop = QtQml.QQmlProperty(r, "width")    h_prop = QtQml.QQmlProperty(r, "height")    print("width: {}, height: {}".format(w_prop.read(), w_prop.read()))    w_prop.write(random.randint(100, 400))    h_prop.write(random.randint(100, 400))def run():    myApp = QtGui.QGuiApplication(sys.argv)    myEngine = QtQml.QQmlApplicationEngine()    directory = os.path.dirname(os.path.abspath(__file__))    myEngine.load(QtCore.QUrl.fromLocalFile(os.path.join(directory, 'main.qml')))    if not myEngine.rootObjects():        return -1    r = myEngine.rootObjects()[0].findChild(QtCore.QObject, "foo_object")    timer = QtCore.QTimer(interval=500)    timer.timeout.connect(partial(testing, r))    timer.start()    return myApp.exec_()if __name__ == "__main__":    sys.exit(run())

此方法的缺点是,如果对象与根对象的关系很复杂(有时其他QML中的对象很难用findChild访问),则访问对象的过程将变得很复杂,有时甚至是不可能的,因此该方法将失败。另一个问题是,当使用objectName作为主要搜索数据时,Python层对QML层的依赖性很高,因为如果在QML中修改了ObjectName,则必须修改python中的逻辑。另一个缺点是,通过不管理QML对象的生命周期,可以在没有Python知道的情况下将其消除,因此它将访问错误的引用,从而导致应用程序意外终止。

2.推送对QML的引用

  • 创建具有相同类型的属性的QObject。
  • 使用setContextProperty导出到QML。
  • 在QObject的属性和项目的属性之间进行绑定。

main.qml

import QtQuick 2.11import QtQuick.Window 2.2import QtQuick.Controls 2.2ApplicationWindow {        visible: true    width: Screen.width/2    height: Screen.height/2    Rectangle {        id: rectangle        x: 187        y: 92        width: r_manager.width        height: r_manager.height        color: "blue"    }}

main.py

import osimport sysfrom PyQt5 import QtCore, QtGui, QtQmlfrom functools import partialclass RectangleManager(QtCore.QObject):    widthChanged = QtCore.pyqtSignal(float)    heightChanged = QtCore.pyqtSignal(float)    def __init__(self, parent=None):        super(RectangleManager, self).__init__(parent)        self._width = 100        self._height = 100    @QtCore.pyqtProperty(float, notify=widthChanged)    def width(self):        return self._width    @width.setter    def width(self, w):        if self._width != w: self._width = w self.widthChanged.emit(w)    @QtCore.pyqtProperty(float, notify=heightChanged)    def height(self):        return self._height    @height.setter    def height(self, h):        if self._height != h: self._height = h self.heightChanged.emit(h)def testing(r):    import random    print("width: {}, height: {}".format(r.width, r.height))    r.width = random.randint(100, 400)    r.height = random.randint(100, 400)def run():    myApp = QtGui.QGuiApplication(sys.argv)    myEngine = QtQml.QQmlApplicationEngine()    manager = RectangleManager()    myEngine.rootContext().setContextProperty("r_manager", manager)    directory = os.path.dirname(os.path.abspath(__file__))    myEngine.load(QtCore.QUrl.fromLocalFile(os.path.join(directory, 'main.qml')))    if not myEngine.rootObjects():        return -1    timer = QtCore.QTimer(interval=500)    timer.timeout.connect(partial(testing, manager))    timer.start()    return myApp.exec_()if __name__ == "__main__":    sys.exit(run())

缺点是您必须编写更多代码。优点是,由于该对象使用setContextProperty,因此所有QML都可以访问该对象;另一个优点是,如果删除了QML对象,则不会产生问题,因为仅消除了绑定。最后,通过不使用objectName,依赖项不存在。


因此,我更喜欢使用第二种方法,有关更多信息,请阅读C ++中的与QML交互。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/639801.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号