You are not logged in.

carpovpv

Beginner

  • "carpovpv" is male
  • "carpovpv" started this thread

Posts: 13

Location: Moscow

Occupation: teacher

  • Send private message

1

Saturday, December 10th 2011, 2:58pm

Close all windows that are childs from this window

Hi, there!

I have a QMdiSubWindow window. Some child QDialogs and QMessageBox are appeared during the application execution. I need a function that will close all childs of QMdiSubWindow. For example, if a user is idle for 5 minutes the window should be closed.

I write the following:

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
while(true)
	{
    	qApp->processEvents();
    	QWidget * w = qApp->activeWindow();
    	if(w == NULL) continue;

    	if(w == this)
    	{
        	// delete widget
        	return;
    	}
    	if(dynamic_cast<QMessageBox *>(w))
    	{
        	QKeyEvent * e = new QKeyEvent(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier);
        	qApp->sendEvent(w, e);
        	delete e;
        	qApp->processEvents();
    	}
    	else
    	{
        	QCloseEvent * e = new QCloseEvent();
        	qApp->sendEvent(w, e);
        	delete e;
        	qApp->processEvents();
    	}
	}


The function works, but Is this a right solution?

This post has been edited 1 times, last edit by "carpovpv" (Dec 10th 2011, 4:20pm)


2

Saturday, December 10th 2011, 3:43pm

no, that is definitely not a right solution. There is no way to know that the active window is spawned from the midi window.

all the windows/dialogs that are opened from the QMdiSubWindow that should close on some event (e.g. idle for 5 mins), should be registered with a manager class.

the manager class should look out for the event, and the close all of the windows when the event is triggered.
If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

carpovpv

Beginner

  • "carpovpv" is male
  • "carpovpv" started this thread

Posts: 13

Location: Moscow

Occupation: teacher

  • Send private message

3

Saturday, December 10th 2011, 4:19pm

Sorry, I ve mistaken in describing my situation.

I have a QMdiSubWindow widget. A user works with it and sometimes launches a QDialog that is the child from this QMdiSubWindow. This QDialog starts the transaction on the server. And the task is to close this dialog and the transaction after sime idle time.

This QDialog and all other QDialogs (childs from this one) are modal, so in my case all active windows to be closed are really active windows.

The manager class is of course the best solution. But I don't understand how to use it. The first QDialog has its own eventFilter which deterimes the idle time. Then I have to close all child windows. Even if I emit a signal, for example, for all child dialogs I can't do this for QMessageBoxes. There may be a number of child QDialogs in the first QDialog.

4

Saturday, December 10th 2011, 4:51pm

why cant you emit signals for qmessagebox?

To implement a monitor and close solution with a manager, you should create an interface for all of your widgets that should be closeable:

Source code

1
2
3
4
5
6
7
8
9
10
class IIdleCloseable
{
  public:
  IIdleCloseable(IdleCloseableManager* mgr) // this is bad design because the 'child' should be manager agnostic, but ignoring that for the moment...
  {
    mgr->Register(this);
  }

  virtual void CloseOnIdle() = 0;
};

and a manager:

Source code

1
2
3
4
5
6
7
8
9
10
11
class IdleCloseableManager
{
  public:
  void Register(IIdleCloseable* closeable ); // keep a pointer to all the closeable windows

private:
  void closeAll()
  {
    // foreach IIdleCloseable*, call IIdleCloseable->CloseOnIdle();
  }
};


you would need to put your idle time calculation into the manager.
If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

carpovpv

Beginner

  • "carpovpv" is male
  • "carpovpv" started this thread

Posts: 13

Location: Moscow

Occupation: teacher

  • Send private message

5

Saturday, December 10th 2011, 5:36pm

About messagebox.... I have about 50 messagebox in those dialogs each of them are simply static functions like QMessageBox::warning... I don't know how to send them a signal without changing the current code.

But in future I' ll use Manager for such problems. By the way is this Observer pattern?

Thank you for fruitful discussion!

6

Saturday, December 10th 2011, 5:50pm

yes, it's a really simple observer.

QMessagebox static are just convenience calls that make a QMessagebox - so just replace the statics with equivalent instantiations. You'll have to subclass the messagebox and the dialogs anyway (to use the interface I gave above) unless you want to start messing with function pointers and callbacks.

For your needs, I guess you could get away without the interface if you want to be more hacky:

-make the register function void Register(QWidget*)
-get rid of all static calls to messagebox because you will need an instance pointer to pass to Register
-in the manager, call close() on the registered widgets instead of CloseOnIdle()


-to be proper, the manager should connect the destroyed() signal of the widgets to some slot in the manager ('Unregister' would be sensible) so that it could remove the widget from the observers list
If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

This post has been edited 1 times, last edit by "Amleto" (Dec 10th 2011, 5:58pm)


carpovpv

Beginner

  • "carpovpv" is male
  • "carpovpv" started this thread

Posts: 13

Location: Moscow

Occupation: teacher

  • Send private message

7

Saturday, December 10th 2011, 6:22pm

Thank you!