Zugriff auf QLineEdit verursacht Absturz



  • Hallo Leute!

    Ich bin neu hier und arbeite erst seit kurzem auf qt. Letztes Jahr bin ich auf SUSE Linux entgültig umgestiegen. Vorher hatte ich für MSDOS- und WINDOWS 32-Bit basierende Systeme Programme geschrieben. Bei diesem Programm komme ich nicht weiter. Nach dem starten des 2ten Fensters und klicken auf den Button "test"
    stürzt das Programm ab. Ich kann innerhalb der Methode Testen nicht auf die Elemente "gf" und "hf" zurückgreifen. Kann mir einer helfen? Möchte nicht unwissend sterben.

    #ifndef COUNTER_H_INCLUDED
    #define COUNTER_H_INCLUDED
    
    #include <QLabel>
    #include <QLineEdit>
    #include <QPushButton>
    #include <QDialog>
    
    class Counter : public  QLineEdit //QLabel
    {
    
    Q_OBJECT // Enable signals and slots
    
    public:
      Counter (QWidget *parent=0);
       ~Counter();
       Counter *gf, *hf;
      QPushButton *cl, *plus;  //, *finito;
        QWidget *fen;
    
    public slots:
        void countUp();
        void testen();
        void MeinFenster(); //QWidget parent);
    
    private:
       char zahlwort[200];
       //Counter *gf, *hf;
       int n;
       QString zahli;
    };
    
    #endif // COUNTER_H_INCLUDED
    

    hier dann counter.cpp:

    #include "counter.h"
    
    Counter::Counter (QWidget *parent)
       : QLineEdit (parent),
     n(0)
    {}
    
      Counter::~Counter()
      {}
    
     void Counter :: MeinFenster() //QWidget parent)
     {
      n =33;
      fen = new QWidget();
      //intoa(n, zahlwort, 10);->setWindowTitle("Faktorielle 1.0");
      fen->setGeometry(100,200,300,200);
      fen->show();
    
      gf = new Counter(fen); // Eigentlich als Eingabe gedacht
      gf->setGeometry(10,10,100,20);
      gf->show();
    
      hf = new Counter(fen); // Als Ausgabe der Berechnungen gedacht
      hf->setGeometry(10,50,100,20);
      hf->show();
    
      cl = new QPushButton("test", fen);
      cl->setGeometry(50,120,95,20);
      cl->show();
    
      plus = new QPushButton("plus", fen);
      plus->setGeometry(50,150,95,20);
      plus->show();
    
      QObject::connect(cl, SIGNAL (clicked()), gf, SLOT(testen()));
      QObject::connect(plus, SIGNAL (clicked()), hf, SLOT(countUp()));
     }
    
     void Counter::countUp ()
     {
     zahli = text();
     n = zahli.toInt();
     n++;
     zahli.setNum(n);
     setText(zahli);
     }
    
     void Counter :: testen()
     {
    
      // hier stürzt das Programm ab   
      zahli = Counter::hf->text();
      setText(zahli);
     }
    

    nun zu main.cpp:

    #include <QApplication>
    #include <QWidget>
    #include <QPushButton>
    #include <QLineEdit>
    #include "counter.h"
    //#include <atoi.h>
    
    int main(int argc, char *argv[])
    {
    
     int n;
     QString zawo;
     QString wort = "123";
     QString test = "Test";
    
     QApplication app(argc, argv);
    
     QWidget *fenster = new QWidget();
     fenster->setWindowTitle("Faktorielle 1.0");
     fenster->setGeometry(450,200,300,200);
    
     //QLineEdit *e = new QLineEdit(fenster);
     //e->setGeometry(10,10,100,20);
    
     //e->setText(wort);
    
     //Counter *erge = new Counter(fenster);
     //erge->setGeometry(10,50,100,20);
    
     //itoa(zahl, xwort, 10);
    
     //wort = e->text();
     //zahl = wort.toInt();
    
     //zahl +=2;
    
     //zawo.setNum(zahl);
    
     //erge->setText(zawo);
     QLabel *l = new QLabel("<H1>Errechnet Faktorielle</H1>",fenster);
     l->show();
    
     Counter *z = new Counter(fenster);
     z->setGeometry(10,80,200,20);
     z->show();
    
     wort = z->text();
     n = wort.toInt();
    
     QPushButton *clear = new QPushButton("Clear", fenster);
     clear->setGeometry(50,120,95,20);
    
     QPushButton *finito = new QPushButton("exit", fenster);
     finito->setGeometry(150,120,95,20);
    
     fenster->show();
    
     // QObject::connect(clear, SIGNAL (clicked()), edit, SLOT(clear()));
     QObject::connect(clear, SIGNAL (clicked()),  z,    SLOT (MeinFenster())); //testen()));
     QObject::connect(finito, SIGNAL (clicked()), &app, SLOT ( quit()));
    
      return app.exec();
    }
    

    Wie kann ich auf hf->text() und gf innerhalb von Counter::testen() zurückgreifen ohne einen Absturz zu produzieren?
    Vielleicht sollte ich mir das mit 50 Jahren nicht antun, aber wo sollen sonst die grauen Haare herkommen! Aber jeder hat mal klein angefangen.

    Also, was hab ich falsch gemacht?

    Vorab Danke!



  • Du solltest den Code erstmal in cpp Tags setzen, sonst kann man das echt nicht lesen hier.

    Und auf den ersten Blick gefällt mir der ganze Stil irgendwie nicht und ich vermute, dass du einfach die C++ Grundlagen noch nicht gut genug kannst, um schon mit GUI anzufangen. "Zugriff verursacht Absturz" heißt ganz klar, dass das Objekt ungültig ist. Nicht initialisierte Variable, schon gelöscht, noch nicht erstellt, oder was auch immer. Sollte man auch leicht mit einem Debugger finden können.



  • Besser so?

    Wie gesagt bin ich neu hier. meine "neuste" IDE war damals MSVC 2.0.
    ISt übrigens ein riesen Sprung, alleine von Windows (Win 7) auf SUSE 13.2.
    Dazu noch mit codeblocks und QT-Creator.
    Kriege das mit dem Zugriff auf die Methoden noch nocht so hin.
    Wird sich mit der Zeit schon geben. Dauert bei uns "Senioren" halt mal länger.
    Schau mer mal!



  • Hallo

    Ich verstehe dein ganzes Konzept nicht.
    Wieso erbt Counter von QLineEdit? Erben bedeutet eine "ist ein"-Beziehung. Also ist ein Counter ein QLineEdit? Ich denke nein.
    Wieso enthält dein Counter zwei weitere Counter (gf und hf)?
    Wieso erstellst du die Elemente in Counter erst bei Aufruf der Funktion MeinFenster? Besser wäre doch sicher im Constructor.
    Und wie Mechanics schon sagte, benutze den Debugger, setze ein paar Haltepunkte und schau dir an was wann aufgerufen wird.



  • denke mal der Name ist nur Bescheuert gewählt 🙂
    Das ding soll sicher CounterWidget heissen ....

    Wobei die vererbung alles andere als gerechtfertigt ist ^^

    wie Braunstein schon andeutet, nur weil ein Gui-Object ein LineEdit beinhaltet, bedient was auch immer, ist noch lange keine vererbung gerechtfertigt.

    Vererben tut man ausschließlich, wenn man jemand anderes (ner library, nem Kumpel, dem eigenenen code 🙂 ) seine Eigene Klasse als die Klasse verkaufen will, von der man abgeleitet hat.
    Derjenige sollte dann gar ned wissen, was er da wirklich hat ...
    Mal vereinfacht ausgedrueckt ^^

    Und wenn man an protected Member und Methoden rankommen will/muss ... aber das ne andere Schiene ...

    noch was ....

    QPushButton *cl, *plus; //, *finito;
    QWidget *fen;

    Zeiger auf Klassen als Member sind ne recht "harte" Abhängigkeit ...
    bei allen C++ technischen Nachteilen die die Qt mit sich bringt, mit selfdestroy und so weiter ... ist der gravierende Vorteil die viel losere Kopplung über Signal/Slot Ebene !!!
    Also lieber die SubElemente lokal in ner Methode Konstruktur erzeugen, und ausschliessliche ueber Signals/Slots verbinden und die dinger dann vergessen (die loeschen sich ja selber wenn der parent stirbt ...)
    Das macht den Code robuster und wartungsfreundlicher ...

    und 200 mal an die Tafel schreiben: C++ != C, C++ = RAII -> Ressource Aqusition Is Initialisation!

    int n;
    

    gehoert initialisiert !

    QPushButton *cl, *plus;  //, *finito;
        QWidget *fen;
    

    gehört ebenfalls initialisiert asap! (initialisierungsliste ... wenn man son kram schon braucht. notfalls mit nullptr)

    Ciao ...



  • rustyoldguy schrieb:

    Besser so?

    Ja. So wirklich durchblicken tu ich aber nicht 😉 Auf den ersten Blick sehe ich den Fehler nicht. Wenn du sagst, dass der Absturz in testen passiert, scheint die Reihenfolge halbwegs ok zu sein. Erst muss MeinFenster aufgerufen werden, und das erstellt erst den Button und verbindet den mit dem Slot testen, also muss hf schon da sein.
    Aber wie gesagt, nur auf den ersten Blick. Der ganze Aufbau ist schon etwas ungewöhnlich und unsicher, da lohnt es sich nicht so, sich den Kopf über irgendwelche Bugs zu zerbrechen 😉 Schmeiß den Code weg und versuch das nochmal, das geht sauberer.



  • Ich hab das ganze noch mal geschrieben. Diesmal hab ich den QT-Designer verwendet.
    Jetzt klappt das ganze.
    Eingabe in Altgrad:

    degree = (grad -> text()).toDouble();
    

    Ausgabe:

    ergebnis  -> setText(QString("%1").arg(sinus,0,'f',7));
    

    Die Kritik mit den Namen möchte ich zu Herzen nehmen. Ich habe die Angewohnheit
    das meiste in deutsch zu schreiben, teilweise sogar im bayerischen Dialekt, manchmal auch in französisch. Ich werde versuchen, mich zu bessern.
    Nicht das einer noch denkt, ich würde so manchen Leuten Kulturimperialismus im Bezug auf die englische Sprache vorwerfen! Gemach, das sei ferne!



  • rustyoldguy schrieb:

    Die Kritik mit den Namen möchte ich zu Herzen nehmen. Ich habe die Angewohnheit
    das meiste in deutsch zu schreiben, teilweise sogar im bayerischen Dialekt

    Ich habe in dem Beitrag noch nichts dazu gesehen und auch selber nichts gesagt, aber wo du da schon selber erwähnst, ich mag sowas selber überhaupt nicht. Das ist immer inkonsistent und hässlich. Meist läuft es auf komischen Mischmasch wie getWert, holeWert oder sowas hinaus. Und was ist mit Funktionsnamen? führeAus()? ausführen()? Ach ja, Sonderzeichen sind ja meist auch nicht schön, also fuehreAus()? Deutsch ist für sowas einfach nicht geeignet. Und dann benutzt man noch zig 3rd party Bibliotheken, wo alles andere auf Englisch ist, und dann hat man noch mehr Inkonsistenzen. Und es schaut absolut amateurhaft aus.
    Ich sehe sowas nur ein, wenn man Spezialsoftware für eine bestimmte Domäne schreibt und die englischen Fachbegriffe nicht kennt und die auch nichts bringen würden. Das kann aber auch in einer eigenen Logikschicht verstecken.



  • Das meiste was ich momentan schreibe, ist in englisch, alleine schon
    wegen der Nähe zu Linux. Manchmal lassen sich aber andere Sprachen als
    Englisch nicht vermeiden, wie etwa bei einem Programm zur Berechnung von Passungen nach DIN ISO 286:

    ES und EI bzw. es und ei
    das ist französisch und steht für

    ecart interieur und ecart superieur

    also oberes und unteres Abmaß. Würde ich upper deviation schreiben,
    müßte ich das mit UD abkürzen. Aber international hat ich ES/EI für
    Einheitsbohrung und es/es für das System Einheitswelle eingebürgert.
    Probleme machen dann auch die Nähe mancher Variablen zu Schlüsselwörtern.
    Dann muss man eben in den saueren Apfel beissen. sonst, da gebe ich
    dir Recht, sind die meisten Bezeichnungen in englisch kürzer als in
    deutsch und das ist in Quellcodes wichtig. Die ersten Proggis in QT
    laufen. Hat wenig Zeit gekostet sich and den Qt-Designer anzupassen.
    Jeder Anfang ist schwer. Der Rest ist Arbeit.



  • rustyoldguy schrieb:

    wie etwa bei einem Programm zur Berechnung von Passungen nach DIN ISO 286:

    Das meinte ich mit Spezialsoftware für bestimmte Domänen.



  • Hi rustyoldguy,
    ich würde Dir empfehlen, sich den Qt Designer anzuschauen.
    Damit musst Du dann Deine GUI nicht mehr händisch zusammen programmieren, sondern kannst schön im WYSIWYG Editor sie so zusammenbauen, wie Du sie brauchst.
    Nur als Randbemerkung.
    Viele Grüße,
    Jakob



  • Das einzige woran ich jetzt noch knabbere, ist dem "Kind" einen richtig
    passenden Namen zu geben. Wellenrechner oder Bohrungsrechner sind hier
    absolut unpassend. IT-Passungsrechner auch nicht.
    Mal gucken, was mir an Namen fürs Proggi noch einfällt.



  • Das mit dem QT-Designer hab ich schon spitz gekriegt. Viel schöner, als
    wie früher wo man das in nerviger Kleinarbeit alles per Hand eingeben
    mußte. Ein sehr schönes Tool!



  • RAD Designer sind nun wirklich nichts neues. Gabs schon in den neunzigern, wenn nicht sogar früher. Natürlich sind die jetzt mächtiger und einfacher zu bedienen, aber wie gesagt nichts grundlegend neues. Und wenn man komplexere GUIs braucht, dann muss man die trotzdem von Hand programmieren. Kann mich nicht erinnern, in den letzten Jahren jemals den Designer verwendet zu haben.


Anmelden zum Antworten