PDA

View Full Version : How to prevent recreation of dialogs



yektaayduk
8th November 2007, 15:06
Hi
I have some QPopupMenu 's on the MenuBar.They are creating QDialogs (not modal one)for different purposes by executing similar code like below:

SignalProcessDialog *SPdialog=new SignalProcessDialog;
SPdialog-> show();

When the user activates another dialog (?SettingsDialog) the SPdialog goes to background(obscured by the mainwindow) and the user activate-create another one from the MenuBar if he needs to change a SProcess parameter.How can I get rid of these unused QDialog windows.How can I be aware of its existence and not to create again and raise it.

yekta

mchara
8th November 2007, 15:30
hi,

add QDialog *somethihing pointers for each dialog you're using to i.e. mainwindow class,
create all dialogs in mainwindow constructor & destroy in destructor, then call somethihing->show() / somethihing ->hide() when you need - dialogs will show or hide itself but not create/destroy - you only need to remember dialogs pointers.

momesana
8th November 2007, 16:10
You can also tell the Dialogs via Window flags to be destroyed when they are closed.
Qt::WA_DeleteOnClose
Makes Qt delete this widget when the widget has accepted the close event (see QWidget::closeEvent()).
In your case however the dialogs seem to never be closed, just obscured so this will not help you much.

The best way in your case is to use an approach similar to the one suggested above but not to create the Dialogs unless they are requested. This way, the programm will have a fast startup and not occupy any memory for the dialogs until they are really requested the first time.
That means, you have a bunch of pointers that point to the dialogs you may need in your application. In your constructor you initialize all pointers to 0. In the slots that are called when a user demands a dialog you check for the pointer and create a dialog *only* if the pointer is null. Then you show it:



// constructor
...
m_dialogX = 0;
...


// slot
void dialogX()
{
if (!m_dialogX) {
m_dialogX = new DialogX(this);
}
m_dialogX->show();
m_dialogX->raise();
}


if m_dialogX points to 0, it means the respective dialog has not been created yet. Is this really the case we create an Object on the free store and assign its address to the pointer. Then the dialogX is shown. In case the user had closed the dialog, it will be shown again. Next we raise it to the top of the parent widget's stack. If it was already shown and solely obscured it will be put atop of other widgets and thus will be visible again.

mchara
9th November 2007, 08:10
Good suggestion, absolutely right !
Maybe it's also worth to hide unused dialogs (finished() signal)just to keep your app esthetic's - not all users will use it on fullscreen or on single display, so don't trust unused dialogs will be always hidden by main window.

wysota
9th November 2007, 12:33
http://www.qtcentre.org/forum/faq.php?faq=qt_general_category#faq_qt_designer_2f orms

Note the "static" keyword.

yektaayduk
9th November 2007, 13:48
Thank you momesana.I'll use it this way.

momesana
9th November 2007, 16:08
http://www.qtcentre.org/forum/faq.php?faq=qt_general_category#faq_qt_designer_2f orms

Note the "static" keyword.
Neat. This way there is no initialisation to zero required in the constructor. Which approach is the more "formal"/standard way to do it? using static or initialising the pointer to zero. Which approach is used by larger programs? Using static is so elegant, I am surprised I,ve never seen any use of it in my Qt Textbooks.

jpn
9th November 2007, 20:40
Neat. This way there is no initialisation to zero required in the constructor. Which approach is the more "formal"/standard way to do it? using static or initialising the pointer to zero. Which approach is used by larger programs? Using static is so elegant, I am surprised I,ve never seen any use of it in my Qt Textbooks.
Of course, if there are more than one "Form1"'s and each of them needs to have its own "Form2", you cannot have a static variable but you would have to use a member variable instead. For some reason static variables are not usually encouraged to be used like this. I really don't know why, I think they're neat too. In addition what you have said, the header file also remains cleaner.. :)

yektaayduk
10th November 2007, 20:57
I tried the code below ,the dialog is not recreated ,works fine.
Thanks wyosota.

static SignalProcessDialog *SPdialog=new SignalProcessDialog;
SPdialog-> show();
SPdialog-> raise();

momesana
11th November 2007, 15:49
But as jpn pointed out, it is important to keep in mind that the static function variable is only initialised *once* for every function calling it from any object of the class. That means if you have two instances of class Y and both call one of its memberfunctions using static, only the first call will initialise its static variables and subsequent calls from both instances work with the same values.

Here is an example:


#include <iostream>
using namespace std;

class X
{
int m_value;
public:
X(int val) : m_value(val) {}
friend ostream& operator<<(ostream& o, X& x) { return o << x.m_value; }
};

class Y
{
public:
Y(int val) { value(val); };
friend ostream& operator<<(ostream& o, Y& y) { return o << y.value(); }
private:
int value(int val=0) { static int value = val; return value; }
};

int main()
{
// Using membervariables
X a(8), b(68), c(3);
cout << a << ", " << b << ", " << c << endl;

//Using static int
Y d(22), e(45), f(87);
cout << d << ", " << e << ", "<< f << endl;
}


Now, if you apply this idea to your Mainwindow with the dialogs, you can see that class X would give you a dialog for each MainWindow whereas Y gives you a single dialog shared by all instances. Both approaches have their uses.

wysota
11th November 2007, 16:01
The limitation of "my" approach (which is not really mine, I think we copied it from some other Qt resource) is only a drawback if you intend to have more than one window of some type opened at the same time.