21

We have a window with several components in QDockWidgets. Ideally, we'd like to have all components dockable, but there is one component that will likely always be visible. So we made that the central widget.

However, this does not allow us to create a tabbed stack of dockable widgets (as you can create by e.g. calling tabifyDockWidget) containing this central widget. So, we tried to create a UI without a central widget, but with several QDockWidgets.

I cannot find any indication in the manual of QDockWidget or QMainWindow that this is a situation that isn't allowed. We create as much as possible in Qt Designer, and it seems to require that you have a central widget - as it shows by crashing after manually editing the XML.

The question is: is it legal to have a QMainWindow with only QDockWidgets and no central widget? Is Qt Designer just crashing because of a bug, or is it telling me that this is a bad idea and I need to stop doing this?

Ivo
  • 3,481
  • 1
  • 25
  • 29

7 Answers7

15

Qt's documentation says that:

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

So you can just hide the empty central widget:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->centralWidget->hide();
}
b8adamson
  • 317
  • 3
  • 6
10

Well it works for me if I type this after "ui->setupUi(this)" generated line.

MainWindow::setCentralWidget(NULL);

If it's "legal" I don't know, but I do know it works well for me.

(and I know this is an old question but still valid :) )

Nikhil
  • 16,194
  • 20
  • 64
  • 81
someone
  • 101
  • 1
  • 3
  • It works! Beware though, I had some strange bug: If I say that the bottom right corner is used by the bottom dock and I add some bottom dock, then resizing between the right docks and the bottom docks does not work anymore sometimes. However, in this particular case, bottom dock == right dock and resizing works if I use the right dock instead of the bottom dock. So, the behavior changes without the central widget. The same effect occurs if I add a central widget but `hide` it, by the way. – IceFire Oct 17 '16 at 16:26
3

Nonsense! I have a fully functional QMainWindow with only QDockWidgets and no central widget. I don't know how "legal" it is but it is deffinatley possible if you create it outside of QtDesigner which is easy enough.

Example

from PyQt4 import QtCore, QtGui

class Window(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        self.setWindowTitle('Dock Widgets')
        self.setTabPosition( QtCore.Qt.TopDockWidgetArea , QtGui.QTabWidget.North )
        self.setDockOptions( QtGui.QMainWindow.ForceTabbedDocks )

        self.dockList = []
        for dockName in 'First Second Third Fourth'.split():
            dock = QtGui.QDockWidget(dockName)
            dock.setWidget(QtGui.QListWidget())
            dock.setAllowedAreas(QtCore.Qt.TopDockWidgetArea)
            self.addDockWidget(QtCore.Qt.TopDockWidgetArea, dock)

            self.dockList.append( dock )


        if len(self.dockList) > 1:
            for index in range(0, len(self.dockList) - 1):
                self.tabifyDockWidget(self.dockList[index],self.dockList[index + 1])



if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.show()
    app.exec_()
Jay
  • 3,373
  • 6
  • 38
  • 55
1

I faced this problem with pyside (QT for python). I just needed the docks, so I had to create a fake widget (i.e. a label) to put as central. However, as soon as I hide it, the docks could not be freely resized anymore. The same happened if I put None/null as central widget.

After lots of unproductive searching on the Internet, I figured out that the problem was with the initial setup of the dock locations (top/bottom/left/right). If I put them all in the same position (i.e. top) letting the user to organize it, the problem doesn't manifest. Then I tried to only use the top and bottom positions (since it was possible for me to organize the docks the way I wanted without using the lateral positions (two in the top and one in the bottom). To my surprise, with this arrangement the problem is finally solved.

Adriel Jr
  • 2,451
  • 19
  • 25
0

I've faced the same problem and I hoped there is already some nice solution for it.

It seems not, so eventually I think I'll use MdiArea.

Maybe you can consider it also? It works in different way but maybe it is nice enought :)

Michał Walenciak
  • 4,257
  • 4
  • 33
  • 61
  • I did. They are only workarounds. You still cannot have dockable central widget. You may use one of the docks as central but it causes you to loose this dock (for example if you use top dock for your central widget, you cannot dock anything over it). – Michał Walenciak Oct 12 '14 at 13:18
  • They are workarounds that work very well. One cannot 'detect' that there is a central widget with the workaround. – dom0 Oct 12 '14 at 13:58
  • If I understand you correctly, you want to say it's impossible to find out if there is central widget or not? It's very simple. – Michał Walenciak Oct 12 '14 at 19:38
  • 1
    Not from a users' perspective. Besides I never quite understood the people wanting a dock as a central widget. That doesn't make a lot of sense from a semantics perspective. (I do very well understand people that want a window consisting only of some docks and I used that, too). – dom0 Oct 12 '14 at 20:16
  • even from user's perspective: central widget never allows to drop any dockable widget on it and runs away. Also you cannot move central widget. – Michał Walenciak Oct 12 '14 at 20:32
  • I think you didn't understand how the workaround works. With the workaround the central widget has a) geometry 0×0 b) is invisible. – dom0 Oct 12 '14 at 22:09
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/62954/discussion-between-michal-walenciak-and-dom0). – Michał Walenciak Oct 13 '14 at 07:53
0

There is a Solution! This is still a hack, though works as the best way you want.

for python

window.setCentralWidget(None)
window.setDockNestingEnabled(True)

for c++

window->setCentralWidget(NULL)
window->setDockNestingEnabled(true)
0

I am going to post my solution based on this thread and splitDockWidget here, as this 12 year old question is still one of the top results when looking for the issue. The key to avoid weird behavior when resizing docks is to only use a single dockarea. Using splitDockWidget allows to create any desired arrangement of docks.

import sys
from PyQt6.QtWidgets import QApplication,QMainWindow,QDockWidget
from PyQt6.QtCore import Qt

class Foo(QMainWindow):

    def __init__(self):
        super().__init__()
        self.resize(500, 500)         
        
        td = QDockWidget('topdock')
        ld = QDockWidget('leftdock')
        rd = QDockWidget('rightdock')
        rd2 = QDockWidget('rightdock2')
        bd = QDockWidget('bottomdock')            
        self.addDockWidget(Qt.DockWidgetArea.TopDockWidgetArea,td)
        self.splitDockWidget(td,ld,Qt.Orientation.Vertical)
        self.splitDockWidget(ld,bd,Qt.Orientation.Vertical)
        self.splitDockWidget(ld,rd,Qt.Orientation.Horizontal)   
        self.splitDockWidget(rd,rd2,Qt.Orientation.Vertical)   
            
if __name__ == '__main__':
    app = QApplication(sys.argv)
    mainWindow = Foo()
    mainWindow.show()
    sys.exit(app.exec())
dukeeloo
  • 161
  • 7