Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Interaction between QML



  • Hello,

    I'm developing an app for 2 types of users and I want to limit the access of some function for one user to another.
    On the first page, the user have to choose with 2 buttons if he is a doctor or a visitor, then the second page have to disable some buttons if he is a visitor.

    I'm thinking of send a signal from the first page to C++ then a signal from C++ to the QML second page, but I wanted to know if there is a way to pass some data from QML (first page) to QML (second page) to modify some items ?

    Thank you


  • Moderators

    @Djeff said:

    I'm thinking of send a signal from the first page to C++ then a signal from C++ to the QML second page, but I wanted to know if there is a way to pass some data from QML (first page) to QML (second page) to modify some items ?

    Of course this is possible.
    For QML to QML you should read QML's property binding feature
    Create a property for the current user type. And use this property in your condition to display the buttons or not. Then it gets updated automatically when the property changes.



  • It's gonna be something like that.
    Note the property userType of Page2 is bound to same property of Page1

    main.qml:
    RootItem {
      Page1 { id: page1 }
      Page2 { userType: page1.userType }
    }
    
    page1.qml:
    Page1 {
      id: root
      property string userType
      Button { text: 'doctor'; onClicked: { userType = 'doctor'; root.close() } }
      Button { text: 'visitor'; onClicked: { userType = 'visitor'; root.close() } } 
    }
    
    page2.qml:
    Page2 {
      property string userType
      ControlsForAll { }
      ControlsForDoctorOnly { enabled: userType == 'doctor' }
    }
    


  • Hello, thanks for your help

    I'm trying to use this "Page2 { userType: page1.userType }" but I dont know how because every page I created have a name like : Pane, applicationWidows etc ... does it possible to create a personal name for a page ? or what I have to do if page1.qml and page2.qml are like this : Pane{.......} , to refere the right page here "Page2 { userType: page1.userType }"

    Thanks

    Edit : I was able to do what I was looking for, using this :

    main.qml
    Pane{
    id: paneMain
    property string userType
    Button{ onClicked: userType = 'Doctor'
    //go to inicio.qml
    }
    }
    
    Inicio.qml
    Pane {
    id : paneInicio
    property string userType
    Button {
    enabled: userType == 'doctor'
                Component.onCompleted: {
                    paneInicio.userType = paneMain.userType
                }
    }
    }
    

    Is that a good way to do ?



  • @Djeff I guess it's not very good.
    The problem is your onCompleted will be called before the user chooses anything on the paneMain in case all the QML files are instantiated at once. And it's not a property binding but a value copying only. So it happens at once and doesn't last long.
    Another problem is that paneInicio must know something about paneMain which is bad from software design point of view. Ideally the dialogs must know only about their parent.



  • If its not good enough i dont really understand how you refer to Page1 or Page2 if I can only use Pane, window, etc to name it ?

    Edit : I think i get it, I have to write this : Inicio { userType: paneMain.userType} , but the problem is that putting this, it put the button of that page in the main page and I dont want this ... :/



  • @Djeff send me the sources, I'll fix the problem. Just upload them to Google Drive and share the link



  • Thank for your help

    well ... I use the Qt's example gallery because it have a good base about what i'm looking for.
    My code is a mess ! I know :) because I using QML since 1 month and I dont have time to learn, so I try to touch everything, and if its work, its good enough for me. I will optimize this in the futur

    The user have to choose if he is a doctor ou visitor on the main page then it block some function on the Inicio page and Servicios page

    here is the files : https://drive.google.com/folderview?id=0B0fuJMdeNSJNS0xZTEw4NzF5dWM&usp=sharing



  • @Djeff Look at gallery.qml button "Visitante", onClicked handler. You want to set the userType first and then proceed to the next page. right? I did the change and it worked better:

                            onClicked: {paneMain.userType = 'visitor';
                                stackView.push(Qt.resolvedUrl("qrc:/pages/Inicio.qml"))
    


  • It worked fine before too, but you tell me to not use this kind of code because I'm not binding the userType

    enabled: userType == 'doctor'
            Component.onCompleted: {
                paneInicio.userType = paneMain.userType
            }
    

    Did you bound it somewhere on the gallery.qml or everything is the same ?



  • @Djeff No it didn't work well before :)
    Just try to log in as a doctor, then return to main screen, then press buttons "Visitor", then "Back", then again "Visitor" and "Back" again. You'll see the controls get disabled in every second case.

    OK. In your code you have to choose where to store the userType information.

    1. To use a 'global' object like paneMain. In this case you have references to paneMain in Inicio.qml which is not good as usually children shouldn't know much about parents. It can be fixed by extracting the Soy pane to a separate file and organizing everything like I wrote in the first post so that only parent would know about children properties.

    2. To let Soy pane know about the Inicio pane and store userType in local variables rather than in a global object. This is also possible but later most likely it'll lead you to a close-coupled spaghetti code. So in this case it's better to remove userType from mainPane and use the following stack view push command:

    stackView.push("qrc:/pages/Inicio.qml", {userType: 'visitor'})
    


  • I will, thank for all your help !


Log in to reply