QDialog - Making this come forward when clicked on and other windows goes behind
-
Hello all,
Hope you are doing well!
I've been trying to research this question for the last couple of days and it seems that I cannot get a solution for my issue. So I'll post it here to see if anyone can help me...
Q: I have a main windows GUI that I am implementing. On that windows is a button that says "graph". When I click on graph, it creates a new dialog window that is modal-less. Now here is my issue. Whenever I want to click on the main application GUI, the dialog window will still be in front of the GUI app. So I can't see anything behind it. Is there a way to make whatever I click on the active window and pops out? (I'm sure there is and I'm just not implementing correctly). Scroll down for picture/explanation.
Here is my code for the button "graph" that is a part of the main GUI application.
dialog is a QDialog class. I have two GUI forms, one that is the active one that has the "graph" button and the second GUI form is the one that is displayed with this QDialog window./// This event will trigger the graph function for // heartbeat in a second window void TestGUI::on_graphButton_clicked() { dialog = new graphGUI(this); dialog->setWindowFlags(Qt::Window); dialog->show(); }
I've also attached a picture below to show you guys what I want out of this process. The main GUI application is in the back and when I click on it, it remains in the back. Is there a way for this to pop out forwards whenever I click on either window applications?
Thank you everyone for your time and help!!
Derek
-
Hi and welcome to the forums
It depends a bit on the actual windows manager.
( if on windows/linux/mac)
But normally, Dialogs stays in front of the parent. ( the this in your code)
You can try to have it freely floating by not given it parent. ( remove "this")
The Qt::Window flag might also have effect on this.Anyway, if none of it works like you want , there is also
http://doc.qt.io/qt-5/qwidget.html#raise
so you could detect clicks on main, and call raise or
http://doc.qt.io/qt-5/qwidget.html#activateWindow
on mainwindow.Sorry I cant give more concrete advice but i forgot the details. Had
same issue in linux and XFCE manager. -
Hi,
IIRC, don't give the graph dialog a parent. Giving a parent makes it go on top of that widget. To ensure you don't have a memory leak, set the
Qt::WA_DeleteOnClose
widget attribute on it. -
Hi mrjj and SGaist,
Thank you so much for both of your replies!! Okay, so I removed the parent declaration inside of the dialog definition. And it does work!
So I guess before I click this as solved, I wanted to see if you guys can help me wrap my head around this...
If I remove the parent (this) from the dialog = new GraphGUI(); , am I still able to call functions from the main GUI .cpp files? So as of right now, I have a data-set that is being graphed on the main GUI. After I click the graph button, I want it to be displayed on there. So this is my original train of thought of making the Dialog a child of the main GUI windows because i'll have access to it's private variables. Now, that it's not a child of that class, how should I go about grabbing data from the main GUI to be displayed on the dialog?
Thank you so much for both of your help!!
Derek
-
Don't make your widget access internals of another widget. That creates a tight coupling that will become a maintenance nightmare.
If your dialog needs data, then create setters for them and the widget that creates that dialog should give all necessaries information to said dialog.
-
Hi mrjj and SGaist,
Thank you so much for both of your replies!! Okay, so I removed the parent declaration inside of the dialog definition. And it does work!
So I guess before I click this as solved, I wanted to see if you guys can help me wrap my head around this...
If I remove the parent (this) from the dialog = new GraphGUI(); , am I still able to call functions from the main GUI .cpp files? So as of right now, I have a data-set that is being graphed on the main GUI. After I click the graph button, I want it to be displayed on there. So this is my original train of thought of making the Dialog a child of the main GUI windows because i'll have access to it's private variables. Now, that it's not a child of that class, how should I go about grabbing data from the main GUI to be displayed on the dialog?
Thank you so much for both of your help!!
Derek
@d_ly56
As @SGaist says, the dialog should not directly access the mainwindow
private variables. Besides the actual widgets in UI are often declared
private so you cant grab data directly from he widgets.
If possible store all data in a struct and simply give it to dialog.
like
struct MyData {
QString name;
int age;
}
and in mainwindow.h
MyData TheData;
and save the widgets data to this.then simply
void TestGUI::on_graphButton_clicked() { dialog = new graphGUI(); dialog->setData(TheData); dialog->setWindowFlags(Qt::Window); dialog->show(); }
Or do you need dialog to ask for data while open ? ( from time to time)
-
Don't make your widget access internals of another widget. That creates a tight coupling that will become a maintenance nightmare.
If your dialog needs data, then create setters for them and the widget that creates that dialog should give all necessaries information to said dialog.
-
Okay, that makes a lot more sense on why I shouldn't give it access to the private variables.
So, my GUI is constantly displaying a real-time data graph, so i'll constantly need data every second for it to update. So I guess a way that I could do this would be to send that data towards the new dialog by creating a function in dialog to set that data to a temp variable in dialog.
Then, from there, I can have access to it and just display it on the graph without having to access the main window's dataset. I can see why this is a much safer way then by giving everything access to the private variables!
Thanks again for you both for giving out these suggestions and help!
Derek
-
Okay, that makes a lot more sense on why I shouldn't give it access to the private variables.
So, my GUI is constantly displaying a real-time data graph, so i'll constantly need data every second for it to update. So I guess a way that I could do this would be to send that data towards the new dialog by creating a function in dialog to set that data to a temp variable in dialog.
Then, from there, I can have access to it and just display it on the graph without having to access the main window's dataset. I can see why this is a much safer way then by giving everything access to the private variables!
Thanks again for you both for giving out these suggestions and help!
Derek
@d_ly56
Hi
For live data, using signals and slot is much easier.
Is it a list of doubles or what is data in this context ?
You can easy
create new signal in main
and hook up to slot in dialog.and to update you simply say
emit NewData( data )
and dialogs get via its slots.Its nearly the same as a function to call, but signal and slots
makes it even better design as dialog dont even have to know mainwindow
as its slot is just called by Qt and anyone could emit data to dialog if needed.
ps. here is small sample
that open dialog that tell mainwindow to switch a tab.
The "data" flow is from dialog to mainwin, but idea is same.
https://www.dropbox.com/s/w1qo7xpjhhxjzhi/myotherdialog.zip?dl=0 -
@d_ly56
Hi
For live data, using signals and slot is much easier.
Is it a list of doubles or what is data in this context ?
You can easy
create new signal in main
and hook up to slot in dialog.and to update you simply say
emit NewData( data )
and dialogs get via its slots.Its nearly the same as a function to call, but signal and slots
makes it even better design as dialog dont even have to know mainwindow
as its slot is just called by Qt and anyone could emit data to dialog if needed.
ps. here is small sample
that open dialog that tell mainwindow to switch a tab.
The "data" flow is from dialog to mainwin, but idea is same.
https://www.dropbox.com/s/w1qo7xpjhhxjzhi/myotherdialog.zip?dl=0I did try to create a new signal in main and it's working wonderfully!
Okay, so when would I want to use a function versus a signal? I'm assuming if it's going to be a constant thing running in the background, then it's probably better to create a new signal that will just call the data by itself?
Thanks so much for that small sample, it actually made it easy to follow and add whatever I needed!
Thanks again for your help!!
Derek