Seite 1 von 1

Problem mit aboutToQuit

Verfasst: 19. Mai 2010 12:01
von trendyAndy
Hallo zusammen,

ich arbeite seit längerem an einer Qt-Anwendung und konnte in diesem Forum schon viele nützliche Informationen finden.
Jetzt hänge ich an so etwas scheinbar einfachem wie dem Signal aboutToQuit.
Ich mach folgendes:

Code: Alles auswählen

...
connect( qApp, SIGNAL(aboutToQuit()), this, SLOT(Beenden()));
...


void MainWindow::Beenden()
{
     .... //Einstellungen in INI speichern etc.

}
So weit so gut. Es wird nur nichts gespeichert oder sonst etwas abgearbeitet. Egal was ich in Beenden rein schreibe.
Kann mir jemand sagen was ich falsch mache?
Ich verstehe das doch richtig, dass wenn ich qApp->quit(); aufrufe das Signal aboutToQuit() emmittiert wird. Ich dieses nur einfange und den SLOT Beenden() aufrufe und darin dann diverse Aktionen ausführen kann.
Kann mir jemand eine Tip geben?

Gruß
André

Verfasst: 19. Mai 2010 12:32
von franzf
Ini Speichern würde ich im Destruktor machen. Leg in der main das MainWin-Objekt auf den Stack, dann kümmert sich RAII ums Zerstören ;) Und du kommst sicher in den Destruktor.
Hast du schomal eine Ausgabe in Beenden() auf die Konsole geschrieben, um zu sehen ob der SLOT überhaupt aufgerufen wird?
Kommt irgend ein Meldung auf der Konsole beim connect? den return des connect() schonmal überprüft?
Ansonsten -> mehr Code. Am besten ein kompilierbares Minimalbeispiel, das den Fehler enthält.

Verfasst: 19. Mai 2010 13:51
von trendyAndy
Hallo Franz,

vielen Dank erst mal. Ich denke im Vergleich zu dir kann man mich als newbie bezeichnen :D
Darum weiß ich auch nicht wie man das MainWin Objekt auf den Stack legt.
Aber ja ich habe eine Ausgabe versucht und es scheint so, als würde da gar nichts passieren! Ich habe dann versucht mit dem Debugger vom Creator zu hantieren, aber da klappts auch nicht so wie ich will.

Gruß

Verfasst: 19. Mai 2010 14:05
von franzf
trendyAndy hat geschrieben:vielen Dank erst mal. Ich denke im Vergleich zu dir kann man mich als newbie bezeichnen :D
Darum weiß ich auch nicht wie man das MainWin Objekt auf den Stack legt.
STACK == Automatischer Speicherbereich
HEAP == dynamischer Speicherbereich:

Code: Alles auswählen

Object o; // automatischer Speicherbereich, wird nach Verlassen des Scope automatisch zerstört
Object *o = new Object; // dynamischer Speicherbereich -> du musst selber Löschen mit delete, o überlebt den aktuellen Scope.
Ist aber C++ und nicht Qt.
Aber ja ich habe eine Ausgabe versucht und es scheint so, als würde da gar nichts passieren!
Hast du auch brav das "Q_OBJECT"-Macro in deiner Klasse, und den Header unter "HEADERS" in deinem .pro?
Wenn nicht gibt es eigentlich auf der Console eine Ausgabe ala Object::connect: No such slot QWidget::Beenden().

Verfasst: 19. Mai 2010 15:29
von trendyAndy
Na gut, so Newbie bin ich dann auch nicht das ich das mit dem Q_OBJECT und der Ausgabe No such slot... nicht weiß.

Aber du hast Recht viele der Grundlagen von C++ habe ich verdrängt obwohl ich erst vor nem Jahr versucht habe die Grundlagen mit einem Buch von Willms wieder aufzufrischen.

Ich arbeite mit dem Creator und da wird alles im Header automatisch eingetragen.

Im Main habe ich dann alles auf dem STACK.
Die Objekte die ich dann im MainWindow erzeuge sind auf dem HEAP. die haben dann auch den destructor mit delete.

War auch in diversen englischsprachigen Foren, aber auch das was ich da gelesen habe funtkionierte nicht.

Verfasst: 19. Mai 2010 16:00
von franzf
win.h

Code: Alles auswählen

#include <QDebug>
#include <QWidget>
#include <QApplication>

class Win : public QWidget
{
    Q_OBJECT
private slots:
    void beenden() {
        qDebug() << "Beenden";
    }
public:
    Win() {
        connect(qApp, SIGNAL(aboutToQuit()), SLOT(beenden()));
    }
};
main.cpp

Code: Alles auswählen

#include <QApplication>

#include "win.h"

int main(int argc, char** argv) {
    QApplication app(argc, argv);
    Win win;
    win.show();
    return app.exec();
}
application.pro

Code: Alles auswählen

TEMPLATE = app
TARGET = 
DEPENDPATH += .
INCLUDEPATH += .

# Input
HEADERS += win.h
SOURCES += main.cpp
Funktioniert hier auf Anhieb.

Verfasst: 19. Mai 2010 20:10
von trendyAndy
Tatsächlich, hat das jetzt funktioniert! :?:
Ich liege dir zu Füßen :wink:
Habe das mit dem qDebug nicht so ganz geschnallt gehabt. Aber jetzt isses klar. Sogar im Destructor gehts mit der Debug-Ausgabe. Aber die Ini will er auch im Destructor nicht beschreiben. :cry:

Verfasst: 19. Mai 2010 20:14
von franzf
trendyAndy hat geschrieben:Aber die Ini will er auch im Destructor nicht beschreiben. :cry:
Dann zeig uns den Destruktor.

Verfasst: 20. Mai 2010 08:53
von trendyAndy
Guten Morgen,

also hier der Code:

Code: Alles auswählen

StackedWidget::StackedWidget(QWidget *parent) :
    QStackedWidget(parent),
    m_ui(new Ui::StackedWidget)
{
    m_ui->setupUi(this);

settings = new QSettings("Startup.INI", QSettings::IniFormat);

}

StackedWidget::~StackedWidget()
{
    settings->beginGroup("SetupAllgemein");
    settings->setValue("Test","Test");
    settings->endGroup();
    delete m_ui;
}
Na ja bei näherem betrachten habe ich auch da in der Qt Doku noch was gefunden dass ich erst mal nachlesen muß...
Gruß

Verfasst: 20. Mai 2010 09:22
von franzf
Qt-Doku hat geschrieben:QSettings::~QSettings ()
Destroys the QSettings object.

Any unsaved changes will eventually be written to permanent storage.

See also sync().
Und, zerstörst du dein QSettings-Objekt? Nö :P
Desweiteren: Ist es wirklich nötig das Settings-Objekt in den dynamischen Speicherbereich zu legen? Ich denke nicht.
Und musst du das Settings-Objekt die ganze Zeit im Speicher belassen, also als Member ablegen? Kannst du nicht im Destruktor ein settings-Objekt erstellen, die Werte reinschreiben und das Objekt automatisch wieder über den Jordan schicken?

Code: Alles auswählen

StackedWidget::~StackedWidget()
{
    QSerttings settings("Startup.INI", QSettings::IniFormat);
    settings.beginGroup("SetupAllgemein");
    settings.setValue("Test","Test");
    settings.endGroup();
    delete m_ui;
}
Und von was erbt dein StackedWidget? Kannst du nicht einfach QStackedWidget verwenden? Wenn du von QStackedWidget ableitest -> warum?

Verfasst: 20. Mai 2010 13:29
von trendyAndy
Meine Klasse StackedWidget erbt von QStackedWidget. Der Name spielt ja auch keine Rolle.
Und in Qt muß man nichts selber löschen was einen parent hat, gilt also für alle QObject Subklassen.
Uns StackedWidget hat das bei mir.
Oder etwa doch nicht?? Wenn nicht, dann wäre meine grüne Qt-Bibel nichts Wert.

Verfasst: 20. Mai 2010 13:43
von brax
Dein StackedWidget hat vielleicht einen Parent, aber Deine QSettings nicht... Also entweder in ~StackedWidget ein "delete settings" aufrufen, oder wie vorgeschlagen als Variable auf dem Stack lokal im Destruktor (wenn Du die settings an anderen Stellen brauchst, geht das natürlich nicht).

Verfasst: 20. Mai 2010 15:33
von trendyAndy
Ok da habt ihr recht. Habe aber weder in meinem Qt Buch noch in irgend einem Beispiel im Netz was gefunden wo das Settings Objekt wieder zerstört wird.
Leider brauche ich die Daten aus der Ini in verschiedenen Objekten/Klassen. erst lese ich Daten und dann schreibe ich irgendwann wieder welche rein.
Aber jetzt sind wir abgeschweift und ich lese erst mal andere threads druch bezüglich der QSettings

Danke und Gruß