Programmstrukturierung



  • Hi,

    hab zwei Fragen zur Programmierung:

    1. Ich habe einen PushButton mit einer Methode verbunden. Nun soll die Methode etwa wie folgt aussehen:

    void Testklasse::Hauptmethode()
    {
    if (ui.pushButtonEINS->clicked())
        {
        QFile Datei(erstellterHauptordner + "/Shell.sh"); 
    
    else if (ui.pushButtonZWEI->clicked())
        {
        QFile Datei(geladenerHauptordner + "/Shell.sh");
        }
    
        Datei.open(QIODevice::WriteOnly | QIODevice::Text);
    
        QTextStream out1(&Datei);
        out1 <<"..."
    }
    

    Dem erstellten QFile Objekt sollen also je nachdem ob ButtonEINS oder ButtonZWEI geklickt wurde ein anderer Pfad zugewiesen werden.
    Problem ist, dass dies ja nun so nicht geht, da QFile Datei nur in der if Klammer gültig ist bzw. danach seine Gültigkeit verliert.

    Muss bzw. kann ich das Qfile Objekt Datei dann so...

    class Testklasse
    .
    .
    .
    private:
    QFile Datei();
    .
    .
    .
    

    in meiner Klasse deklarieren?
    ODER
    Gibt es noch eine bessere Lösung um Speicherplatz einzusparen etc.? -> Ich könnte ja auch den folgenden TextStream in beide if Anweisungen rein schreiben, aber verbraucht das dann nicht viel mehr Speicherplatz wenn ich aus 3000 Zeilen QString im Quelltext dann 6000 Zeilen mache?

    2. Ich glaube irgendwo gelesen zu haben (kann das leider nicht mehr finden), dass man seinen Quelltext, d.h. Methoden, Variablen usw. in einer bestimmten Reihenfolge in den Quelltext schreiben soll. Wenn dem so ist, welche Reihenfolge ist dann die günstigste oder ist das quatsch xD?



  • Gut gemeinter Rat: lass Qt (vorerst) bleiben und geh' zurück auf die Konsole, bis Du die Grundlagen inkl. Klassen verstanden hast. Dann fällt es Dir auch leichter, UI von Programmlogik zu trennen - was allgemein üblich und anzuraten ist.



  • Aber Du bist auf einem guten Weg.

    Option 2 ist natürlich die richtige, wobei Du das () weglassen solltest, und es Sinn macht, das Ding m_Datei zu nennen, wobei ein sinnvollerer Name als Datei noch schöner wäre. Das m_ zeigt Dir dann, dass es sich um eine Member Variable der Klasse handelt, und sie nicht innerhalb einer Funktion deklariert wurde. Am besten früh angewöhnen, hierzu Google -> ungarische Notation. Man muss es damit natürlich nicht übertreiben oder sich übertrieben strikt dran halten, aber mit Präfixes geht einiges übersichtlicher.

    Das hilft Dir und anderen, den Überblick zu behalten.

    Noch ein Hinweis: Du wirst nicht einfach m_File(...) machen können. Stattdessen musst Du Dir eine Methode "Load(...)" oder ähnlich aus der QFile Klasse raussuchen.



  • Zur ungarischen Notation: Das ist eig. unnötig. In modernen (/guten) IDEs kannst du einfach auf eine Variable zeigen, schon wird ihre Deklaration angezeigt. Und m_ ist beschissen, es muss der Typ (also vllt. qf_) der Variable sein, der das Präfix bestimmt.

    Hobo schrieb:

    Noch ein Hinweis: Du wirst nicht einfach m_File(...) machen können.

    Doch. Dafür gibt es Konstruktoren und deren Initialisierungslisten.



  • Hacker schrieb:

    Zur ungarischen Notation: Das ist eig. unnötig. In modernen (/guten) IDEs kannst du einfach auf eine Variable zeigen, schon wird ihre Deklaration angezeigt. Und m_ ist beschissen, es muss der Typ (also vllt. qf_) der Variable sein, der das Präfix bestimmt.

    *hust* Das ist zwar Geschmackssache, aber Deine "moderne IDE" wird Dir eher behilflich sein, indem sie einen Datentyp via Mouse-Over anzeigt, als dass sie zeigt, wo die Variable deklariert wurde. Und wenn ein Snippet ins Board kopiert wird, stehts auch nicht dabei.

    Hobo schrieb:

    Noch ein Hinweis: Du wirst nicht einfach m_File(...) machen können.

    Doch. Dafür gibt es Konstruktoren und deren Initialisierungslisten.

    ,
    Nein. Man kann keinen Constructor außerhalb der Deklaration aufrufen.



  • Hacker schrieb:

    Zur ungarischen Notation: Das ist eig. unnötig. In modernen (/guten) IDEs kannst du einfach auf eine Variable zeigen, schon wird ihre Deklaration angezeigt.

    Making Wrong Code Look Wrong

    Hacker schrieb:

    Und m_ ist beschissen, [...]

    Da gibt's Argumente dafür und dagegen...

    Hacker schrieb:

    [...] es muss der Typ (also vllt. qf_) der Variable sein, der das Präfix bestimmt.

    siehe oben.



  • Hobo schrieb:

    Hacker schrieb:

    Zur ungarischen Notation: Das ist eig. unnötig. In modernen (/guten) IDEs kannst du einfach auf eine Variable zeigen, schon wird ihre Deklaration angezeigt. Und m_ ist beschissen, es muss der Typ (also vllt. qf_) der Variable sein, der das Präfix bestimmt.

    *hust* Das ist zwar Geschmackssache, aber Deine "moderne IDE" wird Dir eher behilflich sein, indem sie einen Datentyp via Mouse-Over anzeigt, als dass sie zeigt, wo die Variable deklariert wurde. Und wenn ein Snippet ins Board kopiert wird, stehts auch nicht dabei.

    Hab ich irgendwas von 'wo' gesagt?

    Zum Konstruktor: Hab ich gesagt, dass es außerhalb der Klasse funktioniert? Ich meinte das:

    MeineKlasse::MeineKlasse():
    qf_file("MeineDatei") {}
    


  • Hacker schrieb:

    Hobo schrieb:

    Hacker schrieb:

    Zur ungarischen Notation: Das ist eig. unnötig. In modernen (/guten) IDEs kannst du einfach auf eine Variable zeigen, schon wird ihre Deklaration angezeigt. Und m_ ist beschissen, es muss der Typ (also vllt. qf_) der Variable sein, der das Präfix bestimmt.

    *hust* Das ist zwar Geschmackssache, aber Deine "moderne IDE" wird Dir eher behilflich sein, indem sie einen Datentyp via Mouse-Over anzeigt, als dass sie zeigt, wo die Variable deklariert wurde. Und wenn ein Snippet ins Board kopiert wird, stehts auch nicht dabei.

    Hab ich irgendwas von 'wo' gesagt?

    Zum Konstruktor: Hab ich gesagt, dass es außerhalb der Klasse funktioniert? Ich meinte das:

    MeineKlasse::MeineKlasse():
    qf_file("MeineDatei") {}
    



  • [] Ja. Mein Gott.



  • void Testklasse::Hauptmethode()
    {
    if (ui.pushButtonEINS->clicked())
        {
        QFile Datei(erstellterHauptordner + "/Shell.sh");
       
    else if (ui.pushButtonZWEI->clicked())
        {
        QFile Datei(geladenerHauptordner + "/Shell.sh");
        }
    
        Datei.open(QIODevice::WriteOnly | QIODevice::Text);
    
        QTextStream out1(&Datei);
        out1 <<"..."
    }
    

    -->

    void Testklasse::Schreibe(const StringTyp& s)
    {
      QFile datei(s);
      datei.open(..);
      // ..
    }
    void Testklasse::Hauptmethode()
    {
       if (ui.pushButtonEINS->clicked())
        Schreibe(erstellterHauptordner + "/Shell.sh");
       else if (ui.pushButtonZWEI->clicked())
        Schreibe(geladenerHauptordner + "/Shell.sh");
    }
    


  • Hi,

    nach brotbernd's Vorlage habe ich den Ansatz jetzt wie folgt gewählt:

    class Testklasse
    {
    
    void ErstelltOderGeladen();
    QString ShellSkript;
    
    slots:
    void Hauptmethode();
    }
    

    Form.cpp:

    void Testklasse::Hauptmethode ()  // Zeile 137
    
    {
        ErstelltOderGeladen();
    
        QFile ShellSkriptDatei(ShellSkript);
    
        ShellSkriptDatei.open(QIODevice::WriteOnly | QIODevice::Text);
    
        QTextStream out1(&ShellSkriptDatei);
        out1 <<"..."
    }
    
    void ErstelltOderGeladen 
    {
        if (ui.pushButtonEINS->clicked())           // Zeile 127
    
        ShellSkript = erstellterHauptordner + "/Shell.sh";
    
        else if (ui.pushButtonZWEI->clicked())      // Zeile 131
    
        ShellSkript = geladenerHauptordner + "/Shell.sh";
    }
    

    Bekomme jetzt noch die Fehlermeldungen :

    /usr/include/qt4/QtGui/qabstractbutton.h: In Elementfunktion »void Testklasse::ErstelltOderGeladen()«:
    /usr/include/qt4/QtGui/qabstractbutton.h:127:10: Fehler: »void QAbstractButton::clicked(bool)« ist geschützt
    Form.cpp:127:56: Fehler: in diesem Zusammenhang
    Form.cpp:127:57: Fehler: »((Testklasse*)this)->Testklasse::ui.Ui::GUIbasisclassOpenFoamGUI::<anonymous>.Ui_GUIbasisclassOpenFoamGUI::pushButtonEINS->QPushButton::<anonymous>.QAbstractButton::clicked(0)« konnte nicht von »void« nach »bool« umgewandelt werden
    /usr/include/qt4/QtGui/qabstractbutton.h:127:10: Fehler: »void QAbstractButton::clicked(bool)« ist geschützt
    Form.cpp:131:74: Fehler: in diesem Zusammenhang
    Form.cpp:131:75: Fehler: »((Testklasse*)this)->Testklasse::ui.Ui::GUIbasisclassOpenFoamGUI::<anonymous>.Ui_GUIbasisclassOpenFoamGUI::pushButtonZWEI->QPushButton::<anonymous>.QAbstractButton::clicked(0)« konnte nicht von »void« nach »bool« umgewandelt werden
    make: *** [Form.o] Fehler 1
    

    Kann mir jemand weiterhelfen?



  • Nein, Du solltest wirklich erstmal einen simplen C++ Kurs machen.
    Das geht zu weit.



  • Ok 🙂 ,

    kannst mich aber vielleicht auf die Stellen hinweisen, die falsch sind?



  • Deine Klassendeklaration ist keine. Aber das sind alles so sachen, wie man eine Klasse deklariert ist z. B. mit etwas Mühe leicht herauszufinden. Das gleiche trifft auf die Funktion ErstelltOderGeladen zu etc.



  • Meine Klassendefinition ist falsch?
    Versteh ich nicht. Ich hab vielleicht die Header weggelassen und auch die Vererbung nicht angezeigt, aber ansonsten hab ich die für das Problem benötigten Daten doch aufgelistet...



  • Na, du lieferst die Daten ja hier auch Edit für Edit nach 😃



  • LOL,

    ja hab bei der Klasse die Klammern noch eingefügt (dachte das wäre jedem klar -> hast aber recht!) und aus der Methode ErstelltOderGeladen(ShellSkript) noch ErstelltOderGeladen() gemacht
    --> wobei zweiteres muss ich wirklich nochmal nachlesen bzw. was ich da mit meinem ersten Versuch erreichen wollte :D!

    Ansonsten wars das aber.

    Anscheinend liegt das Problem ja jetzt nur noch daran, dass die clicked() Methode "geschützt ist". Kann mir jemand sagen wie ich dieses Problem überwinde?



  • Die clicked() Methode macht nicht das was du denkst.

    Es handelt sich dabei um ein Signal, das ausgelöst wird, sobald der Button geklickt wird.

    Du kannst also nicht einfach so überprüfen, ob der Button geklickt ist, sondern musst einen slot anlegen, der aufgerufen wird, sobald der button geklickt wird.

    Das verbinden der signals&slots kannst du entweder automatisch per name machen lassen oder manuell per QObject::connect verbinden.

    Wenn du es autmatisch machen willst, dann versuch mal das:

    class Testklasse
    {
       ...
    private slots:
        void on_pushButtonEINS_clicked(bool checked);
    };
    

    Signals und Slots sind das A und O bei Qt, das solltest du wirklich verstanden haben, sonst wird das nichts mit Qt.

    Evtl mal ins Qt-Unterforum verschieben



  • Hacker schrieb:



  • Swordfish schrieb:

    Hacker schrieb:

    Jetzt Fresse. Langsam fängst du echt an, unangenehm zu werden. Also. Anscheinend verstehst du nicht, was genau ich meinte. Lassen wir es hier einfach so stehen. Wenn du nächstes mal bock auf eine sinnlose Diskussion hast, schreib mir bitte 'ne Mail. Das ist hier voll OT.


Log in to reply