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

Discussion :

Redimensionnement proportionnel

  1. #1
    Membre habitué

    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 18
    Points : 179
    Points
    179
    Par défaut Redimensionnement proportionnel
    Bonjour,

    Je cherche un bout de code montrant comment contraindre le resize d'une QMainWindow effectué par l'usager afin de conserver des proportions fixes largeur/hauteur, ou plus précisement pour que le centralWidget conserse les proportions qui sont celles choisies pour le widget mis en centralWidget (fixées par exemple au moyen de son sizeHint).

    J'ai fait pas mal d'essais sans sucès.

    A titre d'exemple comment, lors d'un resize fait par l'usager contraindre le widget ci-dessous à conserver son rapport h/w = 2/3.

    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
     
    #include <QtGui>
    class MyWidget : public QWidget
    {
    public:
        MyWidget(QWidget *parent = 0){}
        ~MyWidget(){}
        QSize sizeHint() const{return QSize(200,300);}
    protected:
        void paintEvent(QPaintEvent *e)
        {
            QPainter p(this);
            p.drawLine(0,0,width(),height());
        }
    };
    class MainWindow : public QMainWindow
    {
    public:
        MainWindow(QWidget *parent = 0)
        {
            MyWidget *widget = new MyWidget(this);
            setCentralWidget(widget);
        }
        ~MainWindow(){}
    };
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w; w.show();
        return a.exec();
    }

  2. #2
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 921
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 921
    Points : 220 495
    Points
    220 495
    Billets dans le blog
    127
    Par défaut
    Bonjour,

    Je pense que la solution se trouve dans une surcharge du resizeEvent(). Dans celle-ci, vous allez:
    - Accepter l'event que lorsque les taille les tailles reçues sont dans le ratio voulu
    - Sinon, renvoyez un event avec une hauteur calculé selon la largeur, afin de respecter le ratio voulu.

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 23
    Points : 40
    Points
    40
    Par défaut
    Citation Envoyé par mllibre Voir le message
    Bonjour,

    Je cherche un bout de code montrant comment contraindre le resize d'une QMainWindow effectué par l'usager afin de conserver des proportions fixes largeur/hauteur, ou plus précisement pour que le centralWidget conserse les proportions qui sont celles choisies pour le widget mis en centralWidget (fixées par exemple au moyen de son sizeHint).

    J'ai fait pas mal d'essais sans sucès.

    A titre d'exemple comment, lors d'un resize fait par l'usager contraindre le widget ci-dessous à conserver son rapport h/w = 2/3.
    [...]
    Bonjour,

    Regarde ici : http://doc.qt.nokia.com/stable/qwidg...Increment-prop
    ca semble se rapprocher de se que tu veux faire.

  4. #4
    Membre habitué

    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 18
    Points : 179
    Points
    179
    Par défaut
    Merci a LittleWhite et kangs pour ces pistes que j'avais déjà testées.

    -Le resizeEvent est envoyé au widget après que le redimensionnement ait été effectué, pour lui indiquer la nouvelle taille qu'il a. Il arrive donc trop tard. D'autre part faire un resize à l'intérieur de la fonction resizeEvent est déconseillé à cause du problème de bouclage. J'ai quand même essayé ! Qui sait ? avec le resizeEvent du widget et/ou de la mainWindow. Ils sont royalement ignoré.

    - J'avais aussi essayé avec la fonction setSizeIncrement(2, 3) de donner des incréments de variation de taille de rapport 2/3, mais là aussi, ils sont royalement ignorés. Pourquoi ?

    Ci-dessous, le code d'un essai avec ces resize et setSizeIncrement.

    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
    #include <QtGui>
    class MyWidget : public QWidget
    {
    public:
        MyWidget(QWidget *parent = 0)
        {
            setSizeIncrement(2,3);
        }
        ~MyWidget(){}
        QSize sizeHint() const{return QSize(200,300);}
    protected:
        void paintEvent(QPaintEvent *e)
        {
            QPainter p(this);
            p.drawLine(0,0,width(),height());
        }
        // Pour tester : on essaie de maintenir w <= 2h/3
        void resizeEvent(QResizeEvent *e)
        {
            int h = e->size().height(), wd = 2*h/3;
            if (e->size().width() > wd) resize(QSize(wd, h));
        }
    };
    class MainWindow : public QMainWindow
    {
    public:
        MainWindow(QWidget *parent = 0)
        {
            setSizeIncrement(2,3);
            MyWidget *widget = new MyWidget(this);
            setCentralWidget(widget);
        }
        ~MainWindow(){}
    protected:
        // Pour tester : on essaie de maintenir w <= 2h/3
        void resizeEvent(QResizeEvent *e)
        {
            int h = e->size().height(), wd = 2*h/3;
            if (e->size().width() > wd) resize(QSize(wd, h));
        }
    };
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow win; win.show();
        return a.exec();
    }

    Le seul redimensionnement que j'ai réussi à imposer c'est en surchargeant le paintEvent de la mainWindow, dans lequel je mets un resize pour imposer la proportion. Mais le comportement n'est pas génial. La fenêtre suit le resize guidé par la souris de l'usager, sans aucune contrainte et ce n'est qu'à la fin, quand l'usager relâche le bouton, que la dimension de la fenêtre se modifie pour respecter la proportion imposée. Voici le code :
    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
    #include <QtGui>
    class MyWidget : public QWidget
    {
    public:
        MyWidget(QWidget *parent = 0){}
        ~MyWidget(){}
        QSize sizeHint() const{return QSize(200,300);}
    protected:
        void paintEvent(QPaintEvent *e)
        {
            QPainter p(this);
            p.drawLine(0,0,width(),height());
        }
    };
    class MainWindow : public QMainWindow
    {
    public:
        MainWindow(QWidget *parent = 0)
        {
            MyWidget *widget = new MyWidget(this);
            setCentralWidget(widget);
        }
        ~MainWindow(){}
    protected:
        // Pour tester : on essaie de maintenir w <= 2h/3
        void paintEvent(QPaintEvent *e)
        {
            int h = height(), wd = 2*h/3;
            if (width() > wd) resize(QSize(wd, h));
        }
    };
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow win; win.show();
        return a.exec();
    }
    Il doit y avoir un truc que j'ai mal compris ou pas vu. Si quelqu'un a une idée pour résoudre ce petit pb, son code sera le bienvenu.

  5. #5
    Membre habitué
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    111
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2007
    Messages : 111
    Points : 195
    Points
    195
    Par défaut
    Bonjour,

    tu as essayé la fonction setMinimumSize ?
    http://doc.qt.nokia.com/4.7-snapshot...nimumSize-prop

  6. #6
    Membre habitué

    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 18
    Points : 179
    Points
    179
    Par défaut
    Je viens d'essayer :
    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
    #include <QtGui>
    class MyWidget : public QWidget
    {
    public:
        MyWidget(QWidget *parent = 0)
        { setMinimumSize(200,300);}
        ~MyWidget(){}
        QSize sizeHint() const{return QSize(200,300);}
    protected:
        void paintEvent(QPaintEvent *e)
        {
            QPainter p(this);
            p.drawLine(0,0,width(),height());
        }
    };
    class MainWindow : public QMainWindow
    {
    public:
        MainWindow(QWidget *parent = 0)
        {
            MyWidget *widget = new MyWidget(this);
            setCentralWidget(widget);
        }
        ~MainWindow(){}
    };
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow win; win.show();
        return a.exec();
    }
    Le fenêtre refuse d'avoir une taille inférieure à la taille initiale, mais au dela
    prend des proportions quelconques.

  7. #7
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 921
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 921
    Points : 220 495
    Points
    220 495
    Billets dans le blog
    127
    Par défaut
    Citation Envoyé par mllibre Voir le message
    Je viens d'essayer :
    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
    #include <QtGui>
    class MyWidget : public QWidget
    {
    public:
        MyWidget(QWidget *parent = 0)
        { setMinimumSize(200,300);}
        ~MyWidget(){}
        QSize sizeHint() const{return QSize(200,300);}
    protected:
        void paintEvent(QPaintEvent *e)
        {
            QPainter p(this);
            p.drawLine(0,0,width(),height());
        }
    };
    class MainWindow : public QMainWindow
    {
    public:
        MainWindow(QWidget *parent = 0)
        {
            MyWidget *widget = new MyWidget(this);
            setCentralWidget(widget);
        }
        ~MainWindow(){}
    };
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow win; win.show();
        return a.exec();
    }
    Le fenêtre refuse d'avoir une taille inférieure à la taille initiale, mais au dela
    prend des proportions quelconques.
    C'est le principe de la fonction, d'ailleurs

    -Le resizeEvent est envoyé au widget après que le redimensionnement ait été effectué, pour lui indiquer la nouvelle taille qu'il a. Il arrive donc trop tard. D'autre part faire un resize à l'intérieur de la fonction resizeEvent est déconseillé à cause du problème de bouclage. J'ai quand même essayé ! Qui sait ? avec le resizeEvent du widget et/ou de la mainWindow. Ils sont royalement ignoré.
    Le fait qu'il arrive trop tard n'est pas trop gênant dans le sens que comme il arrive vous pouvez forcer le redimensionnement dans le bon ratio.

  8. #8
    Membre habitué

    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 18
    Points : 179
    Points
    179
    Par défaut Pas encore satisfaisant
    La surcharge de resizeEvent correspond au code que j'ai mis dans mon message du 23/10/2011. J'y avais également testé le setSizeIncrement. Il suffit de commenter la ligne 7 pour supprimer ce dernier. Le résultat n'est pas satisfaisant. La mainwindow ignore totalement les resize programmés et suit la taille imposée par la souris. Le widget positionné en centralWidget est plus ou moins mal contraint et le tracé intérieur diminue quand l'utilsateur rétrécit la fenêtre, mais ne ré-augmente pas quand il ré-augmente sa taille.
    Remarque : Je fais mes tests sous Windows avec QtCreator (certaines fonctions sont parfois différentes sous avec X11).
    Je suis preneur de toute amélioration de ce code.

  9. #9
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 921
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 921
    Points : 220 495
    Points
    220 495
    Billets dans le blog
    127
    Par défaut
    Bonjour,

    j'ai testé (enfin), et chez moi, ce code:
    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
    #include <QtGui>
    class MyWidget : public QWidget
    {
    public:
        MyWidget(QWidget *parent = 0)
        {
            // setSizeIncrement(2,3);
        }
        ~MyWidget(){}
        QSize sizeHint() const{return QSize(200,300);}
    protected:
        void paintEvent(QPaintEvent *e)
        {
            QPainter p(this);
            p.drawLine(0,0,width(),height());
        }
        // Pour tester : on essaie de maintenir w <= 2h/3
     
    };
     
    class MainWindow : public QMainWindow
    {
    public:
        MainWindow(QWidget *parent = 0)
        {
            // setSizeIncrement(2,3);
            MyWidget *widget = new MyWidget(this);
            setCentralWidget(widget);
        }
        ~MainWindow(){}
    protected:
        void resizeEvent(QResizeEvent *e)
        {
            qDebug() << e->size();
            int h = e->size().height(), wd = 2*h/3;
            if (e->size().width() > wd)
            {
                qDebug() << "Invalid ratio";
                e->accept();
                resize(QSize(wd, h));
     
            }
            else
            {
                qDebug() << "Valid ratio";
     
                e->ignore();
            }
        }
    };
     
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow win; win.show();
        return a.exec();
    }
    Donne un résultat convaincant (enfin, pour moi)

  10. #10
    Membre habitué

    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 18
    Points : 179
    Points
    179
    Par défaut Ne fonctionne pas chez moi
    Bonjour,

    Merci à LittleWhite pour son intérêt et ses essais.

    J'ai copié votre code et l'ai compilé avec QtCreator 2.01 basé sur Qt 4.7.0.5, sous windows 7.
    Lorsque je modifie la taille de la fenêtre dans le bons sens (impression de "valid ratio"), le fonctionnement est normal, mais dès que je la modifie dans le mauvais (impression d'une multitude d'"invalid ratio") le widget central n'est plus rafraîchit. Si j'iconifie la fenêtre et la rappelle, le widget central n'est plus dessiné.
    La fenêtre quant à elle continue de répondre aux sollicitations de l'usager (changement de taille quelconques, sans restrictions de proportions, iconification, rappel, exit).
    Le comportement du resizeEvent dépend peut-être du systême d'exploitation, d'où mes ennuis ?
    Remarque : En permutant les e->accept() / e->ignore(), ou en les supprimant j'ai exactement le même résultat.

    Merci quand même.

Discussions similaires

  1. Réponses: 4
    Dernier message: 24/08/2010, 10h50
  2. redimensionnement proportionnel d'une fenêtre Tk
    Par regnier1 dans le forum Tkinter
    Réponses: 6
    Dernier message: 29/03/2008, 11h05
  3. redimensionner proportionnellement un swf
    Par nicerico dans le forum Flash
    Réponses: 4
    Dernier message: 17/03/2008, 17h56
  4. Réponses: 2
    Dernier message: 06/02/2007, 12h36
  5. [wxPython]Redimensionnement proportionnel d'un MDIChildFrame
    Par methos1435 dans le forum wxPython
    Réponses: 3
    Dernier message: 01/02/2006, 20h20

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