How to manage popup windows?
-
Hello,
I'm working on a project that has many pop up windows. They are not organized properly and things are getting messy. I'm wondering if there are any common practice or design patterns for solving this problem.
I'd like to give you some concrete examples:
-
my program connects to two different tcp ports on the same ip. cutting off any of them, the user will be notified with a QMessageBox. But in case of unplugging network cable, both message box will show, which is unnecessary.
-
we provide a shortcut key to display a setting dialog. However the program can also show the same dialog when certain event happens. If the user opens the setting dialog already, those event will still trigger a second setting dialog.
-
when application settings are not correct, user will disconnect from the server and an error dialog will show up and terminate the program. But if the user knows about the situation and has opened the setting dialog to fix the issue, the error dialog will terminate his work. which is bad.
I don't know how to deal with this window management problem in a complex software project. Of course, I can solve the issue case by case by checking if certain dialog is shown before displaying another dialog. But there are too many cases, when the code base gets big, this is not practical.
there must be some generic solution I think.
-
-
Question is - can you go one step before the display of the message boxes and make some of the errors plainly visible in the actual main screen the user is looking at? For 1., in some cases, if the error changes the user interface (for example, disables some of the functionality) then that change along with a visible "info" area update could do the trick and save you a lot of extra checking around what message box is already displayed or was already displayed.
For 2. and 3. I guess one needs to know the application. But it seems that the hooking up of events to immediately display message boxes is wrong. Instead, consider what functionality should be available at each point (i.e. maybe a certain settings dialog should not be editable during "operation" mode exactly because of these events? Maybe if an event happens while the user is with a settings dialog open, it should only affect the changes if the user tries to store his new changes - and then he can have that information only then and decide what to do with it?)
I'm sorry if it's a bit general - I'm not much of a user interface guy, but from your description would try to avoid the event-leads-to-messagebox as much as possible.
-
If you are using the static MessageBox calls such as QMessageBox::information(), or QMessageBox::warning() there is not much you can do as these are on the stack, and go out of scope when clicked.
If you are doing this I would modify your code and create your own Message Dialog, adding your own methods for passing and updating messages, Then create this MessageBox on the heap as show below. This way you only have one Message Dialog .
Below I show you how this code might look, of course you will have to write your own MyMessagePopup class inherrited from QDialog or QMessageBox , and make sure this window is not destroyed on close (See QDialog class) and put in methods like I have for the different kind of messages: showMessage() & showError().
Then, no matter where you are in you code, have it so a "show message" request always gets sent to MyMainWindow::showMessage() - one dialog used over and over.
mymainwindow.h:
@class MyMainWindow : public QMainWindow
{
public:
MyMainWindow(QWidget *parent);
void showMessage(QString &);
void showError((QString &);
private:
MyMessagePopup *myMessagePopup;
}
@mymainwindow.cpp:
@
MyMainWindow(QWidget *parent):: QMainWindow(parent):myMesagePopup(0)
{
...
}
void MyMainWindow::showMessage(QString &messageStr)
{
if (!myMessagePopup)
myMessagePopup = new MyMessagePopup();
myMessagePopup->setMessage(messageStr);
myMessagePopup->show();
}
void MyMainWindow::showError(QString &errorStr)
{
if (!myMessagePopup)
myMessagePopup = new MyMessagePopup();
myMessagePopup->setError(errorStr);
myMessagePopup->show();
}
@ -
Thank you very much for the suggestions.
I really want to find a silver bullet for this kinda of problem.
I'm thinking of using state machine.