QDockWidgets disappear



  • I have 3 QDockWidgets layered top/middle/bottom in a QMainWindow with no central widget. Each QDockWidget is the width of the window. When I maximize the window and then drag the top of the bottom pane down any amount, the middle pane disappears (i.e. the top pane extends all the way down to the top of the bottom pane and the middle pane is completely hidden). When the top of the bottom pane is dragged back to or above its original position the middle pane reappears. The same effect occurs if I drag the bottom of the top pane up any amount.

    This happens on both Win7 and Linux Mint. I'm using Qt 4.8.1.

    Adding a central widget fixes it. Adding widgets to the QDockWidgets does not.

    Here's the code:

    @#include "stdafx.h"
    #include "Includes.h"

    enum EPane {
    PANE_TOP
    , PANE_MIDDLE
    , PANE_BOTTOM
    , COUNT_PANE
    };

    void InitMainWindow(QMainWindow* pMainWindow, QLabel* pLabel)
    {
    pMainWindow->show();
    pMainWindow->setWindowTitle("main window");
    pMainWindow->setDockNestingEnabled(true);

    // => no bug if this code runs
    //pMainWindow->setCentralWidget(pLabel);
    }

    void InitDockWidgets(QMainWindow* pMainWindow, QDockWidget* paDockWidget)
    {
    for (int i=0; i < COUNT_PANE; ++i)
    {
    QDockWidget* const p = paDockWidget + i;

    p->setParent(pMainWindow);
    p->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetVerticalTitleBar);
    p->setAutoFillBackground(true);
    p->activateWindow();
    }
    }

    void SetDockWidget(QMainWindow* pMainWindow, QDockWidget* p, Qt::DockWidgetArea dockArea, const char* pTitle, int iRed, int iGreen, int iBlue)
    {
    pMainWindow->addDockWidget(dockArea, p);

    p->setWindowTitle(pTitle);

    QPalette pal = p->palette();
    QColor color;
    pal.setBrush(QPalette::Window, color.fromRgb(iRed,iGreen,iBlue));
    p->setPalette(pal);

    p->show();
    }

    int main(int argc, char* argv[])
    {
    QApplication app(argc, argv);

    QMainWindow mainwin;
    QDockWidget aWidgets[COUNT_PANE];
    QLabel label;

    label.setText("hello, world");
    InitMainWindow(&mainwin, &label);
    InitDockWidgets(&mainwin, aWidgets);
    SetDockWidget(&mainwin, aWidgets + PANE_TOP, Qt::TopDockWidgetArea, "top", 128,255,255);
    SetDockWidget(&mainwin, aWidgets + PANE_MIDDLE, Qt::LeftDockWidgetArea, "middle", 255,128,128);
    SetDockWidget(&mainwin, aWidgets + PANE_BOTTOM, Qt::BottomDockWidgetArea, "bottom", 255,128,255);

    // => bug still happens if this code runs
    //QLabel aLabels[COUNT_PANE];
    //aLabels[PANE_TOP].setText("(top)");
    //aLabels[PANE_MIDDLE].setText("(middle)");
    //aLabels[PANE_BOTTOM].setText("(bottom)");
    //
    //for (int i=0; i<COUNT_PANE; ++i)
    // aWidgets[i].setWidget(aLabels + i);

    return app.exec();
    }
    @

    stdafx.h is an empty file on Linux.

    Includes.h looks like this on Win7:

    @#include "QApplication.h"
    #include "QWidget.h"
    #include "QMainWindow.h"
    #include "QDockWidget.h"
    #include "QLabel.h"
    @

    ...and like this on Linux:

    @#include <QApplication>
    #include <QWidget>
    #include <QMainWindow>
    #include <QDockWidget>
    #include <QLabel>
    @



  • From the docs:

    Creating a main window without a central widget is not supported. You must have a central widget even if it is just a placeholder.

    I guess we know why now ;)



  • I defined and hid the central widget...

    @ pMainWindow->setCentralWidget(pLabel);
    pMainWindow->centralWidget()->hide();
    @

    ...but the bug still happens. Maybe by "placeholder" they literally mean that it must occupy space.

    Here's someone who doesn't use a a central widget and has no problems. I'll ask them to try my case. http://stackoverflow.com/questions/3531031/qmainwindow-with-only-qdockwidgets-and-no-central-widget



  • I have a workaround, which is to do this after the last call to SetDockWidget:

    @ mainwin.splitDockWidget(aWidgets + PANE_TOP, aWidgets + PANE_MIDDLE, Qt::Vertical);
    @

    This works with both a hidden central widget and no central widget.



  • I think the problem here is that there is no "middle" docking position. Docked widgets are top/bottom or left/right, the "middle" position is actually occupied by the central widget. Docked widgets can be split 'within' themselves, for top/bottom widgets this is a horizontal split, for left/right widgets it's a vertical split. Looking at your code you're trying to achieve a vertical split using the top and bottom dock areas which only recognize horizontal splits and the absence of the central widget is confusing the left docked widget over where it should be.

    To get the vertical stacking effect you want try adding all three docked widgets to the left docked area (i.e. add them all as Qt::LeftDockWidgetArea).



  • Thanks, that does work and the bug doesn't occur.

    For more complicated layouts splitDockWidget really seems to do the trick. By splitting in the right order and with the right orientations you can achieve any relative layout you want with any number of QDockWidgets.

    The requirement for a central widget is interesting. Maybe it solves certain problems that can occur when all QDockWidgets are undocked. I'm not the only one who's trying to get around that requirement :)


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.