Uploaded image for project: 'Qt for Python'
  1. Qt for Python
  2. PYSIDE-900

No (obvious) way to create setter using QtCore.Property as a decorator.

    XMLWordPrintable

Details

    • Bug
    • Resolution: Incomplete
    • P2: Important
    • None
    • 5.11.2
    • PySide
    • None
    • Linux/X11

    Description

      The PySide2 document that best explains creating Qt Properties seems to be this one: 

      https://wiki.qt.io/Qt_for_Python_UsingQtProperties

      This makes no mention of the @Property decorator, which does exist, and which has an analog in PyQt5, according to https://stackoverflow.com/questions/52046551/using-radialbar-qml-port-with-pyqt5.  Note the use of setters in PyQt5 – maybe there is a similar way to define a setter in PySide2 but I was unable to find it.

      Here's PyQt5 example code, along with QML. 

      import sys
      
      from PyQt5.QtCore import pyqtSlot, pyqtProperty, pyqtSignal, QObject, QUrl
      from PyQt5.QtWidgets import QApplication
      from PyQt5.QtQml import QQmlApplicationEngine
      
      from PyQt5.QtQml import qmlRegisterType
      
      
      class DataContainer(QObject):
          dataChanged = pyqtSignal()
      
          def __init__(self, parent=None):
              super().__init__(parent)
              self._data = ""
      
          @pyqtProperty(str, notify=dataChanged)
          def data(self):
              return self._data
      
          @data.setter
          def data(self, value):
              print("Set " + value)
              self._data = value
              self.dataChanged.emit()
      
      
      if __name__ == "__main__":
          app = QApplication(sys.argv)
          qmlRegisterType(DataContainer, "MyStuff", 1, 0, "DataContainer")
      
          engine = QQmlApplicationEngine()
          engine.load(QUrl("main.qml"))
      
          sys.exit(app.exec_())
      
      import QtQuick 2.9
      import QtQuick.Controls 1.4
      
      import MyStuff 1.0
      
      ApplicationWindow {
          visible: true
          width: 1280
          height: 1024
          title: "Bug Report"
      
          DataContainer {
              data: "blahblah"
          }
      }
      

      Note the setter prints as expected.  Now try replacing PyQt5 with PySide2 as follows:

      import sys
      
      from PySide2.QtCore import Slot, Property, Signal, QObject, QUrl
      from PySide2.QtWidgets import QApplication
      from PySide2.QtQml import QQmlApplicationEngine
      
      from PySide2.QtQml import qmlRegisterType
      
      
      class DataContainer(QObject):
          dataChanged = Signal()
      
          def __init__(self, parent=None):
              super().__init__(parent)
              self._data = ""
      
          @Property(str, notify=dataChanged)
          def data(self):
              return self._data
      
          @data.setter
          def data(self, value):
              print("Set " + value)
              self._data = value
              self.dataChanged.emit()
      
      
      if __name__ == "__main__":
          app = QApplication(sys.argv)
          qmlRegisterType(DataContainer, "MyStuff", 1, 0, "DataContainer")
      
          engine = QQmlApplicationEngine()
          engine.load(QUrl("main.qml"))
      
          sys.exit(app.exec_())
      

      This fails to load the QML, you will see error text:

      Cannot assign to non-existent property "data"
       

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            kleint Friedemann Kleint
            nels David Friberg
            Votes:
            1 Vote for this issue
            Watchers:
            8 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes