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

  1. #1
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    17 745
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 17 745
    Points : 43 884
    Points
    43 884
    Par défaut Intercepter la fermeture d'une sous-fenêtre (connexion de signaux et de slots avec un QWidget enfant)
    Bonjour,

    Je cherche à intercepter la fermeture d'une sous-fenetre.

    voici mon code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    QWidget* popup=new QWidget();
    popup->setWindowTitle("essai");
    QLabel* popuplabel=new QLabel(popup);
    popuplabel->setText("essai popup");
    popup->show();
    connect(popup,SIGNAL(close()),this,SLOT(fermer()));
    Je cherche lors de la fermeture à afficher un texte dans mon QWidget père du popup sans y arriver;

    dans la console, j'ai le message connect:No such signal QWidget::close()
    dans la doc, je ne vois pas de signal close() par contre il y a un slot close. Ca me parait bizarre qu'il n'y pas de signal close() pour les QWidget alors que c'est un élément important dans Qt,il y quelque chose qui m'échappe.

    Comment faire pour arriver à mes fins ?

    Dois-je créer un objet héritant de QWidget et créer mon propre signal close ?
    pourtant je vois qu'il y a closeEvent dans les QWidgets dois-je créer mon objet héritant de QWidget et réimplémenter closeEvent ce qui me parrait au dessus de mes compétences de débutant.

    Ma demande n'est pas très compliqué je pense, il doit bien y avoir une façon très simple d'arriver à mes fins.

    Je ne suis pas obligé d'avoir mon popup enfant, il peut être autonome tant que j'arrive lors de sa fermeture à envoyer mon signal à la fenêtre principale

    Le principe des signaux/slots en soit n'est pas compliqué mais l'appliquer c'est autre chose.

    Si vous avez des exemples de codes concrets, des explications, car là avec la doc je ne m'en sors pas.

    Merci pour votre aide.

  2. #2
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 617
    Points
    15 617
    Par défaut
    Bonjour

    Effectivement, pas de signal close. Le pourquoi, je sais pas très bien. Peut être pour éviter de trop surcharger l'interface de QWidget

    Mais c'est pas un problème à écrire un tel signal : tu dérives de QWidget et tu redéfinis l'event :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class MyWidget : public QWidget { // on hérite de QWidget
    signals:
        void aboutToClose(); // le signal de fermeture
     
    public:
        void closeEvent(QCloseEvent* event) {
            QWidget::closeEvent(event); // on appelle la fonction du parent
            emit aboutToClose; // on émet le signal
        }
    };
    Ca me parait bizarre qu'il n'y pas de signal close() pour les QWidget alors que c'est un élément important dans Qt,il y quelque chose qui m'échappe.
    Bof, question de point de vue. Mais a priori, non

    Dois-je créer un objet héritant de QWidget et créer mon propre signal close ?
    pourtant je vois qu'il y a closeEvent dans les QWidgets dois-je créer mon objet héritant de QWidget et réimplémenter closeEvent ce qui me parrait au dessus de mes compétences de débutant.
    En fait, indépendamment du problème de signal, c'est quand même ce que tu dois faire
    En terme de programmation objet, tu as une MainWindow qui "voit" le QWidget et le QLabel. Or, QLabel est un objet interne à QWidget et par respect du principe d'encapsulation, MainWindow ne devrait pas connaître l'interieur du QWidget, mais le voir comme une boîte noire, qui offre des services (comme le service "prévenir que tu te ferme", ce que tu veux implémenter avec ton signal, ou le service "affiche un texte", ce que tu fais avec setText)

    Donc, pour faire les choses proprement, il faut hériter de QWidget et créer le QLabel dans le constructeur :

    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
    class MyWidget : public QWidget {
        QLabel* popuplabel;
     
    public:
        MyWidget() : QWidget() {
            popuplabel = new QLabel(this);
            popuplabel->setText("essai popup");
        }
    };
     
    class MyMainWindow : public QMainWindow {
        QWidget* popup;
     
    public:
        MyMainWindow() : QMainWindow() {
            popup = new MyWidget();
            popup->setWindowTitle("essai");
            popup->show();
        }
    };
    Autre remarque, pour inclure un widget dans un autre, utilise les QLayout, pour gérer automatiquement les dimensions et positions, plutôt que simplement mettre comme parent

    Bon courage

  3. #3
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    17 745
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 17 745
    Points : 43 884
    Points
    43 884
    Par défaut voici le code modifié
    Ça me paraissait bizarre de pas avoir le signal close(). donc je comprend tout à fait qu'il me faut créer une nouvelle classe.

    Voici ce que j'ai fait

    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
     
    class mypopup: public QWidget
    {
     Q_OBJECT
     
    signals:
    void aboutToClose();
     
    public:
    void closeEvent()
    {
     emit abouttoClose();
    }
    };
     
    class Mycode : public QMainWindow
    {
      ...
      ...
      mypopup* popup=new mypopup^();
      ....
      QPushButton* popupbouton=new QPushButton("bouton");  // bouton dans mypopup
      connect(popupbouton,SIGNAL(clicked()),this,SLOT(code_du_slot()));
    Comme cela,si je clique sur le bouton dans la fenêtre popup, un signal est envoyé à ma fenetre principale, si je ferme la fenêtre popup,rien ne se passe (je ne retransmet pas closeEvent() comme dans le code qu'on m'a donné precedemment).

    Merci pour l'exemple.

  4. #4
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    17 745
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 17 745
    Points : 43 884
    Points
    43 884
    Par défaut réouverture suite à demande
    Je réouvre le POST suite à une demande qui m'a été faite en privé.
    pour cette demande, a noter la différence entre le dernier code que j'ai mis en exemple et celui fourni en exemple au dessus par gbdivers

    J'ai crée un signal clicked pour intercepter le clic sur un bouton.
    Pour intercepter la fermeture de la fenêtre, il faut bien sûr utiliser le signal "abouttoclose" comme expliqué par l'exmple de gbdivers.

    Dans abouttoclose, il faut mettre le code à exécuter lors de la fermeture de la sous-fenetre

    A noter une autre différence

    le code d'exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    class MyWidget : public QWidget { // on hérite de QWidget
    signals:
        void aboutToClose(); // le signal de fermeture
     
    public:
        void closeEvent(QCloseEvent* event) {
            QWidget::closeEvent(event); // on appelle la fonction du parent
            emit aboutToClose; // on émet le signal
        }
    };
    le code modifié :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    class MyWidget : public QWidget { // on hérite de QWidget
    signals:
        void aboutToClose(); // le signal de fermeture
     
    public:
        void closeEvent() {
            emit aboutToClose; // on émet le signal
        }
    };
    La différence étant que l'évènement closeevent n'est pas remonté au parent.
    (suppression de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    QWidget::closeEvent(event); // on appelle la fonction du parent
    ).

    Si l'info est remonté au parent,alors la fonction closeevent du parent est exécuté donc fermeture fenêtre parent

    En espérant avoir retourné l'ascenseur

  5. #5
    Membre habitué
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Avril 2011
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2011
    Messages : 316
    Points : 126
    Points
    126
    Par défaut
    Bonjour,

    Bon, il faut avouer que je suis très loin d'etre au mieux de ma forme mais voilà les insultes que je reçois :

    soit mywidget.h :
    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
    #ifndef MYWIDGET_H
    #define MYWIDGET_H
     
    #include <QWidget>
     
    class MyWidget : public QWidget
    {
    public:
        MyWidget();
        void closeEvent() {
            emit aboutToClose;
        }
    signals:
        void aboutToClose();
    };
     
    #endif // MYWIDGET_H
    et mywidget.cpp :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include <QtGui>
    #include "mywidget.h"
     
    MyWidget::MyWidget()
    {
    }
    void MyWidget::aboutToClose()
    {
    }
    D:\Programmation\C++\QtC++GestXavMedias2\mywidget.cpp:2: In file included from mywidget.cpp:2:
    D:\Programmation\C++\QtC++GestXavMedias2\mywidget.h:-1: In member function 'void MyWidget::closeEvent()':
    D:\Programmation\C++\QtC++GestXavMedias2\mywidget.h:11: erreur : statement cannot resolve address of overloaded function
    Cordialement

  6. #6
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 617
    Points
    15 617
    Par défaut
    Bonjour

    Il ne faut pas écrire le corps d'un signal

    A lire : Signaux et slots avec Qt4

    Un bloc de signaux est déclaré par le mot-clé signals. Chaque signal déclaré est un simple prototype, l'implémentation étant réalisée par le préprocesseur moc.

  7. #7
    Membre habitué
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Avril 2011
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2011
    Messages : 316
    Points : 126
    Points
    126
    Par défaut
    Bon j'ai compris;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    void MyWidget::aboutToClose()
    {
    }
    dans mon cpp c'est une belle connerie, puisque c'est un signal.

    ceci dit, en toute logique QDialog herite de closeEvent donc je dois pouvoir faire quelque chose comme cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    HttpWindow::~HttpWindow()
    {
        void QtGestXavMedias::on_MAJFiches_clicked();
    }
    HttpWindow etant ma fenetre secondaire et QtGestXavMedias ma fiche principale.
    je sais que ce que j'ai ecrit ci dessus n'est pas bon, c'est juste pour expliquer ce que je voudrais arriver a faire.

    Je pense qu'il faut envoyer un signal a la fermeture de HttpWindow et recuperer ce signal dans la fenetre principale pour executer ce sous programme. Mais je ne vois pas comment.

    cordialement

  8. #8
    Membre habitué
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Avril 2011
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2011
    Messages : 316
    Points : 126
    Points
    126
    Par défaut
    Bonjour,

    je suis un gros gros refracteres aux signaux et slots de Qt mais ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void MaFenetrePrincipale::on_Bouton1_clicked()
    {
        FenetreSecondaire dialog(this);
        connect(&dialog, SIGNAL(close()), ui->BoutonMaj, SLOT(click()));
        dialog.exec();
    }
    mais bien sûr :
    No such signal FenetreSecondaire::close()
    d'ou le MyWidget ?

    soit mywidget.h :
    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
    #ifndef MYWIDGET_H
    #define MYWIDGET_H
    #include <QWidget>
    class MyWidget : public QWidget
    {
        Q_OBJECT
    public:
       void closeEvent(QCloseEvent* event) {
            QWidget::closeEvent(event); // on appelle la fonction du parent
            emit aLaFermeture();
       }
    signals:
       void aLaFermeture();    
    };
    #endif // MYWIDGET_H
    Maintenant il faut que je dise a ma fenetre secondaire d'heriter de MyWidget, oui mais comment ?

    actuellement j'ai fenetresecondaire.h :
    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
    #ifndef FENETRESECONDAIRE_H
    #define FENETRESECONDAIRE_H
    #include <QDialog>
    class QPushButton;
    class FenetreSecondaire : public QDialog
    {
        Q_OBJECT
    public:
        FenetreSecondaire(QWidget *parent = 0);
        ...
        ~FenetreSecondaire();
    private slots:
        ...
        void quitButtonclicked();
        ...
    private:
        QPushButton *quitButton;
    };
    #endif
    Cordialement

  9. #9
    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
    A quoi te sert la classe MyWidget ?

  10. #10
    Membre habitué
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Avril 2011
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2011
    Messages : 316
    Points : 126
    Points
    126
    Par défaut
    a rien puisque QDialog herite de closeEvent !!!

    mais alors pourquoi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void MaFenetrePrincipale::on_Bouton1_clicked()
    {
        FenetreSecondaire dialog(this);
        connect(&dialog, SIGNAL(close()), ui->BoutonMaj, SLOT(click()));
        dialog.exec();
    }
    me renvoie :

    No such signal FenetreSecondaire::close()
    pourtant, je veux bien, quand la fenetre secondaire se ferme, cliquer sur le bouton de mise a jour de ma fenetre principale!

    cordialement

  11. #11
    Invité
    Invité(e)
    Par défaut
    Bonsoir,

    Ce message est tout à fait normal : close() est un slot et non un signal (Cf documentation).

    Si j'ai bien compris ce que tu voulais faire, c'est dans ta classe FenetreSecondaire qu'il faut faire ce que tu as fait dans MyWidget, et utiliser ton signal aLaFermeture().

  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
    Juste avec le nom, c'est évident que ça ne peut pas être un signal, ça a un sens pour une fenêtre de crier "Fermer !" ?

    "QDialog herite de closeEvent" => n'a pas de sens, l'héritage c'est entre les classes. En revanche, un QDialog est un QWidget donc closeEvent étant virtual (protected), un QDialog peut le réimplémenter. Winjerome a tout dit.

  13. #13
    Membre habitué
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Avril 2011
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2011
    Messages : 316
    Points : 126
    Points
    126
    Par défaut
    Merci a vous tous,

    je vais demander a chrtophe qu'il marque resolu.

    voici ci-joint un petit exemple de passage de parametre et d'interaction entre deux fenetres que j'ai mis en oeuvre entre autre avec les conseils ci-dessus.

    cordialement
    Fichiers attachés Fichiers attachés

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

Discussions similaires

  1. Événement à la fermeture d'une sous-fenêtre MDI
    Par sebasti1-88 dans le forum Débuter
    Réponses: 2
    Dernier message: 29/11/2011, 19h03
  2. Comment intercepter la fermeture d'une fenêtre
    Par Claude_Azoulai dans le forum Visual Studio
    Réponses: 2
    Dernier message: 28/03/2011, 18h02
  3. Réponses: 3
    Dernier message: 26/10/2007, 15h49
  4. Ajouter une barre d'outils à une sous fenêtre
    Par barthelv dans le forum MFC
    Réponses: 6
    Dernier message: 23/04/2004, 14h17

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