C++ resize a docked Qt QDockWidget programmatically?

30,297

Solution 1

I just went through this same process. After trying far too many permutations of resize(), adjustSize() and friends on dock widgets and their contained widget, none of which worked, I ended up subclassing QListView and adding that sizeHint() method.

Now it works like a charm.

Solution 2

I made it easy: HEADER:

private void setDockSize(QDockWidget *dock, int, int);
  public slots:
  void returnToOldMaxMinSizes();

SOURCE:

QSize oldMaxSize, oldMinSize;

void MainWindow::setDockSize(QDockWidget* dock, int setWidth,int setHeight)
{

    oldMaxSize=dock->maximumSize();
    oldMinSize=dock->minimumSize();

  if (setWidth>=0)
    if (dock->width()<setWidth)
        dock->setMinimumWidth(setWidth);
    else dock->setMaximumWidth(setWidth);
  if (setHeight>=0)
    if (dock->height()<setHeight)
        dock->setMinimumHeight(setHeight);
    else dock->setMaximumHeight(setHeight);

    QTimer::singleShot(1, this, SLOT(returnToOldMaxMinSizes()));
}

void MainWindow::returnToOldMaxMinSizes()
{
    ui->dockWidget->setMinimumSize(oldMinSize);
    ui->dockWidget->setMaximumSize(oldMaxSize);
}

Solution 3

This is an old question, but I wanted to chime in to mention that Qt 5.6 introduced the QMainWindow::resizeDocks function to handle this.

Unfortunately, it doesn't work for my use case (moving separator between two QDockWidgets that have been split with QMainWindows::splitDockWidget)

Solution 4

It sounds like the dock widget re-sizes itself to the proper size, considering its child widget. From the QDockWidget documentation (emphasis mine):

A QDockWidget acts as a wrapper for its child widget, set with setWidget(). Custom size hints, minimum and maximum sizes and size policies should be implemented in the child widget. QDockWidget will respect them, adjusting its own constraints to include the frame and title. Size constraints should not be set on the QDockWidget itself, because they change depending on wether it is docked; a docked QDockWidget has no frame and a smaller title bar.

In order to change the size, then, you must re-size the child widget.

EDIT: The Qt documentation can sometimes be misleading when it discusses size hints. Often, it's referring to any kind of resizing, whether performed automatically by the widget or programatically.

Solution 5

You could do this:

Set a maximum height for your QTextEdit:

m_compilerOutput = new QTextEdit;
m_compilerOutput->setMaximumHeight(100);

And then in the show event of your main window set it back to the old size or something high:

void MainWindow::showEvent(QShowEvent *)
{
   m_compilerOutput->setMaximumHeight(10000);
}

That is all you should need.

Share:
30,297

Related videos on Youtube

Siddique Vichi
Author by

Siddique Vichi

Updated on July 09, 2022

Comments

  • Siddique Vichi
    Siddique Vichi almost 2 years

    I've just started working on a new C++/Qt project. It's going to be an MDI-based IDE with docked widgets for things like the file tree, object browser, compiler output, etc. One thing is bugging me so far though: I can't figure out how to programmatically make a QDockWidget smaller. For example, this snippet creates my bottom dock window, "Build Information":

    m_compilerOutput = new QTextEdit;
    m_compilerOutput->setReadOnly(true);
    dock = new QDockWidget(tr("Build Information"), this);
    dock->setWidget(m_compilerOutput);
    addDockWidget(Qt::BottomDockWidgetArea, dock);
    

    When launched, my program looks like this (bear in mind the early stage of development):

    Actual

    However, I want it to appear like this:

    Expected

    I can't seem to get this to happen. The Qt Reference on QDockWidget says this:

    Custom size hints, minimum and maximum sizes and size policies should be implemented in the child widget. QDockWidget will respect them, adjusting its own constraints to include the frame and title. Size constraints should not be set on the QDockWidget itself, because they change depending on whether it is docked

    Now, this suggests that one method of going about doing this would be to sub-class QTextEdit and override the sizeHint() method. However, I would prefer not to do this just for that purpose, nor have I tried it to find that to be a working solution.

    I have tried calling dock->resize(m_compilerOutput->width(), m_compilerOutput->minimumHeight()), calling m_compilerOutput->setSizePolicy() with each of its options... Nothing so far has affected the size. Like I said, I would prefer a simple solution in a few lines of code to having to create a sub-class just to change sizeHint(). All suggestions are appreciated.

  • McLeary
    McLeary almost 11 years
    One can replace the QTimer::singleShot call to a qApp->processEvents(). Works the same way. Even this being a nasty hack it was the only way I found to resize a docked widget in Qt.
  • TheTrowser
    TheTrowser over 7 years
    shouldn't it work as in python: create a new Qwidget and call dock.setWidget([your new Widget]). That way, you could handle it, as in this example: stackoverflow.com/questions/19760583/… ? That way, you would only override QWidget once and it will work for every case
  • AshkanVZ
    AshkanVZ almost 6 years
    You are correct, Setting the maximum and minimum width/height of the dock is enough. Also we can reimplement the "resizeEvent" of the QMainWindow and set these two values in that event, to have a dynamic sizing of the QDockWidget.
  • titusjan
    titusjan over 2 years
    If I understand your response to the answer to your use case correctly, it does work as long as you call resizeDocks after calling QMainWindow::show()