title: How to create PyQt Properties dynamically
body: <p>I am currently looking into a way to create GUI desktop applications with Python and HTML/CSS/JS using PyQt5's <strong>QWebEngineView</strong>.</p>
  
  <p>In my little demo application, I use a <strong>QWebChannel</strong> to publish a Python <strong>QObject</strong> to the JavaScript side, so that data can be shared and passed back and forth. Sharing and connecting slots and signals so far works fine.</p>
  
  <p>I'm having difficulties though with the synchronisation of simple (property) values. From what I've read, the way to go is to implement a pyqtProperty in the shared QObject via decorated getter and setter functions, with an additional signal emitted in the setter, used to notify JavaScript when the value has changed. The code below shows that and so far this works fine:</p>
  
  <pre><code>import sys
  from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal 
  from PyQt5.QtWidgets import QApplication
  from PyQt5.QtWebChannel import QWebChannel
  from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage
  
  
  class HelloWorldHtmlApp(QWebEngineView):
      html = '''
      &lt;!DOCTYPE html&gt;
      &lt;html&gt;
      &lt;head&gt;
          &lt;meta charset="utf-8"/&gt;        
          &lt;script src="qrc:///qtwebchannel/qwebchannel.js"&gt;&lt;/script&gt;
          &lt;script&gt;
          var backend;
          new QWebChannel(qt.webChannelTransport, function (channel) {
              backend = channel.objects.backend;
          });
          &lt;/script&gt;
      &lt;/head&gt;
      &lt;body&gt; &lt;h2&gt;HTML loaded.&lt;/h2&gt; &lt;/body&gt;
      &lt;/html&gt;
      '''
  
      def __init__(self):
          super().__init__()
  
          # setup a page with my html
          my_page = QWebEnginePage(self)
          my_page.setHtml(self.html)
          self.setPage(my_page)
  
          # setup channel
          self.channel = QWebChannel()
          self.backend = self.Backend(self)
          self.channel.registerObject('backend', self.backend)
          self.page().setWebChannel(self.channel)
  
      class Backend(QObject):
          """ Container for stuff visible to the JavaScript side. """
          foo_changed = pyqtSignal(str)
  
          def __init__(self, htmlapp):
              super().__init__()
              self.htmlapp = htmlapp
              self._foo = "Hello World"
  
          @pyqtSlot()
          def debug(self):
              self.foo = "I modified foo!"
  
          @pyqtProperty(str, notify=foo_changed)
          def foo(self):            
              return self._foo
  
          @foo.setter
          def foo(self, new_foo):            
              self._foo = new_foo
              self.foo_changed.emit(new_foo)
  
  
  if __name__ == "__main__":
      app = QApplication.instance() or QApplication(sys.argv)
      view = HelloWorldHtmlApp()
      view.show()
      app.exec_()
  </code></pre>
  
  <p>Starting this with the Debugger connected, I can call the <code>backend.debug()</code> slot in the JavaScript console, which leads to the value of <code>backend.foo</code> being "I modified foo!" afterwards, which means the Python code succesfully changed the JavaScript variable.</p>
  
  <p>This is kind of tedious though. For every value I'd want to share, I'd have to</p>
  
  <ul>
  <li>create an internal variable (here <code>self._foo</code>)</li>
  <li>create a getter function</li>
  <li>create a setter function</li>
  <li>create a signal in the <code>QObject</code>'s body</li>
  <li>emit this signal explicitly in the setter function</li>
  </ul>
  
  <p>Is there any simpler way to achieve this? Ideally some sort of one-liner declaration? Maybe using a class or function to pack that all up? How would I have to bind this to the <code>QObject</code> later on? I'm thinking of something like</p>
  
  <pre><code># in __init__
  self.foo = SyncedProperty(str)
  </code></pre>
  
  <p>Is this possible? Thanks for your ideas!</p>