Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Setting context property for individual QML UI element
Forum Updated to NodeBB v4.3 + New Features

Setting context property for individual QML UI element

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
3 Posts 3 Posters 849 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • ? Offline
    ? Offline
    A Former User
    wrote on last edited by A Former User
    #1

    Hello,
    I am in process of learning Qt and writing it in python. So far progress is good, but I've come across one problem which I don't know how to solve. Let's look at a sample app:

    # foo.py
    from PySide2.QtCore import QObject, Property, Slot
    
    class FooController(QObject):
        def __init__(self, parent=None):
            QObject.__init__(self, parent)
            self.__text = "Foo"
    
        @Property(str)
        def text(self):
            return self.__text
    
        @Slot()
        def clickListener(self):
            print('Foo')
    
    // Foo.qml
    import QtQuick 2.9
    import QtQuick.Controls 2.2
    
    Button {
        text: fooController.text
        onClicked: fooController.clickListener()
    }
    
    # bar.py
    from PySide2.QtCore import QObject, Property, Slot
    
    class BarController(QObject):
        def __init__(self, parent=None):
            QObject.__init__(self, parent)
            self.__text = "Bar"
    
        @Property(str)
        def text(self):
            return self.__text
    
        @Slot()
        def clickListener(self):
            print('Bar')
    
    // Bar.qml
    import QtQuick 2.9
    import QtQuick.Controls 2.2
    
    Button {
        text: barController.text
        onClicked: barController.clickListener()
    }
    
    # main.py
    import sys
    from PySide2.QtCore import QUrl
    from PySide2.QtGui import QGuiApplication
    from PySide2.QtQml import QQmlApplicationEngine
    
    from lib.bar.bar import BarController
    from lib.foo.foo import FooController
    
    if __name__ == '__main__':
        app = QGuiApplication(sys.argv)
        engine = QQmlApplicationEngine()
    
        fooController = FooController()
        barController = BarController()
    
        engine.rootContext().setContextProperty("fooController", fooController)
        engine.rootContext().setContextProperty("barController", barController)
        engine.load(QUrl.fromLocalFile('main.qml'))
    
        if not engine.rootObjects():
            sys.exit(-1)
        sys.exit(app.exec_())
    
    // main.qml
    import QtQuick.Controls 2.2
    import QtQuick 2.10
    import "./foo"
    import "./bar"
    
    ApplicationWindow {
        visible: true
    
        Row {
            Foo {}
            Bar {}
        }
    }
    

    This sample app works as intended: two buttons are displayed with names 'Foo' and 'Bar', and on click they print text in console.
    What I don't like, is that currently I am setting context properties for both components in main:

    engine.rootContext().setContextProperty("fooController", fooController)
    engine.rootContext().setContextProperty("barController", barController)
    

    This results in controllers being available globally in qml. What I want to achieve is modular approach. I can imagine that it would look like this - in main.py:

    context = engine.rootContext()
    fooController.attachToContext(context)
    barController.attachToContext(context)
    

    and corresponding methods in controllers:

     def attachToContext(self, context):
            elemContext = context.findQmlElementByName("Foo").context()
            elemContext.setContextProperty("controller", self)
    

    This way (I guess) controllers could be isolated and only accessed by the view they are set to, also this way name conflicts could be avoided. But this is theory, as I have no idea how could I achieve this - I've looked for solutions, but to no avail.

    Thank you in advance for any suggestions

    1 Reply Last reply
    1
    • dheerendraD Offline
      dheerendraD Offline
      dheerendra
      Qt Champions 2022
      wrote on last edited by
      #2

      What you are looking for is two separate context and expose the object separately. If this is the case did you get a chance to look at QQmlContext documentation. It has an example expose with different contexts.

      Dheerendra
      @Community Service
      Certified Qt Specialist
      http://www.pthinks.com

      P 1 Reply Last reply
      0
      • dheerendraD dheerendra

        What you are looking for is two separate context and expose the object separately. If this is the case did you get a chance to look at QQmlContext documentation. It has an example expose with different contexts.

        P Offline
        P Offline
        patrickkidd
        wrote on last edited by patrickkidd
        #3

        @dheerendra said in Setting context property for individual QML UI element:

        What you are looking for is two separate context and expose the object separately. If this is the case did you get a chance to look at QQmlContext documentation. It has an example expose with different contexts.

        I would like to know this as well.

        The documentation only describes how to create a QQmlContext as a child of another QQmlContext, but doesn't say anything about how to retrieve or set a QQmlContext for a particular QQuickWidget.

        https://alaskafamilysystems.com/

        1 Reply Last reply
        0

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved