Reputation: 1092
I use a subclass of QDockWidget with a little trick. The "topLevelChanged" signal is connected to this member slot :
void MyDockWidget::updateWindowFlags(bool topLevel)
{
if (topLevel == true)
{
setWindowFlags(Qt::Dialog|Qt::CustomizeWindowHint|Qt::WindowTitleHint|Qt::WindowMaximizeButtonHint|Qt::WindowCloseButtonHint);
// "setWindowFlags" hides the widget, show it again
show();
}
}
This works well (at least on Windows, which is my target) and display a "maximize" button in the title bar.
Now I want to make the dock widget behave like a "top level" widget : not always on top of the main window and appears in taskbar.
I've tried to :
But there is still some problems : the user can't use drag'n'drop anymore to re-attach the dock to the main window.
I think this is because the parent is NULL, so the dock widget doesn't know where it should re-attach on drag'n'drop.
Is there any way to have the desired behaviour (dock widget not always on top and appears in task bar) without re-parenting it to NULL ? Playing with some flags ?
Or is there anyway to have the dock widget to behave properly when its parent is set to NULL ?
Thanks
Upvotes: 1
Views: 1288
Reputation: 21
At least with Linux (Mint/Cinnamon) and Qt 5.15 there is a solution that covers most of the requirements and it even looks portable.
Like you did above, connect your QDockWidget's "topLevelChanged" signal to the slot:
void MyClass::dockSetWinFlags(bool detached)
{
if (detached) {
dock->setWindowFlags(Qt::CustomizeWindowHint |
Qt::Window |
Qt::WindowMinimizeButtonHint |
Qt::WindowMaximizeButtonHint |
Qt::WindowCloseButtonHint);
dock->show();
}
}
The important difference is the Qt::Window flag instead of Qt::Dialog. Now the dock becomes a full top window with a title bar and the Min/Max/Close buttons, so it does not stay on top of the main window anymore and is also shown in the desktop taskbar.
The only thing that does not work is drag'n'drop back to the main window, but the alternative method - clicking on the "float" button - still works.
Upvotes: 0
Reputation: 802
You can set the windows EX style WS_EX_APPWINDOW:
#ifdef Q_OS_WIN32
#include "qt_windows.h"
#ifdef _MSC_VER
#pragma comment(lib,"user32.lib")
#endif
// MinGW: add >>LIBS += -lUser32<< to .pro file.
void makeWidgetApearInWindowsTaskbar(QWidget* widget) {
HWND id = HWND(widget->winId());
::ShowWindow(id, SW_HIDE);
::SetWindowLong(id, GWL_EXSTYLE, GetWindowLong(id, GWL_EXSTYLE) | WS_EX_APPWINDOW);
::ShowWindow(id, SW_SHOW);
}
#endif
Upvotes: 1