Variablenübergabe an Slot



  • Hallo,

    Ich habe ein Widget, welches beim Start verschiedene Variablen übergeben bekommt.
    Nun soll beim Drücken eines Buttons mit diesen Variablen gearbeitet werden.
    Wie bekomme ich den Wert der Variablen an den Slot übergeben?

    .h für das Widget:

    Eingabemaske(short anzahl, std::string acnam,QWidget *parent = 0);
    

    .cpp Widget

    Eingabemaske::Eingabemaske(short anzahl, std::string acnam, QWidget *parent):
        QDialog(parent),
        ui(new Ui::Eingabemaske)
    

    Aufruf des Widget:

    Eingabemaske maske(anzahl, acnam);
        maske.setModal(true);
        maske.exec();
    

    Im Widget Eingabemaske soll nun ein PushButton gedrückt werden, der unter anderem mit "anzahl" und "acnam" arbeiten soll. Leider kennt die Methode diese Variablen nicht.

    .h für Methode:

    void on_Speichern_pressed();
    

    .cpp

    void Eingabemaske::on_Speichern_pressed()
    
        {
            QMessageBox msgbox;
            msgbox.setText("TEst");
            msgbox.setText(QString::fromStdString(acnam));
            msgbox.exec();
    

    Ich habe es schon mit einer Parameterübergabe wie bei einer Funktion versucht:

    void Eingabemaske::on_Speichern_pressed(int anzahl, std::string acnam)
    

    aber irgendwie finde ich keine Ansatz dem Aufruf der Funktion die notwendigen Parameter mitzugeben.



  • Dieser Thread wurde von Moderator/in SeppJ aus dem Forum Compiler- und IDE-Forum in das Forum Andere GUIs - Qt, GTK+, wxWidgets verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Dein Slot kann nur die gleichen Parameter annehmen, die dein Signal (QPushButton::clicked(bool)) versendet. Das heißt hier gar nichts oder einen bool.
    Unter der Voraussetzung, dass du die Variablen, die du im ctor an das Widget übergibst, auch als Membervariablen in der Klasse speicherst, kannst du, wenn du deinen Slot als Member in deiner Widgetklasse deklarierst (ob als private oder public slot ist in dem Fall vermutlich egal). Dort kannst du dann auch direkt auf alle Member zugreifen.
    Ansonsten könntest du hier vermutlich auch noch mit Lambda-Funktionen arbeiten.
    Zum Beispiel:

    QObject::connect(button, &QPushButton::clicked, [this](){ this->anzahl = 0; }
    

    Wobei erstere Lösung schöner ist.



  • Danke für den Tipp. Habs jetzt folgendermassen umgesetzt:

    .h Datei:

    public:
        Eingabemaske(short anzahl, std::string acnam, QWidget *parent = 0);
        ~Eingabemaske();
        short anzahl;
        std::string acnam;
    
    private slots:
        void on_pushButton_clicked();
    
        void on_pushButton_2_clicked();
    

    .cpp Datei:

    void Eingabemaske::on_pushButton_clicked()
    {
            //Buttons auslesen und Ergebnis in Variable schreiben
        for  (short i=0; i < anzahl; i++)
        {
            if (doors[i]->isChecked()==1)
            {
                ds=1;
            }
            else
            {
                ds=0;
            }
            if (slides[i]->isChecked()==1)
            {
                sls=1;
            }
            else
            {
                sls=0;
            }
            if (dpress[i]->isChecked()==1)
            {
                dp=1;
            }
            else
            {
                dp=0;
            }
            if (spress[i]->isChecked()==1)
            {
                sp=1;
            }
            else
            {
                sp=0;
            }
            if (hrd[i]->isChecked()==true)
            {
                hw = 1;
            }
            else
            {
                hw=0;
            }
    
            //Tuernummer auslesen und in ShortInt umwandeln
            QString num = nummern[i]->text();
            nr = num.toShort();
    
            //Tuername auslesen und in String umwandeln
            QString nam = namen[i]->text();
            if (nam == NULL)        //Wenn Tuername: leer ist
            {
                nam = QString("Tuer_%1").arg(num);      //weise automatisch einen Namen zu
            }
            else{};
            nm = nam.toStdString();
    cout<<"4"<<endl;
            //Variablen in Klasse schreiben
            tueren[i].set_nummer(nr);
            tueren[i].set_name(nm);
            tueren[i].set_door_stat(ds);
            tueren[i].set_slide_stat(sls);
            tueren[i].set_door_press(dp);
            tueren[i].set_slide_press(sp);
            tueren[i].set_hardw(hw);
    cout<<"5"<<endl;
            //Speichere Daten in Datei
            tueren[i].safe(acnam);
        }
    }
    

    tueren[i].safe(acnam):

    void ctuer::safe(string acnam)
    {
        ofstream file;
        file.open ("./ACDATA/"+acnam+".ac", ios::out|ios::app);
        file << nummer << endl;
        file << name << endl;
        file << door_stat << endl;
        file << slide_stat << endl;
        file << door_press << endl;
        file << slide_press << endl;
        file << hardw << endl;
        file.close();
    }
    

    Die Übergabe von "anzahl" scheint problemlos zu funktionieren. Leider hab ich ein Problem mit "acnam" . Bei der Verwendung in "tueren[i].safe()" stürzt mein Programm ab. (ohne sinnvolle Fehlermeldung)

    Irgendeine Idee was die Ursache sein könnte?

    In meiner ursprünglichen Programmversion habe ich die Variable in ein Label der GUI geschrieben (von std::string in QString) und beim Speichern der Datei wieder auslesen lassen (QString in std::String). Das hat problemlos funktioniert. Allerdings möchte ich meine GUI nicht als Datenablage missbrauchen.

    Danke schon mal.



  • gelöst:

    public:
        Eingabemaske(short anzahl, std::string acnam, QWidget *parent = 0);
    

    durch

    public:
        Eingabemaske(short anz, std::string acn, QWidget *parent = 0);
    

    ersetzt.



  • Zunächst erst einmal finde ich (das ist allerdings Geschmackssache), dass du dich auf eine Sprache festlegen solltest, mit der du Variablen benennst und kommentierst. Dein derzeitiges Gemisch finde ich grauenhaft.
    Wenn dein Englisch nicht gut genug ist (wobei für Variablennamen üblicherweise die Übersetzungen von Google Translate reichen), dann solltest du alles auf Deutsch formulieren. Wobei Englisch im Zweifelsfall immer vorzuziehen ist.

    Unter der Annahme, dass der Rückgabewert von den ganzen isChecked() ein bool ist (ist vermutlich so, weil das warhscheinlich alles QCheckBoxes oder so sind), dann mach einfach folgendes:

    ds = doors[i]->isChecked();
    sls = slides[i]->isChecked();
    dp = dpress[i]->isChecked();
    sp = spress[i]->isChecked();
    hw = hrd[i]->isChecked();
    

    Kürzer und besser lesbar. Wenn ich nichts übersehen habe, dann müsste das eigentlich problemlos möglich sein und du nichts herausgeschnitten hast. (Erklärung: true == 1 und false == 0)

    Dein ctuer::safe() würde ich so schreiben:

    void ctuer::safe(const string& acnam)
    {
        ofstream file("./ACDATA/"+acnam+".ac", ios::app);
        file << nummer << '\n'
            << name << '\n'
            << door_stat << '\n'
            << slide_stat << '\n'
            << door_press << '\n'
            << slide_press << '\n'
            << hardw << '\n';
    }
    

    Den Klassennamen ctuer finde ich auch ziemlich unschön. Einmal schreibt man bei eigene Klassen üblicherweise zur Kennzeichnung den ersten Buchstaben groß und das "c", das vermutlich für Class steht, braucht man eigentlich auch nicht.
    Die Datei kann man schon im ctor festlegen, std::ios::out braucht man beim std::ofstream nicht.

    Insgesamt finde ich deinen Code irgendwie sehr verwirrend. Der Sinn und Zweck von vielen Aktionen ist irgendwie nicht ganz klar. Zum Beispiel das hier:

    tueren[i].set_nummer(nr);
            tueren[i].set_name(nm);
            tueren[i].set_door_stat(ds);
            tueren[i].set_slide_stat(sls);
            tueren[i].set_door_press(dp);
            tueren[i].set_slide_press(sp);
            tueren[i].set_hardw(hw);
    

    Warum schreibst du die Ergebnisse nicht direkt dorthin?
    Insgeamt machst du so etwas öfter, zum Beispiel auch mit "nm" in Zeile 58. Abgesehen davon, dass das kein toller Variablenname ist.

    In meiner ursprünglichen Programmversion habe ich die Variable in ein Label der GUI geschrieben (von std::string in QString) und beim Speichern der Datei wieder auslesen lassen (QString in std::String). Das hat problemlos funktioniert. Allerdings möchte ich meine GUI nicht als Datenablage missbrauchen.

    Was du hiermit sagen willst, kann ich nicht so ganz verstehen. Oder auch: will ich nicht verstehen, wenn es tatsächlich so gemeint ist, wie ich es verstehe.
    Und du kannst eigentlich fast immer std::string verwenden, wenn ein QString für eine Funktion verlangt ist, dann hat QString meines Wissens eigentlich einen eigenen ctor dafür. Wenn nicht, einfach std::string::c_str() verwenden, dafür gibt es einen ctor.

    Edit:
    Zu deiner Lösung: Du kennst aber schon "this", oder?


Log in to reply