QT: finished(int), close(), accept() und reject()



  • Es ist doch so, daß Signale mit mehreren Slots verbunden sein können. So auch bei finished(int), accept() und reject().

    Folgendes Beispiel:

    //...
    connect(this, SIGNAL(close()), this, SLOT(close()));
    // Das kann auch SIGNAL(finished(int) und ein CloseSlot(int) sein
    
    //...
    void GUI::Options::close()
    {
    	QMessageBox::information(this, tr("Close"), tr("Close"));
    	emit UnHide(0, true);
    	delete(this);
    }
    
    void GUI::Options::accept()
    {
    //	QMessageBox::information(this, tr("Accept"), tr("Ok"));
    	emit UnHide(0, true);
    	delete(this);
    }
    
    void GUI::Options::reject()
    {
    //	QMessageBox::information(this, tr("Reject"), tr("Cancel"));
    	emit UnHide(0, true);
    	delete(this);
    }
    

    Warum kommt so nichts bei close() an? Ich komme jeweils nur in accept() oder reject() an. Mir ist schon klar, daß ich diese Slots überschrieben habe. Bei close() oder CloseSlot(int) komme ich an, wenn ich kein cancel() behandle.

    Also warum werden nicht close() und cancel() angesteuert?



  • delete this;
    

    Ist so richtig böse in dem Kontext 😉
    Wenn das Objekt weg ist, kann auf "this" doch auch kein SLOT mehr aufgerufen werden... Wenn du willst, dass das Objekt nach ABarbeitung aller connections zerstört wird, machst du das so:

    this->deleteLater();
    

    Aber ich weiß nicht ob das die Ursache für dein Problem ist, denn dieses hab ich nciht sooo ganz verstanden 😉



  • Das

    delete this;
    

    ist böse ja und nicht Teil des Problems. Das Problem ist, dass ich entweder in eine Schleife laufe, wenn ich da z.B.

    this->close();
    

    verwende. Ist ja auch logisch, dass ich da dann immer wieder im close() Slot lande und somit netterweise mein Fenster eben nicht geschlossen wird. Jedoch lande ich immer - und das ist mein Problem oder die Frage - im close() Slot, auch wenn ich eigentlich das finished(int) oder das done() Signal mit einem anderen, nicht überschriebenem Slot vereinbart habe.

    Also kann ich nur

    this->hide()
    

    aufrufen.

    Dennoch würde mich interessieren, warum ich mit

    connect(this, SIGNAL(finished)int), this, SLOT(CloseSlot()));
    

    auch wieder nur im close() Slot lande, wenn ich das Fenster schließe (also auf das X klicke).



  • Beschreib doch mal was du erreichen willst genauer.
    Wenn es dir z.B. darum geht, das close() abzufangen, dann implementiert man dafür das closeEvent().
    Ebenso gibt es ein hideEvent() und ein showEvent() 🙂

    Also nochmal: Genau beschreiben was du erreichen willst, dann gibts auch ne Lösung.



  • Ich wollte gerade sowieso nocheinmal schreiben, denn ich hatte mnich wieder ungenau ausgedrückt. Ich komme, wenn ich den close() Slot nicht überschrieben habe, in meinen CloseSlot() Slot. Jedoch komme ich nur in den close() Slot (so überschrieben), aber eben nicht mehr in den CloseSlot() Slot.

    Was ich erreichen will, ist folgendes:
    Ich will eine ButtonBox verarbeiten und in einem anderen Slot (dachte ich mir) das einfache X zum Schließen des Fensters auch verarbeiten.

    QObject::connect(buttonBox, SIGNAL(accepted()), OptionsClass, SLOT(accept()));
            QObject::connect(buttonBox, SIGNAL(rejected()), OptionsClass, SLOT(reject()));
    

    und

    connect(this, SIGNAL(finished)int), this, SLOT(CloseSlot()));
    

    habe ich.
    Ich weiß nicht, welche Kombination von Signal/Slots sinnvoll ist, damit ich das bewerkstelligt bekomme, ohne dass ich in jeweils mehreren Slots lande oder ein Slot überhaupt nicht aufgerufen wird.
    Mir ist klar, dass ich mit einem überschriebenem close() Slot natürlich einiges an Funktionalität verliere bzw. dann wohl immer in dem Slot lande (bei finished(int), close(), done(), reject()). Nicht klar ist mir, warum ich nicht auch in meinem eigenen CloseSlot() lande.

    Ich drücke mich schon wieder dämlich aus.
    Also habe ich einfach zwei Fragen:
    Wie mappe ich ein "Fenster geschlossen durch Klick auf das X" (also welches Signal sollte ich abfangen)?
    Welche Signale verwende ich bei einer ButtonBox?

    Nagut und wieso gibt es dann noch Events? 🙂



  • Lies dir die Doku durch 😉

    bool QWidget::close () [slot]

    Closes this widget. Returns true if the widget was closed; otherwise returns false.

    First it sends the widget a QCloseEvent. The widget is hidden if it accepts the close event. If it ignores the event, nothing happens. The default implementation of QWidget::closeEvent() accepts the close event.

    Damit sollte es klar sein 😉
    close() ruft auch nur closeEvent() auf. Demnach musst du ein Flag einführen, über welches du erkennst, ob das direkt durch das closeEvent() oder die ButtonBox aufgerufen wurde.
    Also etwa so (code nur zur Veranschaulichung 🙂

    class Widget : public QWidget
    {
      Q_OBJECT
      bool buttonClosed;
      QPushButton* button;
      protected:
        void closeEvent()
        {
          if( buttonClosed ) qDebug() << "Button vlicked to close the window!";
          // anderes was noch passieren soll...
          // zurücksetzen
          buttonClosed = false;
        }
      public:
        Widget( QWidget* parent=0 )
        : QWidget(parent),
          buttonClosed(false)
        {
          pushButton = new QPushButton(this);
          connect( pushButton, SIGNAL(clicked()), this, SLOT(buttonClose()) );
        }
      public slots:
        void buttonClose()
        {
          buttonClosed = true;
          close();
        }
    };
    


  • Da habe ich noch einiges zu lesen und einiges zu lernen 🙂
    Es ist noch alles etwas viel und, vor allem, nicht leicht, die Info aus der Doku zu ziehen, die ich wirklich brauche. Also ich lande nicht immer an der richtigen Stelle 🙂

    Gut, dann schau ich mir jetzt gleich noch die Events an.

    Vielen Dank für Deine Hilfe. Das ist genau das, was ich wissen musste 🙂



  • Bitte bitte 🙂
    Aber noch mal 2 Sachen

    connect(this, SIGNAL(finished)int), this, SLOT(CloseSlot()));
    

    das SIGNAL ist falsch... Du willst eher SIGNAL(finished(int))
    Deines dürfte wegen der Klammerung gar nicht mal kompilieren 🙂

    connect(this, SIGNAL(close()), this, SLOT(close()));
    

    es gibt kein SIGNAL "close".



  • Das erste war natürlich ein Tippfehler. Aber wie ich auf das zweite gekommen bin, kann ich jetzt auch nicht sagen. 😃
    Grundsätzlich hatte ich da finished(int) drin.
    Aber darauf habe ich jetzt einmal den connect vollkommen weggelassen und sehe, daß ich beim Schließen des Fensters auch im reject() Slot lande.
    Man lernt nie aus 😉

    Danke nochmal 🙂



  • Und ähm 😞
    Asche auf mein Haupt.

    Nur der Richtigkeit halber: Mit obig geschildertem Problem landete ich nicht im close() Slot, sondern immer im reject() Slot. Nicht, daß sich hier jemand etwas falsches anliest. Es war schon spät gestern.



  • Und noch ein kleiner Nachtrag der Vollständigkeit habler:

    void CloseEvent() {// ...}
    

    funktioniert so natürlich nicht, da es

    void CloseEvent(CloseEvent *Event)
    

    ist, welches überschrieben werden soll.

    Ich kam erst jetzt dazu, das noch zu schreiben.


Anmelden zum Antworten