Как сделать, чтобы QDockWidget отображался на панели задач?

Я использую подкласс QDockWidget с небольшой хитростью. Сигнал "topLevelChanged" подключен к этому слоту члена:

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();
    }
}

Это хорошо работает (по крайней мере, в Windows, которая является моей целью) и отображает кнопку «развернуть» в строке заголовка.

Теперь я хочу, чтобы виджет док-станции вел себя как виджет «верхнего уровня»: не всегда поверх главного окна и появляется на панели задач.

Я пытался:

  • изменить виджет док-станции на NULL, когда он отсоединен от главного окна
  • изменить виджет док-станции на предыдущий родитель, когда он повторно прикреплен к главному окну

Но есть еще некоторые проблемы: пользователь больше не может использовать перетаскивание, чтобы повторно прикрепить док к главному окну.

Я думаю, это потому, что родитель имеет значение NULL, поэтому виджет док-станции не знает, куда он должен повторно прикрепляться при перетаскивании.

Есть ли способ добиться желаемого поведения (виджет док-станции не всегда находится сверху и отображается на панели задач) без повторной привязки его к NULL? Игра с некоторыми флагами?

Или в любом случае виджет док-станции должен вести себя правильно, когда его родитель имеет значение NULL?

Спасибо


person Aurelien    schedule 22.06.2017    source источник


Ответы (2)


Вы можете установить стиль Windows EX 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
person KungPhoo    schedule 31.01.2019
comment
Можно ли это сделать в PyQt5? - person locke14; 21.10.2019
comment
Используйте Windows API. Он должен работать при включении: - person KungPhoo; 23.10.2019

По крайней мере, для Linux (Mint/Cinnamon) и Qt 5.15 есть решение, которое удовлетворяет большинству требований и даже выглядит переносимым.

Как и выше, подключите сигнал topLevelChanged вашего QDockWidget к слоту:

void MyClass::dockSetWinFlags(bool detached)
{
    if (detached) {
         dock->setWindowFlags(Qt::CustomizeWindowHint |
                        Qt::Window | 
                        Qt::WindowMinimizeButtonHint |
                        Qt::WindowMaximizeButtonHint |
                        Qt::WindowCloseButtonHint);
         dock->show();
     }
} 

Важным отличием является флаг Qt::Window вместо Qt::Dialog. Теперь док-станция становится полноценным верхним окном с заголовком и кнопками Min/Max/Close, поэтому она больше не остается поверх главного окна и также отображается на панели задач рабочего стола.

Единственное, что не работает, это перетаскивание обратно в главное окно, но альтернативный метод — нажатие на плавающую кнопку — все еще работает.

person kybos    schedule 13.08.2020