Seite 1 von 1

[gelöst] setText = Absturz?

Verfasst: 19. Oktober 2013 00:43
von ichbinneuhier
Vorweg: "ichbinneuhier" meine ich ernst. Nicht neu in Programmierung, nicht neu in C++, aber Qt war mir bis letzte Woche völlig unbekannt.

Ich habe für mein neuestes Projekt (kommt später, kommt später...) aus Faulheit beschlossen, mir das GUI von einem Framework zusammenkleben zu lassen. Qt gefiel mir ganz gut. Ich habe auch - dank CSS, was einer der Gründe für meine Wahl war - schon schnell einen großen Fortschritt bei der Umsetzung meines GUI-Entwurfs (wie gesagt: kommt später, kommt später...) gemacht, seit gestern ist zumindest der grafische Teil fertig. Jetzt geht's allerdings darum, dieses GUI auch zu befüllen.

Das Konzept meines Projekts ist es im Wesentlichen, eine XML-Datei in ein Objekt namens file auszulesen und ihren Inhalt teilweise auf die QLabel im Programm zu verteilen. Dafür habe ich eine Funktion namens parseXML teilweise gebaut, teilweise aus dem Netz übernommen, die die relevanten Knoteninhalte in einzelne private QStrings speichert, zum Beispiel qsAppName (mit Gettern und Settern). Das klappt auch ganz gut, aber auslesen kann ich es dann nicht mehr so leicht - beim Versuch, setText anzuwenden, schmiert es einfach ab.

Die relevanten Codeteile:

Code: Alles auswählen

void MyXMLFile::init(QString fileName /* = "defaultfile*/)
{
    // ... read XML file and save the settings into the private vars ...
    // this is repeated until we have a valid file :-)

    QFile ourFile;
    
    // ...
    
    ourFile.setFileName(fileName);

    QDomDocument document;
    if (!document.setContent(&ourFile))
    {
        // errorhandling ...
    }

    ourFile.close();

    // we have a valid file! yay!
    // parse it into our file object...
    QDomElement documentElement = document.documentElement();

    // top level:
    QDomNode node = documentElement.firstChild();
    parseXML(node);

    // we have all variables now. place them into the labels.
    // ...
    ui.appname->setText(this->getAppName()); // crash!
}
Läuft alles super, in qsAppName steht laut qDebug auch das Richtige drin. Reinschreiben tu' ich so:

Code: Alles auswählen

void MyXMLFile::parseXML(QDomNode& node)
{
    QDomNode domNode = node.firstChild();
    QDomElement domElement;
    while (!(domNode.isNull()))
    {
        if (domNode.isElement())
        {
            domElement = domNode.toElement();
            if (!(domElement.isNull()))
            {
                // ...

                if (domElement.tagName().toUtf8() == "appName")
                    setAppName(domElement.text());
            }
        }
        parseXML(domNode);
        domNode = domNode.nextSibling();
    }

    // first element tree parsed. head over to the next.
    if (!(node.nextSibling().isNull()))
    {
        parseXML(node.nextSibling());
    }
}
Ich nehme einfach mal an, der Fehler liegt in meiner Verwendung von setText. Das GUI kommt aus Qt Designer, ich habe da händisch nicht viel gemacht (vom CSS mal abgesehen); der Absturz sieht nach kaputtem Pointer aus. Aber welcher soll das sein?

Wer weiß Rat?

Re: setText = Absturz?

Verfasst: 19. Oktober 2013 20:42
von veeman
Wann rufst du die MyXMLFile::init Funktion auf?

Die solltest du nach dem Aufruf der Funktion setupUI machen, da die GUI Elemente sonst nicht verfügbar sind.

Re: setText = Absturz?

Verfasst: 19. Oktober 2013 20:54
von ichbinneuhier
Die rufe ich im Konstruktor von MyXMLFile auf. Auszug aus MainWindow::MainWindow:

Code: Alles auswählen

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
  // ....

    ui.setupUi(this); // use the dialog from the .ui file

    // ...

    file = new MyXMLFile();

    // ...
}

Re: setText = Absturz?

Verfasst: 20. Oktober 2013 09:26
von Christian81
MyXMlFile und MainWindow sind aber unterschiedliche Klassen...

Re: setText = Absturz?

Verfasst: 20. Oktober 2013 14:51
von ichbinneuhier
Das ist richtig. Muss ich "ui" jetzt in jeder Unterklasse des Programms neu definieren? :shock:

Re: setText = Absturz?

Verfasst: 20. Oktober 2013 15:08
von Christian81
Du hast in beiden Klassen eine Member-Variable ui. Warum dem so ist - keine Ahnung da wir nicht dein kompilierfähiges kleines Beispiel haben. Wenn man ui in der einen Klasse initialisert ist es, nur weil in einer anderen Klasse eine Member-Variable genauso heißt nicht auch dort initialisiert. Du solltest schon wissen was Du wo benötigst... -> C++ Grundlagen.

Re: setText = Absturz?

Verfasst: 20. Oktober 2013 15:22
von ichbinneuhier
Christian81 hat geschrieben:Du hast in beiden Klassen eine Member-Variable ui.
Ich verwende eigentlich die gleiche in beiden Klassen, jeweils Ui::MainWindow ui;. Ich habe quasi zwei Instanzen meines UIs (wenn ich Qt da gerade richtig verstehe), sollte also problemlos von überall darauf zugreifen können...?

Re: setText = Absturz?

Verfasst: 20. Oktober 2013 21:23
von Christian81
Ich glaube ein C++ - Buch wäre hier angebracht. Sorry aber da fehlen definitiv die einfachsten Grundlagen... :(

Re: setText = Absturz?

Verfasst: 20. Oktober 2013 21:27
von ichbinneuhier
Zumindest fehlt das Verständnis davon, wie Qt seine GUI-Klassen verwaltet. Ich finde eine derart wenig zielführende Antwort ja inkompatibel mit deiner Signatur, aber was weiß ich schon? ;)

Re: setText = Absturz?

Verfasst: 21. Oktober 2013 15:23
von Scary Hallo
ichbinneuhier hat geschrieben: Ich verwende eigentlich die gleiche in beiden Klassen, jeweils Ui::MainWindow ui;. Ich habe quasi zwei Instanzen meines UIs (wenn ich Qt da gerade richtig verstehe), sollte also problemlos von überall darauf zugreifen können...?
Ich denke nicht, dass es gut ist von zwei Klassen ein UI-Element zuzugreifen. Ich bin mir auch nicht sicher, ob das geht. Es ist auf jeden Fall kein schönes Design.
Falls doch, musst du in der Klasse MyXMLFile das UI-Element auch instantiieren. Also

Code: Alles auswählen

setupUi( ...
oder so.
Du kannst mit Q_CHECK_PTR(ui.appname) auch prüfen, ob dein Objekt überhaupt existiert.

Re: setText = Absturz?

Verfasst: 21. Oktober 2013 22:15
von veeman
Es gibt eigentlich mehrere Wege die Daten an ein UI zu übergeben. Die einfachste wäre es eine Referenz auf deine UI-Klasse zu übergeben sodass du drauf zugreifen kannst.

Re: setText = Absturz?

Verfasst: 21. Oktober 2013 22:45
von ichbinneuhier
Danke, veeman. Diese Lösung funktioniert! :)