PDA

View Full Version : How to move QMdiSubWindow in and out of QMdiArea?



lni
5th October 2012, 10:57
Hi,

I try to implement QMdiSubWindow::moveEvent so that user can grab QMdiSubWindow and move it in and out of QMdiArea, much the same way as Google's chrome does.

However can I achieve that while QMdiArea::subWindowList still keeps the list even though the QMdiSubWindow is moved out?

Thanks

lni
12th October 2012, 11:07
Anyone please?

wysota
12th October 2012, 11:21
It is possible to detach the window by writing some code but the window will become a standalone window, it will not be in the list of mdi subwindows. You need to keep your own list of windows that includes both those attached to the mdi and those you have detached. I implemented something like that but it doesn't work by moving the window. Rather than that I have a button or keyboard shortcut for that. With chrome it is easy because to detach a window, you grab and pull its tab. With MDI you don't have such tabs (unless you're working in document mode).

Carlsberg
12th October 2012, 11:37
I think Google Chrome is different, every tab is a separate process if I'm not mistaken

lni
14th October 2012, 05:11
It appears to be easy but rather it is not.

I re-implement QMdiSubWindow::moveEvent ( QMoveEvent * event ), I did QMdiArea::removeSubWindow or QMdiArea::addSubWindow based on mouse inside or outside the QMdiArea. Then re-implement QMdiArea::childEvent to manage my own subwindow list, with subwindow's destroyed signal attached, it still won't work...

Without tab you can grab subwindow's title bar, so that is not an issue though...

wysota
14th October 2012, 08:42
it still won't work...
What doesn't work?


Without tab you can grab subwindow's title bar, so that is not an issue though...
The problem is not having anything to grab or not, it is detecting when to detach.

lni
15th October 2012, 08:56
What doesn't work?


The problem is not having anything to grab or not, it is detecting when to detach.

Please look at the attached codes and see if we can get something going together.

wysota
15th October 2012, 09:58
So what doesn't work?

lni
15th October 2012, 12:45
So what doesn't work?

Can't get QMdiSubWindow::focusInEvent after it is moved out. So I can't get signal QMdiArea::subWindowActivated ( QMdiSubWindow * )...

Any idea?

wysota
15th October 2012, 12:46
You won't get that event because there is no subwindow for the detached window.

lni
16th October 2012, 03:02
You won't get that event because there is no subwindow for the detached window.

I understand I won't get QMdiArea::subWindowActivated ( QMdiSubWindow * ) signal, but I should get QMdiSubWindow::focusInEvent because it belongs to QWidget?

wysota
16th October 2012, 04:10
Your widget is not a subclass of QMdiSubWindow. You will get a focusIn event for the widget itself, provided that the widget itself accepts focus.

lni
16th October 2012, 07:19
Your widget is not a subclass of QMdiSubWindow. You will get a focusIn event for the widget itself, provided that the widget itself accepts focus.

OK, it got too many problems, such as when I call QMdiArea::tileSubWindows or QMdiArea::cascadeSubWindows, the QMdiSubWindow::moveEvent got called and all the subwindows are detached from the QMdiArea.

So I decide to override QMdiSubWindow's system menu by adding "Detach from Work Area" and "Attach to Work Area". The "Detach from Work Area" is added correctly to the QMdiSubWindow's system menu. However, after it is detached, the window becomes a standalone window and the window manager's system menu is used. I lose those menu items that I have added...

Is there a way to solve this?

wysota
16th October 2012, 11:37
Is there a way to solve this?

The way I did it is that I wrapped every detachable widget in another object (call it Window or sth like that) that has an interface similar to QWidget and whenever I want to do something on my widget, I call it through this interface. This gives me a wrapper both when the window is in the MDI area (a.k.a. has a QMdiSubWindow instance) or not. Then I can assign a keyboard shortcut or a context menu handler to all widgets I want and attach the window from there.

lni
29th October 2012, 11:15
The way I did it is that I wrapped every detachable widget in another object (call it Window or sth like that) that has an interface similar to QWidget and whenever I want to do something on my widget, I call it through this interface. This gives me a wrapper both when the window is in the MDI area (a.k.a. has a QMdiSubWindow instance) or not. Then I can assign a keyboard shortcut or a context menu handler to all widgets I want and attach the window from there.

Could you show the codes? Thanks

wysota
29th October 2012, 11:27
Could you show the codes? Thanks

Unfortunately no, it's not open source.

ant32
31st May 2013, 01:20
this is what I did from the main window to pop out a window.

void MainWindow::on_action_Pop_Out_triggered()
{
if (ui->mdiArea->activeSubWindow()){
QMdiSubWindow *sub = ui->mdiArea->activeSubWindow();
QWidget *wid = sub->widget();
wid->hide();
sub->deleteLater();
ui->mdiArea->removeSubWindow(wid);
wid->show();
}
}