Verschiedene frames



  • QDialog API lesen. --> show() -->exec() -->close() dann weisst du was jedes einzelne davon macht .. in deinem Fall warscheinlich ein .exec() mit anschließener Signal-Emmitierung und eigenem Slothandler oder Rückgabewertabhandlung im buttonPressed Slot ...



  • void MainWindow::on_Add_clicked()
    {
        Hinzufuegen *add = new Hinzufuegen;
        add->show();
    }
    

    So funktioniert es. Das zweite Fenster geht ohne Probleme auf und bleibt auch auf. Wie kann ich jetzt in einer button-click Funktion der Dialog-klasse auf das Hauptfenster zugreifen ?

    Mit ui-> kann ich dort nur auf den Dialog zugreifen, aber keine Daten aus dem Hauptfenster auslesen.

    Gruß,
    Prof



  • Prof schrieb:

    void MainWindow::on_Add_clicked()
    {
        Hinzufuegen *add = new Hinzufuegen;
        add->show();
    }
    

    Und wer räumt hinter Hinzufuegen auf? Nach verlassen der on_Add_clicked() hast du ein offenes Fenster das kein Parent hat ... leaaaaaaak. Ich glaube du Missbrauchst den Dialog. Sag mal was du erreichen willst ...



  • Ich will erreichen, dass der Benutzer im Dialog ein paar Daten(Strings) eingeben kann und diese dann im hauptformular weiter benutzt werden können.



  • Gut - aber wie soll sich das dem User präsentieren? Soll er einen Datensatz eingeben, danach im Hauptfenter mit den eingegebenen Daten weiter arbeiten - der Dialog interessiert ihn nicht mehr? Oder soll der Dialog omnipräsent sein? Also sollen ständig einzelne Parameter angepasst werden (z.B. Zoom, oder bei nem Graphen Durchschnittslinien, usw)
    Falls 1) ->

    void MainWindow::on_Add_clicked()
    {
        Hinzufuegen add;
        if( add.exec() == QDialog::Accepted ) {
            // Code, um die Daten aus dem Dialog ins Hauptfenster zu Transferieren
        }
        // hier ist der Dialog wieder weg
    }
    

    Falls 2) Du suchst wahrscheinlich QDockWidget. Die sind immer verfügbar, und wenn sie doch mal kurz verschwinden sollen, geht das auch problemlos. Man kann sie sogar vom Hauptfenster abdocken!



  • es geht um das erste:

    // Code, um die Daten aus dem Dialog ins Hauptfenster zu Transferieren

    Das ist doch der Knackpunkt. Wie bekomme ich die Daten aus dem Dialog ins Hauptfenster ? Eine Instanz der dialog-klasse habe ich jetzt.

    Hinzufuegen *add = new Hinzufuegen;
        QPushButton *button = new QPushButton("&klick mich", add);
    
        connect(button, SIGNAL(clicked()), this, SLOT(hallo()));
    
        add->open();
    

    das funktioniert, aber das eigentliche problem habe ich noch nicht gelöst. Das Textfeld habe ich übrigends über den res. editor erstellt und nicht über den Quelltext.



  • Nimm doch dann nicht open sondern exec(). Ersteres returnd sofort, zweiteres blockiert - was du ja scheinbar willst. So kannst du deinen Dialog auch auf dem Stack halten -> kein MemoryLeak.
    Dann ist Hinzufügen doch deine eigene Klasse. Verpass der Klasse doch getter, um auf die Daten der Eingabeelemente zuzugreifen. dein Hauptfenster holt sich dann nach dem Ausführen (wenn der Dialog wieder zu ist) die Daten ab.



  • Danke für deine Bemühungen. So langsam verzweifele ich... 😃 😃

    Verpass der Klasse doch getter
    

    Darum gehts. Ich kann keinen getter schreiben, wenn ich nicht weiß, wie ich z.b den Text aus einem Text-edit auf dem Dialog auslesen kann. Könntest du vieleicht ein kleines beispiel schreiben ?

    1 MainWindow und 1 Dialog mit einem Button und TextEdit drauf. Beim Buttonklick soll dann der eingegebene Text z.B. in die StatusBar vom MainWindow eingefügt werden.



  • So... Jetzt habe ich es fast gelöst:

    void MainWindow::auslesen()
    {
        QString text;
        text = line->text();
        ui->statusBar->showMessage(text);
    }
    
    void MainWindow::on_pushButton_clicked()
    {
        dialog = new QDialog;
        dialog->setGeometry(500,500, 500, 500);
    
        QPushButton *button = new QPushButton("&klick mich", dialog);
        button->move(50,0);
    
        line = new QLineEdit(dialog);
        line->move(50,50);
    
        connect(button, SIGNAL(clicked()), this, SLOT(auslesen()));
        dialog->exec();
    }
    

    Jetzt frage ich mich nur, ob das auch mit fertigen *.ui - Formularen funktioniert, oder ob ich jedes mal wenn ich einen Dialog erstelle auf das schnelle Zusammenklicken im Res. Editor verzichten muss.

    Grüße,
    Prof



  • warum nur benutzt du new du produzioerst dort ein Memory leak ... der Dialog hat keinen parent und nach verlassen des Slots ist der scope von "dialog" weg ... jedesmal wenn du den Slot aufrufst wird also 1 Dialogelement angelegt und nicht wieder aufgeräumt ?!? Du brauchst den Dialog nur dort, mach einfach Dialog dialog; und gut ist. Wenn du einen komplizierteren Dialog hast, baust du dir eine Klasse die meinetwegen auch ein ui hat Ddas von Dialog erbt und benuzt halt den ... bei nem einfachen Dialog macht man das so ähnlich wie du aber mit Layouts:

    void MainWindow::on_pushButton_clicked()
    {
      // hier noch kein dialog da
      {
        Dialog d; // nix new, nur hier gebraucht // wenn ein komplexer Dialog dann in ne Klasse auslagern, entsprechende Getter/SetterSlots bauen
        QHBoxLayout * la = new QHBoxLayout(&d);         // an d gekoppelt, wird das gelöscht löschsts seine childs mit ! 
        QLineEdit   * le = new QLineEdit(&d);           // an d gekoppelt, wird das gelöscht löschsts seine childs mit !
        QPushButton * p0 = new QPushButton("Jo", &d);  // an d gekoppelt, wird das gelöscht löschsts seine childs mit !
        QPushButton * p1 = new QPushButton("Nö", &d);  // an d gekoppelt, wird das gelöscht löschsts seine childs mit !
        la->addWidget(le);
        la->addWidget(p0);
        la->addWidget(p1);
    
        d.setLayout(la);
    
        connect(p0, SIGNAL(clicked()), &d, SLOT(accept());
        connect(p1, SIGNAL(clicked()), &d, SLOT(reject());
    
        if (d.exec() == == QDialog::Accepted) 
        {
           ui->statusBar->showMessage(le->text());
        }
      // hier lebt der Dialog d und alle kinder noch
      }
      // hier nimmer
    }
    


  • Danke. Das funktioniert.

    Jetzt stehe ich allerdings wieder vor einem Problem. Wenn das Item in einer QComboBox geändert wird, soll der Labeltext von einem label auf dem Dialog geändert werden.

    connect(&liste, SIGNAL(currentIndexChanged(QString)), this, SLOT(DialogAktualisieren()));
    

    Soweit ist noch alles in Butter.

    void MainWindow::DialogAktualisieren()
    {
        QString auswahl = liste.itemText(liste.currentIndex());
        formular.setText(auswahl);
    }
    

    Jetzt leider nicht mehr. Er geht in die Funktion DialogAktualisieren rein und führt alles aus, was drin steht. Allerdings wird der Labeltext nicht aktualisiert. Ein neues Label kann ich anscheinend auch nicht erstellen.

    Hat jemand eine Idee ?



  • Du solltest dringend mal ein wenig Grundlagenforschung betreiben... dein Signal gibt dir den String mit ... warum nutzt du den nicht?

    Ich hoffe mal das formular eine von dir abgeleitete QDialog-Klasse ist der du den SLOT setText() verpasst hast und die du irgendwo schonmal initialisiert hast ... befürchte aber mal das Gegenteil ...

    // hingeklatscht und nicht compiliert ... als Beispiel für eigene Klasse
    class Form : public QDialog {
    Q_OBJECT
    public: 
      Form(const QWidget * parent = 0) : QDialog(parent) 
      { 
        label1.setText("MeinText");
        label1.setText("ist sehr");
        label1.setText("Sinnfrei");
    
        QDialogButtonBox * buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok
                                          | QDialogButtonBox::Cancel, Qt::Horizontal, this );
    
        connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
        connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
    
        QVBoxLayout * l = new QVBoxLayout(this); 
        l->addWidget(&label1); 
        l->addWidget(&label2); 
        l->addWidget(&label3); 
        l->addWidget(buttonBox);
      }
    
    public slots:  
      void setText(const QString & text) { label1.setText(text); }
      void setText1(const QString & text) { label1.setText(text); }
      void setText2(const QString & text) { label2.setText(text); }
      void setText3(const QString & text) { label3.setText(text); }
    private:
      QLabel label1, label2, label3;
    };
    
    class MainWindow : public QMMainWindow (
    // viel zeug
    private slots:
      void DialogAktualisieren(const QString & text);
    private:
      Form formular;
    // noch vielmehr zeug
    };
    
    void MainWindow::DialogAktualisieren(const QString & text)
    {
        formular.setText(text); 
    }
    


  • Danke. So langsam bekomme ich den Überblick. Die Funktion, die ich gesucht habe, heißt übrigends "findChild()". Jetzt kann ich auch den Res.-editor benutzen 🙂



  • Hi,

    mal wieder stehe ich vor einem Problem:

    Ich will aus der Dialogklasse auf ein ListWidget im Hauptfenster zugreifen. Dort soll der Text aus einem ListWidget ausgelesen werden und dann als Label-Text im Dialog angezeigt werden.

    void Dialog::Refresh()
    {
    
        QListWidget *liste = findChild<QListWidget*>("ProfileAnzeigen");
    
        Fzg = liste->currentItem()->text();
    
        ui->Fahrzeug->setText("Fahrzeug: " + Fzg);
    }
    

    Das Programm stürzt ab.

    void Dialog::Refresh()
    {
    
        QObject *widget = this->parent();
        QListWidget *liste = findChild<QListWidget*>("ProfileAnzeigen");
    
        Fzg = liste->currentItem()->text();  
    
        ui->Fahrzeug->setText("Fahrzeug: " + Fzg);
    }
    

    So stürzt es auch ab. Wahrscheinlich weil das hauptfenster kein parent vom dialog ist.

    Wie muss ich vorgehen ?

    Gruß,
    Prof



  • findChild wird halt kein passendes child finden und deshalb nen NULL-Zeiger zurückliefern. Das sollte man IMMER prüfen, insbesondere wenn so ein Hinweis auch in der Doku steht!
    Außerdem solltest du unbedingt erstmal ordentlich C++ lernen. Da ist so viel Raten dabei...
    findChild ist eine Membermethode. Sie operiert auf einem Objekt, es wird ein bestimmtes child einer QObject-Instanz gesucht. In deinem Fall willst du ein child des MainWindow suchen, rufst es aber auf eine Instanz von Dialog (genauer: this) auf. Merkst du was? Kann nur schief gehen...

    Entweder richtest du dir Connections (Signal/Slot) ein, um das Refresh zu triggern und gleich den passenden Wert für dein Label zu liefern, oder aber du gibst dem Dialog-Konstruktor die passende MainWindow-Instanz mit, die Dialog dann auch speichert - dann kannst du wenns sein soll drauf zugreifen. Nachteil: Dein Dialog macht sich abhängig von der MainWindow-Implementierung (ui, child-Namen, ...), dafür ist es der schnellste direkte Weg.



  • je nachdem wer der parent des Dialog ist gehts auch über den ... hack hack hack ...


Anmelden zum Antworten