Problem mit aboutToQuit

Alles rund um die Programmierung mit Qt
Antworten
trendyAndy
Beiträge: 54
Registriert: 27. März 2009 15:01

Problem mit aboutToQuit

Beitrag 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é
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag 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.
trendyAndy
Beiträge: 54
Registriert: 27. März 2009 15:01

Beitrag 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ß
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag 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().
trendyAndy
Beiträge: 54
Registriert: 27. März 2009 15:01

Beitrag 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.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag 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.
trendyAndy
Beiträge: 54
Registriert: 27. März 2009 15:01

Beitrag 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:
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

trendyAndy hat geschrieben:Aber die Ini will er auch im Destructor nicht beschreiben. :cry:
Dann zeig uns den Destruktor.
trendyAndy
Beiträge: 54
Registriert: 27. März 2009 15:01

Beitrag 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ß
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag 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?
trendyAndy
Beiträge: 54
Registriert: 27. März 2009 15:01

Beitrag 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.
brax
Beiträge: 208
Registriert: 11. Mai 2010 11:22

Beitrag 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).
trendyAndy
Beiträge: 54
Registriert: 27. März 2009 15:01

Beitrag 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ß
Antworten