Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Show different qml ui from c++
Forum Updated to NodeBB v4.3 + New Features

Show different qml ui from c++

Scheduled Pinned Locked Moved Unsolved General and Desktop
c++qml
30 Posts 5 Posters 10.9k Views 5 Watching
  • 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.
  • F Offline
    F Offline
    firefox
    wrote on last edited by
    #5

    This is my slot that gets called when login is succesful.

    void Login::showClient()
    {
        cout<<"trying to load client"<<endl;
        QQmlApplicationEngine engine;
        engine.load(QUrl(QStringLiteral("qrc:/BuddyList.qml")));
    
    }
    

    my cout statement gets printed that means slot is indeed getting called.
    Should I really be creating a new engine and load the qml file is there an elegant way of doing it?

    1 Reply Last reply
    0
    • jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on last edited by
      #6

      engine is a local variable and gets destroyed when showClient() finishes.

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      1
      • mrjjM Offline
        mrjjM Offline
        mrjj
        Lifetime Qt Champion
        wrote on last edited by
        #7

        @firefox said:
        well this seems wrong as
        QQmlApplicationEngine engine;
        is a local variable and will be deleted as soon as function ends.

        Cant you use the original engine that loads the login?

        1 Reply Last reply
        1
        • F Offline
          F Offline
          firefox
          wrote on last edited by firefox
          #8

          Thanks,

          that was a brain fart on my side.
          This is how my slot looks like now

          void Login::showClient()
          {
              emit loginSuccessful();
              cout<<"trying to load client"<<endl;
              Q_ASSERT(engine);
              engine->load(QUrl(QStringLiteral("qrc:/BuddyList.qml")));
          }
          

          Now the problem is login.qml is still shown even after loading new qml file to same engine.
          To overcome this, I added a new signal that is emitted when login is succesful that is picked by login.qml and set's it visible property to false.

          But this seems like a hack and I'm guessing the login.qml instance still lingers around in memory. Do you guys suggest any better way to unload the login.qml from engine?

          1 Reply Last reply
          0
          • mrjjM Offline
            mrjjM Offline
            mrjj
            Lifetime Qt Champion
            wrote on last edited by
            #9

            Hi

            • that was a brain fart on my side.
              Its a classic fart :)

            Im have not used QML so much to know if there is better way
            and not sure how to unload using engine.

            We can try to ask @Wieland ;)

            1 Reply Last reply
            0
            • F Offline
              F Offline
              firefox
              wrote on last edited by
              #10

              @mrjj

              Thanks mrjj.
              I'm new to this forum. How to include @Wieland to this discussion? Will he be getting a notification if I @mention him.

              mrjjM 1 Reply Last reply
              0
              • F firefox

                @mrjj

                Thanks mrjj.
                I'm new to this forum. How to include @Wieland to this discussion? Will he be getting a notification if I @mention him.

                mrjjM Offline
                mrjjM Offline
                mrjj
                Lifetime Qt Champion
                wrote on last edited by
                #11

                @firefox
                yes he will :)
                Hopefully he dont mind :)

                1 Reply Last reply
                0
                • ? Offline
                  ? Offline
                  A Former User
                  wrote on last edited by
                  #12

                  Hi, I will look into this tomorrow, I promise!

                  1 Reply Last reply
                  1
                  • ? Offline
                    ? Offline
                    A Former User
                    wrote on last edited by A Former User
                    #13

                    Ok, this is what I would do:

                    1. backend in C++, exposed to QtQuick
                    2. main.qml with the main application window
                    3. Login.qml with the login window
                    4. In main.cpp: use QQmlApplicationEngine and engine.load() to show main.qml as always
                    5. main.qml has its visible property set to false on startup
                    6. Login.qml is a Window from QtQuick.Window 2.0
                    7. main.qml has such a login window as a child
                    8. on startup the login window's visible property is set to true

                    -> on startup both the main window and the login window are loaded but only the login window is visible

                    1. the backend has one slot and two signals
                    2. the login window calls the backend's slot after the user has entered her password and clicked on a login button
                    3. the backend's slot takes the entered password as argument and checks if it's correct
                    4. if the password is correct the backend emits a "loginOk" signal, otherwise it emits a "loginFailed" signal
                    5. the login window has a slot connected to the backend's loginFailed signal. if it receives this signal it will tell the user to try it again

                    -> if password is wrong login window says "try again"

                    1. the main window has a slot connected to the backends loginOk signal
                    2. if it receives this signal it will make the login window invisible and make itself (the main window) visible

                    If you like the idea then I can post a working example.
                    Cheers!

                    1 Reply Last reply
                    3
                    • ? Offline
                      ? Offline
                      A Former User
                      wrote on last edited by
                      #14

                      Oh, I forgot this: If you're really concerned about the memory the login window consumes then you can also create and destroy the login window dynamically from within main.qml.

                      1 Reply Last reply
                      1
                      • F Offline
                        F Offline
                        firefox
                        wrote on last edited by
                        #15

                        @Wieland
                        Thank you. I like your idea. I'm new to qml but I'd like to try it out myself first and see if I can get it working.
                        I'd like to know about creating and destroying the login window dynamically. I think I would need it as the application is a chat client and I'd require to create and destroy chat windows.

                        ? 1 Reply Last reply
                        0
                        • F firefox

                          @Wieland
                          Thank you. I like your idea. I'm new to qml but I'd like to try it out myself first and see if I can get it working.
                          I'd like to know about creating and destroying the login window dynamically. I think I would need it as the application is a chat client and I'd require to create and destroy chat windows.

                          ? Offline
                          ? Offline
                          A Former User
                          wrote on last edited by
                          #16

                          @firefox The official docs have the necessary info for dynamic creation / destruction, see: Dynamic QML Object Creation from JavaScript.

                          kshegunovK 1 Reply Last reply
                          0
                          • ? A Former User

                            @firefox The official docs have the necessary info for dynamic creation / destruction, see: Dynamic QML Object Creation from JavaScript.

                            kshegunovK Offline
                            kshegunovK Offline
                            kshegunov
                            Moderators
                            wrote on last edited by kshegunov
                            #17

                            @Wieland
                            Isn't this a fairly complex solution for quite the simple problem?
                            (I'm not arguing about the solution itself, only pondering about QML)

                            Read and abide by the Qt Code of Conduct

                            1 Reply Last reply
                            0
                            • F Offline
                              F Offline
                              firefox
                              wrote on last edited by firefox
                              #18

                              @Wieland

                              I created a login.qml and added it as child of main.qml and visible set to true
                              main.qml has it's visible property set to false and when it receives loginSuccesful signal it's visible is set to true and login's visible is set to false.

                              ApplicationWindow {
                                  id: mainClientId
                                  visible: false
                                  height: 640
                                  width:480
                                  minimumHeight: 500
                                  minimumWidth: 400
                                  color: "#cecece"
                              
                              
                                  Login {   //This is defined as window in Login.qml
                                      visible: true
                                      id: loginClientId
                                  }
                              
                              
                                  Connections {
                                      target: loginClass
                                      onLoginSuccessful: {
                                          console.log("in Connections")
                                          mainClientId.visible = true
                                          loginClientId.visible = false
                                      }
                              
                                  }
                              }
                              

                              But since the parent's visible property is false, even login window doesn't show up when i run the application. Am I doing it right?

                              @kshegunov what do you suggest here?

                              kshegunovK 1 Reply Last reply
                              0
                              • F firefox

                                @Wieland

                                I created a login.qml and added it as child of main.qml and visible set to true
                                main.qml has it's visible property set to false and when it receives loginSuccesful signal it's visible is set to true and login's visible is set to false.

                                ApplicationWindow {
                                    id: mainClientId
                                    visible: false
                                    height: 640
                                    width:480
                                    minimumHeight: 500
                                    minimumWidth: 400
                                    color: "#cecece"
                                
                                
                                    Login {   //This is defined as window in Login.qml
                                        visible: true
                                        id: loginClientId
                                    }
                                
                                
                                    Connections {
                                        target: loginClass
                                        onLoginSuccessful: {
                                            console.log("in Connections")
                                            mainClientId.visible = true
                                            loginClientId.visible = false
                                        }
                                
                                    }
                                }
                                

                                But since the parent's visible property is false, even login window doesn't show up when i run the application. Am I doing it right?

                                @kshegunov what do you suggest here?

                                kshegunovK Offline
                                kshegunovK Offline
                                kshegunov
                                Moderators
                                wrote on last edited by
                                #19

                                @firefox
                                I don't work with QML, so I'm not suggesting anything. I was simply surprised it looks so complicated in QML (for the widgets module, which I use, what you're asking would be a two line snippet).

                                Read and abide by the Qt Code of Conduct

                                1 Reply Last reply
                                0
                                • F Offline
                                  F Offline
                                  firefox
                                  wrote on last edited by
                                  #20

                                  Okay, Just realized the mistake.

                                  This is how main.qml looks now and it works.

                                  
                                  Item {
                                  
                                      Client {
                                          id: clientId
                                          visible:false
                                      }
                                  
                                      Login {
                                          id: loginId
                                          visible: true
                                      }
                                  
                                  
                                      Connections {
                                          target: loginClass
                                          onLoginSuccessful: {
                                              console.log("in Connections")
                                              clientId.visible = true
                                              loginId.visible = false
                                          }
                                  
                                      }
                                  }
                                  
                                  
                                  1 Reply Last reply
                                  0
                                  • F Offline
                                    F Offline
                                    firefox
                                    wrote on last edited by firefox
                                    #21

                                    folks,

                                    got another problem

                                    I have this signal messageReceivedToQml emitted by my c++ backend when a new message arrives.
                                    And I connected to my qml like this

                                    Connections {
                                            target: loginClass
                                            onMessageReceivedToQml: {
                                                console.log("in client connections")
                                                Script.createChatWindow()
                                            }
                                        }
                                    

                                    my createChatWindow javascript function is

                                    function createChatWindow() {
                                        console.log("creating chat window");
                                        var chatWindow2 = Qt.createComponent("ChatWindow.qml");
                                        chatWindow2.createObject(clientId);
                                    }
                                    
                                    

                                    the log 'creating chat window' gets printed when i receive a message but the chat window created is not visible. Am I missing something here?

                                    1 Reply Last reply
                                    0
                                    • mrjjM Offline
                                      mrjjM Offline
                                      mrjj
                                      Lifetime Qt Champion
                                      wrote on last edited by
                                      #22

                                      Hi
                                      I dont know QML but
                                      i was wondering if it needs something like
                                      chatWindow2.visible = true
                                      or
                                      chatWindow2.show()

                                      Sorry if its just silly. :)

                                      1 Reply Last reply
                                      0
                                      • F Offline
                                        F Offline
                                        firefox
                                        wrote on last edited by firefox
                                        #23

                                        @mrjj Even I'm new to qml. nothing is sily to me :)

                                        I can't beleive i did the same mistake of using local variables instead of global. (Update: this is not the issue. Just had to delete the build folder and build again)
                                        I changed the code as below.

                                        var chatWindow;
                                        var sprite;
                                        function createChatWindow() {
                                            console.log("creating chat window");
                                            chatWindow = Qt.createComponent("ChatWindow.qml");
                                            sprite=chatWindow.createObject(clientId);
                                        }
                                        
                                        

                                        Update:Okay, It worked after the above changes. I just had to delete the build folder and build again.

                                        damn i edited the post instead of new post and everything is gone. edited again and added the code.

                                        1 Reply Last reply
                                        1
                                        • F Offline
                                          F Offline
                                          firefox
                                          wrote on last edited by firefox
                                          #24

                                          Hi folks,

                                          Have an issue here. have a look at this code I'm trying.

                                          
                                          function handleMessage(from, msg) {
                                              var mysprite = loginClass.checkJid(from);  //This method returns the QQuickWindow object
                                              if(mysprite != "not found")
                                              {
                                                  console.log("in append block")   //This means this is a connected client and is not the first message. So we just append the message to chatAreaId(TextArea)
                                                  mysprite.chatAreaId.append(from+":"+msg);   //chatAreaId is the id of TextArea component 
                                              }
                                              else {
                                                  mysprite = createChatWindow();
                                                  console.log("in chat window block")    //This means the client is connecting to us for first time. so we need to create a dedicated chat window for the client  and add the id of client to backend with addToJids
                                                  loginClass.addToJids(from, mysprite);
                                                  mysprite.chatAreaId.append(from+":"+msg);
                                              }
                                          }
                                          
                                          function createChatWindow() {
                                              var chatWindow;
                                              var sprite;
                                              console.log("creating chat window");
                                              chatWindow = Qt.createComponent("ChatWindow.qml");
                                              sprite=chatWindow.createObject(clientId);   //This is a QQuickWindow
                                              return sprite;
                                          }
                                          

                                          So when I get a message I want to append it to TextArea component of my QQuickWindow object created dynamically with createObject.() function. But how do I access the qml components of QQuickWindow created dynamically?

                                          The above code gives an error saying "Cannot call method 'append' of undefined"

                                          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