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 :

Gestion fenêtre auxiliaire


Sujet :

Qt

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2011
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 24
    Points : 10
    Points
    10
    Par défaut Gestion fenêtre auxiliaire
    Bonjour,

    J'ai développé une application qui permet d'ouvrir une fenêtre auxiliaire. Pour l'instant, cette fenêtre auxiliaire est modale. J'aimerais qu'elle soit amodale, mais que :
    - il ne soit pas possible d'en ouvrir deux (et que l'essai de nouvelle ouverture fasse revenir la fenêtre existante au premier plan),
    - la fermeture de la fenêtre principale entraîne celle de la fenêtre auxiliaire.

    Comment vérifier que la fenêtre auxiliaire existe déjà ?
    Comment la faire passer au premier plan ?
    Comment la fermer quand on ferme la fenêtre principale ?

    Cordialement.

  2. #2
    Membre chevronné Avatar de Jbx 2.0b
    Homme Profil pro
    Développeur C++/3D
    Inscrit en
    Septembre 2002
    Messages
    476
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur C++/3D
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2002
    Messages : 476
    Points : 1 787
    Points
    1 787
    Par défaut
    Salut,

    Il faudrait que tu nous dévoile un peu de ton code qu'on puisse répondre précisément. Je vais essayer malgré tout de te donner quelques infos.

    Pour la question 3, il faut que ta fenêtre secondaire soit enfant de la fenêtre principale. Il suffit pour cela de donner comme argument le pointeur de la fenêtre principale au constructeur de la fenêtre fille. Par exemple, si tes deux fenêtres sont des QDialog (mais c'est valable aussi avec QMainWindow, QFrame, QWidget...) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    QDialog* fenetrePrincipale = new QDialog();
    QDialog* fenetreSecondaire = new QDialog(fenetrePrincipale);
    Il faut aussi que ta QApplication ait sa propriété setQuitOnLastWindowClosed() à true mais c'est le comportement par défaut, donc tu n'as normalement pas a t'en soucier.

    Pour les question 1 et 2, c'est pas vraiment propre à Qt, c'est plutôt à toi de coder le comportement voulu. Un simple booléen peut par exemple stocker l'état de la fenêtre secondaire. Tu passes le booléen à true une fois la fenêtre ouverte, et tu le remet à false quand tu la ferme . Ensuite tu empêches l'ouverture d'une autre fenêtre tant qu'il n'est pas à false. En fouillant un peu, il semblerait qu'appeler successivement hide() puis show() sur une fenêtre la replace au premier plan. Sinon regarde peut-être du côté de setFocus().

    Bon courage.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2011
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 24
    Points : 10
    Points
    10
    Par défaut
    Merci pour ces indications !

    Voici des morceaux de mon code :

    main.cpp

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int main(int argc, char *argv[])
    {
        ...
        FenetrePrincipale FP;
        ...
    }
    FenetrePrincipale.h

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class FenetrePrincipale : public QMainWindow
    {
        Q_OBJECT
     
    	public:
                FenetrePrincipale();
                ~FenetrePrincipale();
        ...
    }
    FenetrePrincipale.cpp

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    FenetrePrincipale::FenetrePrincipale()
    {
        ...
        creerActions();
        ...
    }
     
    void FenetrePrincipale::creerActions()
    {
        ...
        actVerifMot = new QAction("Vérifier mot", this);
        connect(actVerifMot, SIGNAL(triggered()), this, SLOT(verifierMot()));
        ...
    }
    verifierMot.cpp

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void FenetrePrincipale::verifierMot( )
    {
        ...
        verifier = new QWidget( );
        verifier->show( );
        ...
    }
    Comment faire dans mon cas pour que la fenêtre "verifier" soit une fenêtre fille de la fenêtre principale "FP" ?

  4. #4
    Membre chevronné Avatar de Jbx 2.0b
    Homme Profil pro
    Développeur C++/3D
    Inscrit en
    Septembre 2002
    Messages
    476
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur C++/3D
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2002
    Messages : 476
    Points : 1 787
    Points
    1 787
    Par défaut
    Tu lui transmet le pointeur de la fenêtre mère :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    void FenetrePrincipale::verifierMot( )
    {
        ...
        verifier = new QWidget(this);
        verifier->show( );
        ...
    }

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2011
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 24
    Points : 10
    Points
    10
    Par défaut
    J'avais essayé ça, mais il ne crée pas de deuxième fenêtre (il crée le contenu de ma fenêtre secondaire dans la fenêtre principale).

  6. #6
    Membre expérimenté

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2009
    Messages
    1 009
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2009
    Messages : 1 009
    Points : 1 738
    Points
    1 738
    Par défaut
    Normal. Regarde la documentation du constructeur de QWidget, et à quoi sert le deuxième paramètre que tu n'utilises pas.

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2011
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 24
    Points : 10
    Points
    10
    Par défaut
    En faisant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
      verifier = new QWidget( this, Qt::Window );
      ...
      verifier->setWindowModality( Qt::NonModal );
    j'obtiens bien une fenêtre secondaire non modale, mais quand je clique dans la fenêtre principale, celle-ci ne repasse pas au premier plan. Comment faire pour que ce soit le cas ?

  8. #8
    Membre expérimenté

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2009
    Messages
    1 009
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2009
    Messages : 1 009
    Points : 1 738
    Points
    1 738
    Par défaut
    Donc en fait tu ne veux pas vraiment de lien de parenté (au sens Qt), simplement tu veux qu'une fenêtre gère l'autre. Donc reste avec ton code précédent, sans parent, et par contre il faut que le pointeur sur ta fenêtre (verifier) soit en membre de ta FenetrePrincipale, afin que tu puisses la fermer dans le destructeur de FenetrePrincipale, gérer son ouverture et sa mise en premier plan (activateWindow()). Bien sûr pour la création de "verifier", elle ne doit être faite qu'une fois.

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2011
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 24
    Points : 10
    Points
    10
    Par défaut
    Merci pour la réponse.

    Ma fenêtre "verifier" est membre de "FenetrePrincipale" :

    FenetrePrincipale.h

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    class FenetrePrincipale : public QMainWindow
    {
        ...
            private :
        ...
                QWidget *verifier;
        ...
    }

    Dans FenetrePrincipale.cpp, j'ai mis :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    FenetrePrincipale::~FenetrePrincipale()
    {
        ...
        delete verifier;
    }
    mais ma fenêtre "verifier" n'est pas fermée quand je quitte ma fenêtre principale.

  10. #10
    Membre expérimenté

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2009
    Messages
    1 009
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2009
    Messages : 1 009
    Points : 1 738
    Points
    1 738

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2011
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 24
    Points : 10
    Points
    10
    Par défaut
    Merci jbx2004 et Troudhyl ! J'obtiens bien le comportement souhaité après ajout d'un booléen "presenceFenetreVerifier".

    Création de la fenêtre "verifier" :

    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
    void FenetrePrincipale::verifierMot( )
    {
        if ( !presenceFenetreVerifier )
        {
            ...
            verifier = new QWidget( );
            verifier->show( );
            presenceFenetreVerifier = true;
        }
        else
        {
            verifier->hide();
            verifier->show();
        }
    }
    Destructeur de ma fenêtre principale :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    FenetrePrincipale::~FenetrePrincipale()
    {
        qDebug() << "Destructeur de FenetrePrincipale";
        ecrireParametresGlobaux( );
        if ( presenceFenetreVerifier )
        {
            qDebug() << "Destructeur de verifier";
            delete verifier;
        }
    }
    Il me reste un dernier problème (remarque : je viens de m'en apercevoir, mais ce n'est peut-être pas lié à cette modification) : quand je ferme mon application par le menu "Quitter" et l'action associée

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    connect(actionQuitter, SIGNAL(triggered()), qApp, SLOT(quit()));
    tout se passe bien. Par contre, quand je la ferme en cliquant sur la croix en haut à droite, j'obtiens une erreur et je vois dans les traces de debug que le destructeur est appelé deux fois. J'ai vu que la croix était liée à "closeEvent", mais je ne comprends pas d'où vient le deuxième appel au destructeur.

  12. #12
    Membre expérimenté

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2009
    Messages
    1 009
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2009
    Messages : 1 009
    Points : 1 738
    Points
    1 738
    Par défaut
    Pas besoin de booléen pour faire ça. Habituellement, les pointeurs membres qu'on n'alloue pas tout de suite, on les mets à NULL (0). Donc verifier, dans le constructeur il faut l'initialiser à 0, et ensuite tu peux changer les
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if ( presenceFenetreVerifier )
    par

  13. #13
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2011
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 24
    Points : 10
    Points
    10
    Par défaut
    Merci, c'est effectivement plus simple.

    Il me reste le problème de l'erreur (deux appels du destructeur) quand je ferme avec la "croix".

    J'ai vu que c'était lié à "setAttribute ( Qt::WA_DeleteOnClose );". Si je supprime cette instruction, je n'ai plus l'erreur (mais ma fenêtre "verifier" ne se ferme plus). J'ai lu que ça pouvait venir de la création d'un objet sans faire de "new".

    Il faut que je modifie la création de ma fenêtre principale dans le "main.cpp" ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int main(int argc, char *argv[])
    {
        QApplication app(argc, argv);
        ...
        FenetrePrincipale FP;
        ...
        return( app.exec() );
    }

  14. #14
    Membre expérimenté

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2009
    Messages
    1 009
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2009
    Messages : 1 009
    Points : 1 738
    Points
    1 738
    Par défaut
    Hum c'est vrai. WA_DeleteOnClose permet de s'assurer que le destructeur est appelé à la fermeture de la fenêtre (destruction à la fermeture, c'est assez clair). Mais évidemment sans new, on ne veut pas de delete, d'où le bug, ce n'était pas une bonne idée.

    Le problème d'origine c'est cette règle : tant qu'une fenêtre est ouverte, le programme ne s'arrête pas. Tu as deux fenêtres sans lien de parenté, donc la règle est valable. Ton but est que la fermeture d'une fenêtre provoque celle des autres (et donc du programme).

    Dans ce cas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void FenetrePrincipale::closeEvent ( QCloseEvent* event )
    {
        if (verifier)
            verifier->close();
     
        QMainWindow::closeEvent(event);
    }

  15. #15
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2011
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 24
    Points : 10
    Points
    10
    Par défaut
    Merci beaucoup, ça marche !

    Encore une petite question : je me suis aperçu que je pouvais supprimer le "delete verifier" du destructeur de FenetrePrincipale.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    FenetrePrincipale::~FenetrePrincipale()
    {
        qDebug() << "Destructeur de FenetrePrincipale";
        ecrireParametresGlobaux( );
        if ( verifier )
        {
            qDebug() << "Destructeur de verifier";
            //delete verifier;
        }
    }
    La fenêtre "verifier" est bien fermée dans tous les cas, notamment quand je passe par le menu "Quitter" qui n'appelle pas le closeEvent modifié. Pourquoi ?

  16. #16
    Membre expérimenté

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2009
    Messages
    1 009
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2009
    Messages : 1 009
    Points : 1 738
    Points
    1 738
    Par défaut
    T'as fait un new pour vérifier, il faut donc un delete. Donc tu dois le laisser. Ou alors tu lui mets le DeleteOnClose, si tu veux créer/supprimer à chaque fois...

    Pour fichier/quitter, la fonction n'est pas de fermer la fenêtre mais de quitter l'application. Donc à vérifier dans les sources mais ça doit déclencher quit().

  17. #17
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2011
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 24
    Points : 10
    Points
    10
    Par défaut
    OK ; merci pour tout !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [WD17] Gestion compte auxiliaire
    Par MISS ELIOTE dans le forum WinDev
    Réponses: 4
    Dernier message: 25/02/2014, 11h48
  2. Réponses: 2
    Dernier message: 08/02/2010, 12h12
  3. Gestion fenêtres Modales
    Par portu dans le forum Langage
    Réponses: 3
    Dernier message: 24/03/2006, 13h18
  4. [Tcl/Tk] Gestion de fenêtre
    Par HRS dans le forum Tcl/Tk
    Réponses: 2
    Dernier message: 28/08/2004, 21h27
  5. [DirectInput] Gestion des touches en mode fenêtré
    Par Harry_polin dans le forum DirectX
    Réponses: 8
    Dernier message: 19/03/2003, 17h50

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