C++ redimensionner un qdockwidget docké programmatiquement?

je viens de commencer à travailler sur un nouveau projet C++/Qt. Ce sera un IDE basé sur MDI avec des widgets dockés pour des choses comme l'arborescence de fichiers, le navigateur d'objets, la sortie du compilateur, etc. Une chose me tracasse jusqu'à présent: je ne sais pas comment programmer un QDockWidget plus petit. Par exemple, cet extrait crée ma fenêtre de dock du bas, "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);

lors de son lancement, mon programme ressemble à ceci (gardez à l'esprit le stade précoce de de développement):

Actual

Cependant, je veux qu'il apparaisse comme ceci:

Expected

Je n'arrive pas à y arriver. La référence Qt sur QDockWidget dit ceci:

conseils de taille personnalisés, tailles minimum et maximum et les politiques de taille doivent être mis 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 elles changent selon qu'il est amarré ou non.

maintenant, cela suggère qu'une méthode pour faire cela serait de sous-classe QTextEdit et de remplacer la méthode sizeHint() . Toutefois, je préférerais ne pas le faire uniquement dans ce but, et je n'ai pas non plus essayé de trouver une solution qui fonctionne.

j'ai essayé appelant 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 dans quelques lignes de code à avoir à créer une sous-classe juste pour changer sizeHint() . Toutes les suggestions sont appréciées.

25
demandé sur Kos 2010-04-27 20:18:27
la source

9 ответов

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 dock et leur widget contenu, dont aucun n'a fonctionné, j'ai fini par sous-classer QListView et en ajoutant que sizeHint() méthode.

maintenant ça marche comme un charme.

4
répondu Charl Botha 2013-05-22 18:38:48
la source

j'ai rendu ça facile: En-tête:

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);
}
7
répondu semenvx 2012-03-25 21:04:34
la source

il sonne comme le widget dock se re-tailles à la bonne taille, compte tenu de son widget enfant. De la documentation QDockWidget (mine d'emphase):

un QDockWidget agit comme un wrapper pour son widget enfant, défini avec setWidget(). Des conseils de taille personnalisés, des tailles minimum et maximum et des politiques de taille devraient être mis 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 elles changent selon qu'il est amarré ou non; un QDockWidget amarré n'a pas de cadre et une barre de titre plus petite.

afin de changer la taille, puis, vous devez re-taille le widget enfant.

modifier: la documentation Qt peut parfois être trompeuse quand elle discute des indices de taille. Souvent, il est fait référence à tout type de redimensionnement, qu'il soit effectué automatiquement par le widget ou programatically.

6
répondu TreDubZedd 2010-05-07 03:25:34
la source

C'est une vieille question, mais je voulais faire remarquer que Qt 5.6 a introduit la fonction QMainWindow::resizeDocks pour gérer cela.

malheureusement, cela ne fonctionne pas pour my use case (séparateur mobile entre deux QDockWidgets qui ont été séparés avec QMainWindows::splitDockWidget)

4
répondu Alex Goldberg 2017-05-23 14:46:50
la source

avez-vous essayé d'appeler resize() sur le QTextEdit dans votre widget dock? Vous pouvez également essayer de définir temporairement les tailles maximum et minimum du widget dock à la taille que vous voulez qu'il soit, puis restaurer les valeurs originales.

2
répondu Kitsune 2010-05-02 05:50:25
la source

Vous pourriez faire ceci:

fixez une hauteur maximale pour votre QTextEdit :

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

puis dans le spectacle de votre fenêtre principale de revenir à l'ancienne taille ou de quelque chose de haut:

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

C'est tout ce dont vous avez besoin.

2
répondu thuga 2013-05-23 11:06:46
la source
Les Tests

utilisant resize sur le QDockWidget::widget() (c'est-à-dire le widget que le QDockWidget gère) ne fonctionnent pas toujours comme prévu.

avec une QDockWidget sous-classe (DW) dans laquelle a été ajouté un QWidget avec un QHBoxLayout qui a deux widgets ( panneau gauche et panneau droit ), tous ayant leurs politiques de taille réglées à QSizePolicy::Minimum , le DW A Normalement les deux widgets de panneau visibles. Lorsque le DW est placé dans un quai latéral application ( QMainWindow ) la fente manipulant le signal dockLocationChanged du DW cache le panneau de gauche et redimensionne le DW->widget() au panneau de droite. Lorsque le DW est déplacé de façon programmatique vers la partie inférieure du dock, le panneau gauche est mis visible et le DW remplit toute la largeur de la fenêtre principale (bien sûr). Lorsque le DW est ensuite déplacé de façon programmatique vers un quai latéral, le panneau gauche est caché et le DW est redimensionné vers le bas. Cela fonctionne comme prévu. Toutefois, si le bateau est traîné de la zone du quai de fond à une zone de quai latéral, bien que le panneau gauche soit caché et que la nouvelle taille soit appliquée comme auparavant, le DW n'est pas redimensionné comme lorsque le repositionnement est fait de façon programmatique. Le DW peut être redimensionné manuellement en faisant glisser le handele splitter entre le DW et la zone centrale de la fenêtre principale. Notez que la zone centrale de la fenêtre principale est un QWidget ayant un QHBoxLayout avec des politiques de taille QSizePolicy::Expanding .

appelant adjustSize sur la fenêtre principale après que le DW a été redimensionné a pas d'effet. Ceci malgré le fait que le DW ait réimposé sizeHint pour rendre sa taille minimale selon que le panneau gauche est visible ou non.

soit je manque quelque chose dans la façon de contrôler la taille de QDockWidget (qui, étant donné la difficulté que j'ai eu à comprendre toutes les interactions entre les parties du système de gestion de la configuration, est très probable), soit le QMainWindow ignore ou dépasse les instructions de mise en page qu'il est donné. Étroitement l'examen du flux d'événements durant les opérations de repositionnement du QDockWidget suggère cette dernière: après que le slot manipulant le signal dockLocationChanged a fait son travail de redimensionnement et est retourné à la boucle d'événements , je peux voir que le QMainWindow , quand le repositionnement de l'utilisateur est fait, applique des opérations supplémentaires de redimensionnement sur le QDockWidget affecté, annulant ainsi la logique d'application qui tente de contrôler la taille du quai. Quelque chose ne va pas dans le QMainWindow ....

1
répondu user674263 2012-03-26 14:19:02
la source

le problème de redimensionnement des widgets de quai lorsque la puissance est maximisée est décrit dans QTBUG-16252 ( https://bugreports.qt.io/browse/QTBUG-16252 )

j'ai trouvé une autre solution. Travaille pour moi sur QT 5.4.1 minGW sur Windows7. Il semble que certaines opérations de restauration de l'état du widget soient étroitement liées à la boucle d'événement QApplication.

Les dimensions des DockWidget

ne sont restaurées correctement que lorsque les conditions suivantes sont remplies:

  1. restoreGeometry() est appelé avant d'entrer QApplication::exec() (e.g. in constructor of your MainWindow class)

  2. restoreState() est appelé après exec() (par exemple via QTimer)

Voici mon 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);

}
0
répondu vrogach 2015-05-15 12:40:16
la source

si les dockWidgets sont amarrés, les tailles sont contrôlées par leur parent. Dans de tels cas, vous pouvez utiliser la fonction QMainWindow::resizeDocks .

si flottant, les tailles sont déterminées par leurs enfants. Redimensionner les enfants pour atteindre votre but.

0
répondu momo 2017-04-28 10:22:42
la source

Autres questions sur