IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Qt Discussion :

Comment resizer un widget central indépendamment de la taille des widgets adjacents ?


Sujet :

Qt

  1. #1
    Nouveau membre du Club
    Profil pro
    dev
    Inscrit en
    Avril 2010
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : dev

    Informations forums :
    Inscription : Avril 2010
    Messages : 53
    Points : 25
    Points
    25
    Par défaut Comment resizer un widget central indépendamment de la taille des widgets adjacents ?
    Bonjour,

    J'ai une appli dans le style de Qt Main Window demo (demos/mainwindow/), c'est-à-dire que j'ai un widget central dans lequel je réalise un rendu 3D et j'ai d'autre widget dockable me servant entre autre au paramétrage de mon appli.

    Après chargement d'une scène, je voudrais pouvoir passer mon widget central dans la bonne résolution 1024x768 par exemple sans forcément passer par de nombreux calculs du style taille de la fenêtre principale - taille des fenêtres dockables présentes.

    En faisant par exemple un setResolution(1024, 768), je voudrais avoir la taille de mon widget ajusté en gardant la taille des widgets dockables intacts.
    Comme le résultat de cette opération voit la taille de la fenêtre principale modifiée, je crains qu'il ne soit pas possible de faire ça indépendamment de la taille des autres fenêtres.

    Pour l'instant, j'ai réussi à resizer le widget central en 1024x768 mais au détriment des widgets dockables qui sont diminués de taille alors que celle de la fenêtre principale reste inchangée.

    J'ai bon espoir dans les capacités de Qt pour réaliser ça de manière simple mais là je sèche

  2. #2
    Membre éprouvé

    Profil pro
    Inscrit en
    Mai 2007
    Messages
    774
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Mai 2007
    Messages : 774
    Points : 969
    Points
    969
    Par défaut
    Salut,

    un QWidget::resize(w,h) tout simple fait ce que tu veux non ?

    G.
    Un problème avec Qt ? Vous trouverez votre réponse ici : http://doc.trolltech.com/4.6/overviews.html
    En français (traduction réalisée par l'équipe Qt de DVP) : http://qt.developpez.com/doc/4.6/vues-d-ensemble/

  3. #3
    Nouveau membre du Club
    Profil pro
    dev
    Inscrit en
    Avril 2010
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : dev

    Informations forums :
    Inscription : Avril 2010
    Messages : 53
    Points : 25
    Points
    25
    Par défaut
    Et bien non justement cela ne fonctionne pas.
    Car le widget que je souhaite resizer n'est pas la fenêtre principale mais le widget central qui est une fenêtre enfant de la fenêtre principale.

    QWidget::resize(w,h) fonctionne bien sur la fenêtre principale mais pour avoir une taille de 1024x768 sur la fenêtre réalisant le rendu, je serais obligé de faire QWidget::resize(1024+w,768+h) où w et h serait la taille des fenêtres dockables présentes, opération que je cherche à éviter car ces 2 valeurs ne sont pas forcément simple à calculer

  4. #4
    Membre émérite
    Avatar de ymoreau
    Homme Profil pro
    Ingénieur étude et développement
    Inscrit en
    Septembre 2005
    Messages
    1 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur étude et développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 154
    Points : 2 834
    Points
    2 834
    Par défaut
    Peut être en mettant la sizePolicy des autres widgets à "fixed" avant de redimensionner ton widget central ?

  5. #5
    Nouveau membre du Club
    Profil pro
    dev
    Inscrit en
    Avril 2010
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : dev

    Informations forums :
    Inscription : Avril 2010
    Messages : 53
    Points : 25
    Points
    25
    Par défaut
    Encore mieux QWidget::resize(1024,768) n'a aucun effet sur la fenêtre fille et pourtant QWidget::size() retourne bien 1024x768. C'est à ni rien y comprendre

    Citation Envoyé par YoniBlond Voir le message
    Peut être en mettant la sizePolicy des autres widgets à "fixed" avant de redimensionner ton widget central ?
    Je voudrais justement rester indépendant des autres widgets (qui sont dockables). Je n'ai pas envie de faire une sauvegarde de l'état général des wigets, opérer les changements puis restaurer l'état d'origine des autres widgets. Autant faire un truc dans ce goût là:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
      setUpdatesEnabled(false);
      // Tant que la fenêtre de rendu n'est pas à la bonne taille
      while (ui->_Renderer->width() < 1024)
        resize(width() + 1, height()); // resizer la fenêtre principale
      setUpdatesEnabled(true);
    J'aurais opté pour cette solution si le setUpdatesEnabled(false) faisait correctement son boulot. Je vois la fenêtre se resizer en dynamique

    Mon problème revient à notifier la fenêtre parent qu'une fenêtre enfant souhaite changer de taille et que la parent doit s'adapter. Je pensais m'en sortir avec QSizePolicy mais je ne vois pas comment ??

  6. #6
    Membre émérite
    Avatar de ymoreau
    Homme Profil pro
    Ingénieur étude et développement
    Inscrit en
    Septembre 2005
    Messages
    1 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur étude et développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 154
    Points : 2 834
    Points
    2 834
    Par défaut
    Je ne suis pas sûr de comprendre, avec la dernière méthode dont tu parles, tes dockwidgets ne gardent pas forcément la même taille si ? Ça devrait dépendre de leur sizepolicy.

    Les sizePolicy servent à indiquer comment le parent doit agencer ses enfants, je ne pense pas qu'il y ait moyen d'indiquer au parent de s'agrandir avec ça. Je ne pense pas que tu puisses non plus modifier la taille de la fenêtre sans que ça influe sur tes dockwidgets, à moins d'explicitement les "bloquer".

  7. #7
    Nouveau membre du Club
    Profil pro
    dev
    Inscrit en
    Avril 2010
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : dev

    Informations forums :
    Inscription : Avril 2010
    Messages : 53
    Points : 25
    Points
    25
    Par défaut
    Effectivement, ils ne gardent pas la même taille mais ce qui m'importe surtout c'est de ne pas les voir diminuer. Dans ce code, au pire ils s'agrandissent.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
      setUpdatesEnabled(false);
      // Tant que la fenêtre centrale n'est pas à la bonne taille
      while (ui->_Renderer->width() < 1024)
        resize(width() + 1, height()); // resizer la fenêtre principale
      setUpdatesEnabled(true);
    En reprenant l'exemple suivant
    http://qt.developpez.com/doc/latest/...ainwindow.html



    Cela revient à simuler le resize de la fenêtre principale par l'utilisateur jusqu'à ce que le widget central possède la bonne taille.
    Avec les QSizePolicy par défaut, on verrait les docks rouges, bleu et jaune avoir leur width() augmenter alors que le width() des docks vert et gris resterait identique.
    (cette méthode ne fonctionne de toute façon pas car on voit en dynamique les widgets se resizer.)

    En tout cas c'est le comportement que je désire obtenir.

    Alors que si on fait par exemple un setMinimunSize(1024, 768) sur la fenêtre centrale, la fenêtre principale gardant la même taille, tout les docks voient leur taille diminuer
    A moins évidemment que l'on fixe leur taille mais j'ai envie que l'utilisateur puisse les resizer (et pas envie de les fixer, puis les defixer)

    Comme ce n'est pas la première appli dans laquelle j'ai besoin de faire ça et que je suis certain que le problème s'est déjà posé, j'étais certain de pouvoir faire ça en Qt mais que je ne savais juste pas comment faire.

    Enfin, je ne sais pas si ça joue mais je n'ai pas mis de layout sur le widget central.

  8. #8
    Membre émérite
    Avatar de ymoreau
    Homme Profil pro
    Ingénieur étude et développement
    Inscrit en
    Septembre 2005
    Messages
    1 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur étude et développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 154
    Points : 2 834
    Points
    2 834
    Par défaut
    Le layout du widget central ne s'occuperait que des enfants du widgets central, dans ton cas ça ne devrait rien changer.

    Je ne pense pas qu'il existe une façon toute simple de faire ce que tu veux avec Qt, une fenêtre n'est pas censée s'agrandir toute seule en général, c'est plutôt les éléments qu'elle contient qui vont s'organiser au mieux. Comme ton widget central aura apparemment une taille fixe (ou au moins minimum), ça serait à l'utilisateur de maximiser ou agrandir la fenêtre selon l'espace qu'il veut avoir pour les dock widgets. Pour ma part je laisserais donc les dockwidget se faire "réduire" par ton widget central. Car imagine que tu agrandisses la fenêtre plus grand que la résolution d'écran, ça serait pas très confortable.

  9. #9
    Nouveau membre du Club
    Profil pro
    dev
    Inscrit en
    Avril 2010
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : dev

    Informations forums :
    Inscription : Avril 2010
    Messages : 53
    Points : 25
    Points
    25
    Par défaut
    Citation Envoyé par YoniBlond Voir le message
    une fenêtre n'est pas censée s'agrandir toute seule en général, c'est plutôt les éléments qu'elle contient qui vont s'organiser au mieux.
    Sauf si on fixe effectivement toutes les tailles des fenêtres et que l'on agrandit la taille d'une des fenêtres alors la taille de la fenêtre parent va s'agrandir. (D'où le "en général", tu me diras) Le parent adapte ses enfants, c'est bien mais je trouve qu'il devrait y a voir une option pour que le parent s'adapte aussi à ses enfants. Après tout, je me moque de contrôler la taille de la QMainWindow, ce qui m'importe c'est la taille de la fenêtre de rendu. Ça parait tellement classique comme problème que je m'étonne que l'on ne puisse pas faire ça facilement en Qt.

    Citation Envoyé par YoniBlond Voir le message
    Pour ma part je laisserais donc les dockwidget se faire "réduire" par ton widget central.
    Il se font si réduire qu'ils deviennent inutilisables. J'obligerais l'utilisateur à resizer à la mano tous les dockets alors qu'il suffirait que je le laisse resizer la fenêtre de rendu, je complexifierais l'ergonomie

    Citation Envoyé par YoniBlond Voir le message
    Car imagine que tu agrandisses la fenêtre plus grand que la résolution d'écran, ça serait pas très confortable.
    C'est le problème de l'utilisateur, la résolution du rendu est un paramètre qu'il contrôle. Si c'est le cas, il ne peut de toute façon pas voir toute la scène. Je cherche "juste" à adapter la fenêtre centrale à la résolution qu'il désire pour une meilleure ergonomie.

  10. #10
    Nouveau membre du Club
    Profil pro
    dev
    Inscrit en
    Avril 2010
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : dev

    Informations forums :
    Inscription : Avril 2010
    Messages : 53
    Points : 25
    Points
    25
    Par défaut
    De mieux en mieux si j'exécute le code suivant (fonction câblée sur un bouton)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void fct()
    {
      QSize s = size(); // QMainWindow's size = 984 x 706
      ui->_Renderer->setMinimumSize(QSize(1024, 768)); // centralWidget
      s = size(); // QMainWindow's size = toujours 984 x 706 !!!
    }
    Mais à la sortie de la fonction, je constate que la QMainWindow est bien redimensionné car si je rexécute

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void fct()
    {
      QSize s = size(); // QMainWindow's size = 1284 x 964
      ui->_Renderer->setMinimumSize(QSize(1024, 768)); // centralWidget
      s = size(); // QMainWindow's size = 1284 x 964
    }
    Je ne sais pas quel événement est appelé à la sortie de la fonction pour que la QMainWindow soit effectivement resizer ??

    idem avec updateGeometry()
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void fct()
    {
      QSize s = size(); // QMainWindow's size = 984 x 706
      ui->_Renderer->setMinimumSize(QSize(1024, 768)); // centralWidget
      updateGeometry();
      ui->_Renderer->updateGeometry();
      updateGeometry(); // au cas où...
      s = size(); // QMainWindow's size = 984 x 706
    }

  11. #11
    Nouveau membre du Club
    Profil pro
    dev
    Inscrit en
    Avril 2010
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : dev

    Informations forums :
    Inscription : Avril 2010
    Messages : 53
    Points : 25
    Points
    25
    Par défaut
    bon ce n'est pas la fonction updateGeometry() mais adjustSize() qu'il fallait appeler

  12. #12
    Nouveau membre du Club
    Profil pro
    dev
    Inscrit en
    Avril 2010
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : dev

    Informations forums :
    Inscription : Avril 2010
    Messages : 53
    Points : 25
    Points
    25
    Par défaut
    Voici un solution qui fonctionne (avec centralWidget() = ui->_Renderer)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
     
    void MainWindow::ResizeRenderer(QSize resolution)
    {
      QObjectList childs = children();
      QList<QSize> minSizes;
      QList<QSize> maxSizes;
     
      // Fix size of all children widget
      for (int i = 0; i < childs.size(); ++i)
      {
        QWidget* child = qobject_cast<QWidget*>(childs[i]);
        if (!child || (child == ui->_Renderer))
          continue;
     
        // Save previous min & max size of widget
        minSizes.append(child->minimumSize());
        maxSizes.append(child->maximumSize());
        // Fixed widget size to its actual size
        child->setFixedSize(child->size());
      }
     
      // resize renderer to the new resolution
      ui->_Renderer->setFixedSize(resolution);
      // resize its parent (QMainWindow)
      adjustSize();
      // Allow user to resize renderer
      ui->_Renderer->setMinimumSize(0, 0);
      ui->_Renderer->setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
     
      // Restaure min & max size of all children widget
      for (int i = 0; i < childs.size(); ++i)
      {
        QWidget* child = qobject_cast<QWidget*>(childs[i]);
        if (!child || (child == ui->_Renderer))
          continue;
     
        child->setMinimumSize(minSizes.takeFirst());
        child->setMaximumSize(maxSizes.takeFirst());
      }
    }
    Je trouve ça un peu lourd pour juste resizer une fenêtre mais bon en attendant une meilleure méthode...

  13. #13
    Nouveau membre du Club
    Profil pro
    dev
    Inscrit en
    Avril 2010
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : dev

    Informations forums :
    Inscription : Avril 2010
    Messages : 53
    Points : 25
    Points
    25
    Par défaut
    En fait la méthode ci-dessus ne fonctionne que si on passe à une résolution supérieure.

    La fonction ci-dessous est corrigée et filtre directement les dock widgets et impose une contraite sur leur largeur ou leur hauteur suivant leur position dans la MainWindow avant de resizer le widget central
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    void MainWindow::ResizeRenderer(const QSize& resolution)
    {
      QSize renderRes = ui->_Renderer->size();
      if (resolution == renderRes)
        return;
     
      bool isWidthExpanding = resolution.width() >= renderRes.width();
      bool isHeightExpanding = resolution.height() >= renderRes.height();
      QList<int> sizes;
      QObjectList childs = children();
     
      // Fix size of all children widget
      for (int i = 0; i < childs.size(); ++i)
      {
        QDockWidget* dock = qobject_cast<QDockWidget*>(childs[i]);
        if (!dock || dock->isFloating())
          continue;
     
        switch (dockWidgetArea(dock))
        {
          case Qt::LeftDockWidgetArea:
          case Qt::RightDockWidgetArea: // Constraint width
            sizes.append(dock->minimumWidth());
            sizes.append(dock->maximumWidth());
            dock->setFixedWidth(dock->width());
            break;
          case Qt::TopDockWidgetArea:
          case Qt::BottomDockWidgetArea: // Constraint height
            sizes.append(dock->minimumHeight());
            sizes.append(dock->maximumHeight());
            dock->setFixedHeight(dock->height());
            break;
        }
      }
     
      // Resize renderer to the new resolution and prevent resize event
      ui->_Renderer->blockSignals(true);  
      ui->_Renderer->setFixedSize(resolution);
      ui->_Renderer->blockSignals(false);
      // resize its parent (QMainWindow)
      adjustSize();
      // Allow user to resize renderer
      ui->_Renderer->setMinimumSize(0, 0);
      ui->_Renderer->setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
     
      // Restaure min & max size of all children widget
      for (int i = 0; i < childs.size(); ++i)
      {
        QDockWidget* dock = qobject_cast<QDockWidget*>(childs[i]);
        if (!dock || dock->isFloating())
          continue;
     
        switch (dockWidgetArea(dock))
        {
          case Qt::LeftDockWidgetArea:
          case Qt::RightDockWidgetArea:
            dock->setMinimumWidth(sizes.takeFirst());
            dock->setMaximumWidth(sizes.takeFirst());
            break;
          case Qt::TopDockWidgetArea:
          case Qt::BottomDockWidgetArea:
            dock->setMinimumHeight(sizes.takeFirst());
            dock->setMaximumHeight(sizes.takeFirst());
            break;
        }
      }
    }

Discussions similaires

  1. Taille du widget central
    Par saad.hessane dans le forum Débuter
    Réponses: 2
    Dernier message: 02/03/2011, 09h30
  2. [Qt Designer] Les widgets de QtDesigner ne sont pas des widgets ?
    Par contremaitre dans le forum Outils
    Réponses: 1
    Dernier message: 28/12/2010, 23h19
  3. Réponses: 2
    Dernier message: 11/03/2010, 14h14
  4. QTabWidget resize à la taille des widgets
    Par Gulish dans le forum Qt
    Réponses: 1
    Dernier message: 12/12/2008, 19h36
  5. Taille des widgets en fonction de la dimension de la fenetre
    Par flo_k dans le forum GTK+ avec C & C++
    Réponses: 0
    Dernier message: 07/12/2008, 22h13

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo