Show different qml ui from c++
-
Hi,
I'm trying to make a application with qml UI and C++ backend.
When I run the application login screen comes up which is main.qml in my project.I have another application.qml file which is the UI that should show up when login is successful.
What is the best way to achieve this? I'm not sure how to proceed here.Thanks
firefox -
Hi
What about emit signal from the login screen to the c++ program if login is valid?
Then c++ can show next QML file.
http://wisol.ch/w/articles/2014-12-15-qt-signal-slots-qml-cpp/ -
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? -
engine is a local variable and gets destroyed when showClient() finishes.
-
Thanks,
that was a brain fart on my side.
This is how my slot looks like nowvoid 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?
-
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 ;)
- that was a brain fart on my side.
-
Hi, I will look into this tomorrow, I promise!
-
Ok, this is what I would do:
- backend in C++, exposed to QtQuick
- main.qml with the main application window
- Login.qml with the login window
- In main.cpp: use QQmlApplicationEngine and engine.load() to show main.qml as always
- main.qml has its visible property set to false on startup
- Login.qml is a Window from QtQuick.Window 2.0
- main.qml has such a login window as a child
- 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
- the backend has one slot and two signals
- the login window calls the backend's slot after the user has entered her password and clicked on a login button
- the backend's slot takes the entered password as argument and checks if it's correct
- if the password is correct the backend emits a "loginOk" signal, otherwise it emits a "loginFailed" signal
- 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"
- the main window has a slot connected to the backends loginOk signal
- 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! -
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.
-
@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. -
@firefox The official docs have the necessary info for dynamic creation / destruction, see: Dynamic QML Object Creation from JavaScript.
-
@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) -
@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?
-
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 } } }