Question

Je viens de commencer à travailler sur un nouveau projet C ++ / QT. Ce sera un IDE basé sur MDI avec des widgets amarrés pour des choses comme l'arborescence de fichiers, le navigateur d'objet, la sortie du compilateur, etc. Une chose me dérange jusqu'à présent: je ne peux pas comprendre comment faire par programme QDockWidget plus petit. Par exemple, cet extrait crée ma fenêtre de quai inférieure, "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);

Lorsqu'il est lancé, mon programme ressemble à ceci (gardez à l'esprit le stade précoce du développement):

Actual

Cependant, je veux que cela apparaisse comme ceci:

Expected

Je n'arrive pas à faire arriver cela. La référence QT sur QDockWidget dit ceci:

Des conseils de taille personnalisés, des tailles minimales et maximales et des politiques de taille doivent être mises en œuvre dans le widget enfant. QDockWidget les respectera, ajustant ses propres contraintes pour inclure le cadre et le titre. Les contraintes de taille ne doivent pas être définies sur le QDockWidget lui-même, car ils changent selon qu'il est amarré

Maintenant, cela suggère qu'une méthode pour faire cela serait de sous-classe QTextEdit et remplacer le sizeHint() méthode. Cependant, je préférerais ne pas le faire juste à cette fin, et je ne l'ai pas essayé de trouver que c'est une solution de travail.

J'ai essayé d'appeler dock->resize(m_compilerOutput->width(), m_compilerOutput->minimumHeight()), appelant m_compilerOutput->setSizePolicy() Avec chacune de ses options ... rien jusqu'à présent n'a affecté la taille. Comme je l'ai dit, je préférerais une solution simple en quelques lignes de code pour avoir à créer un sous-classe juste pour changer sizeHint(). Toutes les suggestions sont appréciées.

Était-ce utile?

La solution

Je viens de passer par ce même processus. Après avoir essayé beaucoup trop de permutations de resize(), adjustSize() et des amis sur les widgets de quai et leur widget contenu, dont aucun a fonctionné, j'ai fini par sous-classe QListView et ajoutant que sizeHint() méthode.

Maintenant, cela fonctionne comme un charme.

Autres conseils

J'ai rendu les choses faciles: en tête:

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

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

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.

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)

Have you tried calling resize() on the QTextEdit inside your dock widget? You could also try temporarily setting the dock widget's maximum & minimum sizes to the size you want it to be, then restore the original values.

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.

Tests using resize on the QDockWidget::widget() (i.e. the widget that the QDockWidget is managing) do not consistently work as expected.

With a QDockWidget subclass (DW) in which a QWidget with a QHBoxLayout that has two widgets (left-panel and right-panel) added, all of which have had their size policies set to QSizePolicy::Minimum, the DW normally has both panel widgets visible. When the DW is positioned in a side dock an application (QMainWindow) slot handling the DW's dockLocationChanged signal hides left-panel and re-sizes the DW->widget() to the size right-panel. When the DW is programmatically moved to the bottom dock area leftPanel is set visible and the DW fills the full width of the main window (of course). When the DW is then programmatically moved to a side dock area the left-panel is hidden and the DW is re-sized down. This works as intended. However, if the DW is dragged from the bottom dock area to a side dock area, though the left-panel is hidden and the re-size applied as before, the DW is not re-sized down as when the repositioning is done programatically. The DW can be manually re-sized down by dragging the splitter handele between the DW and main window central area. Note that the main window central area is a QWidget having a QHBoxLayout with size polices QSizePolicy::Expanding.

Calling adjustSize on the main window after the DW has been re-sized has no effect. This despite the DW having reimplemented sizeHint to return its minimum size depending on whether left-panel is visible or not.

Either I am missing something in how to control the size of QDockWidget (which, given the difficulty I've had understanding all the interactions amongst the parts of the layout management system, is quite likely), or the QMainWindow is ignoring or overriding the layout instructions that it is being given. Closely examining the event stream during the QDockWidget repositioning operations suggests the latter: After the slot handling the dockLocationChanged signal has done its resizing work and returned to the event loop I can see that the QMainWindow, when user repositioning is done, applies additional re-size operations on the affected QDockWidget thus undoing the application logic that attempts to control the dock size. Something seems amiss in the QMainWindow ....

If the dockWidgets are docked, the sizes are control by their parent. In such cases you can use the QMainWindow::resizeDocks function.

If floating, sizes are determined by their children.Resize children to achieve your purpose.

The resize of dock widgets problem when MainWindow is maximized is described in QTBUG-16252 (https://bugreports.qt.io/browse/QTBUG-16252)

I've found another workaround on it. Works for me on QT 5.4.1 minGW on Windows7. It looks like some widget state restore operations are closely related to QApplication event loop.

DockWidget sizes are restored correctly ONLY when following conditions are met:

  1. restoreGeometry() is called BEFORE entering QApplication::exec() (e.g. in constructor of your MainWindow class)

  2. restoreState() is called AFTER exec() (e.g. via QTimer)

Here is my code:

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

    //...

    MainWindow mainWindow;
    mainWindow.show();

    return application.exec();
}

MainWindow::MainWindow(...) 
{
    ui->setupUi(this);

    //...
    QTimer* nt = new QTimer(this);

    nt->setSingleShot(true);
    nt->setInterval( 100 );

    connect(nt, SIGNAL(timeout()), SLOT(restoreWidgetSettings()));
    nt->connect(nt, SIGNAL(timeout()), SLOT(deleteLater()));

    nt->start();

    restoreWidgetSettings(true);
}

void MainWindow::restoreWidgetSettings(bool geometryOnly) {

    //...
    QByteArray geometry = getSettings();

    restoreGeometry(geometry);

    if(geometryOnly)
        return;

    //... //create dock widgets here

    restoreState(mainWindowState);

}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top