• <i id='IOIwp'><tr id='IOIwp'><dt id='IOIwp'><q id='IOIwp'><span id='IOIwp'><b id='IOIwp'><form id='IOIwp'><ins id='IOIwp'></ins><ul id='IOIwp'></ul><sub id='IOIwp'></sub></form><legend id='IOIwp'></legend><bdo id='IOIwp'><pre id='IOIwp'><center id='IOIwp'></center></pre></bdo></b><th id='IOIwp'></th></span></q></dt></tr></i><div id='IOIwp'><tfoot id='IOIwp'></tfoot><dl id='IOIwp'><fieldset id='IOIwp'></fieldset></dl></div>
  • <tfoot id='IOIwp'></tfoot>
    <legend id='IOIwp'><style id='IOIwp'><dir id='IOIwp'><q id='IOIwp'></q></dir></style></legend>
    • <bdo id='IOIwp'></bdo><ul id='IOIwp'></ul>

    <small id='IOIwp'></small><noframes id='IOIwp'>

      1. 如何从我的 Python 文件中更新 Qml 对象的属性?

        时间:2023-08-07
      2. <i id='0SaXr'><tr id='0SaXr'><dt id='0SaXr'><q id='0SaXr'><span id='0SaXr'><b id='0SaXr'><form id='0SaXr'><ins id='0SaXr'></ins><ul id='0SaXr'></ul><sub id='0SaXr'></sub></form><legend id='0SaXr'></legend><bdo id='0SaXr'><pre id='0SaXr'><center id='0SaXr'></center></pre></bdo></b><th id='0SaXr'></th></span></q></dt></tr></i><div id='0SaXr'><tfoot id='0SaXr'></tfoot><dl id='0SaXr'><fieldset id='0SaXr'></fieldset></dl></div>
        <legend id='0SaXr'><style id='0SaXr'><dir id='0SaXr'><q id='0SaXr'></q></dir></style></legend>

              <bdo id='0SaXr'></bdo><ul id='0SaXr'></ul>

              <small id='0SaXr'></small><noframes id='0SaXr'>

                <tbody id='0SaXr'></tbody>

              1. <tfoot id='0SaXr'></tfoot>

                  本文介绍了如何从我的 Python 文件中更新 Qml 对象的属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

                  问题描述

                  我想在 Qml 中显示一个矩形,并且我想从我的 python 代码中更改矩形的属性(宽度、长度).其实python代码中有一个socket连接,通过它从另一台电脑接收width和length的值.简单地说:另一个用户应该能够实时调整这个矩形.我知道如何在我的 python 文件中建立套接字连接并使用 PyQt5,我可以从 python 显示 qml 文件.

                  I want to show a rectangle in Qml and I want to change the rectangle's properties(width, length) from my python code. In fact, there is a socket connection in the python code, through which the values of width and length are received from another computer. To put it simple: another user should be able to adjust this rectangle in real-time. I know how to make a socket connection in my python file and using PyQt5, I can show the qml file from python.

                  但是,我无法通过我的 python 代码访问矩形的参数.我该怎么做?

                  However, I am in trouble to access the rectangle's parameters through my python code. How can I do that?

                  这是我的 qml 文件的简化示例:

                  This is a simplified sample of my qml file:

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

                  这是我在 .py 文件中写的内容:

                  And here is what I have written in my .py file:

                  from PyQt5.QtQml import QQmlApplicationEngine, QQmlProperty
                  from PyQt5.QtQuick import QQuickWindow, QQuickView
                  from PyQt5.QtCore import QObject, QUrl
                  from PyQt5.QtWidgets import QApplication
                  import sys
                  def run():
                      myApp = QApplication(sys.argv)
                      myEngine = QQmlApplicationEngine()
                  
                      myEngine.load('mainViewofHoomanApp.qml')
                  
                  
                      if not myEngine.rootObjects():
                          return -1
                      return myApp.exec_()
                  
                  if __name__ == "__main__":
                      sys.exit(run())
                  

                  推荐答案

                  在python/C++中有几种方法可以修改QML元素的属性,各有优缺点.

                  There are several methods to modify a property of a QML element from python/C++, and each has its advantages and disadvantages.

                  • 通过另一个对象通过findChildren获取QML对象.
                  • 分别使用 setProperty()property() 或使用 QQmlProperty 修改或访问属性.
                  • Obtain the QML object through findChildren through another object.
                  • Modify or access the property with setProperty() or property(), respectively or with QQmlProperty.

                  ma​​in.qml(qml 用于下一个 2 .py)

                  main.qml (the qml is for the next 2 .py)

                  import QtQuick 2.11
                  import QtQuick.Window 2.2
                  import QtQuick.Controls 2.2
                  
                  ApplicationWindow {    
                      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 os
                  import sys
                  from PyQt5 import QtCore, QtGui, QtQml
                  from functools import partial
                  
                  def 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 QQml 属性.

                  import os
                  import sys
                  from PyQt5 import QtCore, QtGui, QtQml
                  from functools import partial
                  
                  def 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 不知情的情况下被消除,因此它会访问不正确的引用,从而导致应用程序意外终止.

                  A disadvantage of this method is that if the relation of the object with the rootobject is complex(Sometimes objects that are in other QMLs are hard to access with findChild) the part of accessing the object becomes complicated and sometimes impossible so this method will fail. Another problem is that when using the objectName as the main search data there is a high dependency of the Python layer to the QML layer since if the objectName is modified in QML the logic in python would have to be modified. Another disadvantage is that by not managing the life cycle of the QML object it could be eliminated without Python knowing so it would access an incorrect reference causing the application to terminate unexpectedly.

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

                  ma​​in.qml

                  import QtQuick 2.11
                  import QtQuick.Window 2.2
                  import QtQuick.Controls 2.2
                  
                  ApplicationWindow {    
                      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"
                      }
                  }
                  

                  ma​​in.py

                  import os
                  import sys
                  from PyQt5 import QtCore, QtGui, QtQml
                  from functools import partial
                  
                  class 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())
                  

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

                  The disadvantage is that you have to write some more code. The advantage is that the object is accessible by all the QML since it uses setContextProperty, another advantage is that if the QML object is deleted it does not generate problems since only the binding is eliminated. And finally, by not using the objectName, the dependency does not exist.

                  所以我更喜欢使用第二种方法,更多信息请阅读 从 C++ 与 QML 交互.

                  So I prefer to use the second method, for more information read Interacting with QML from C++.

                  这篇关于如何从我的 Python 文件中更新 Qml 对象的属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!

                  上一篇:使用 Qt Designer 表单和 PyQt5 在 QWidget 中绘制 matp 下一篇:AttributeError:模块 'sipbuild.api' 没有 PyQt5 5.1

                  相关文章

                  最新文章

                        <bdo id='e7wfc'></bdo><ul id='e7wfc'></ul>
                      <i id='e7wfc'><tr id='e7wfc'><dt id='e7wfc'><q id='e7wfc'><span id='e7wfc'><b id='e7wfc'><form id='e7wfc'><ins id='e7wfc'></ins><ul id='e7wfc'></ul><sub id='e7wfc'></sub></form><legend id='e7wfc'></legend><bdo id='e7wfc'><pre id='e7wfc'><center id='e7wfc'></center></pre></bdo></b><th id='e7wfc'></th></span></q></dt></tr></i><div id='e7wfc'><tfoot id='e7wfc'></tfoot><dl id='e7wfc'><fieldset id='e7wfc'></fieldset></dl></div>
                    1. <legend id='e7wfc'><style id='e7wfc'><dir id='e7wfc'><q id='e7wfc'></q></dir></style></legend>

                    2. <tfoot id='e7wfc'></tfoot>

                      <small id='e7wfc'></small><noframes id='e7wfc'>