GUI Elemente vererben

Alles rund um die Programmierung mit Qt
Antworten
cole-hawk
Beiträge: 6
Registriert: 1. März 2010 13:12

GUI Elemente vererben

Beitrag von cole-hawk »

Hallo,

ich weiß nicht recht, ob die Überschrift erkennen lässt, was ich vorhabe oder nicht...

Also ich habe mit Qt Designer eine kleine Oberfläche erstellt.
Dazu habe ich eine Klasse RXControl, in welcher dann auch die ganzen Slots definiert sind, dieich zu beginn mit den Buttons verbinde.
RXControl wird im header so definiert:

Code: Alles auswählen

class RXControl : public QDialo, public Ui::RXControl
{
   Q_OBJECT
public: RXControl(QWidget *parent = 0)
private: blablabla
private slots: hier die slots
};
in der *.cpp steht dann:

Code: Alles auswählen

RXControl::RXControl(QWidget *parent) : QDialog(parent)
{
  setupUi(this);
  dann komment die ganzen connects
}
hier folgen dann die solts
Jetzt habe ich einen slot in dem alle LineEdits gefüllt werden, die die GUI so hat... die werte werden auf einer struct gelesen. Das klappt auch alles wunderbar..
Da dieser slot aber sehr lang und groß ist, wollte ich das was er macht der Übersicht halber gern in eine neue Funktion auslagern. Das Problem dabei ist, dass die neue Klasse die LineEdits auch kennen muss...

Also hab ich ein bisschen rumprobiert und mir eine Klasse Settings erstellt:

Code: Alles auswählen

class Settings : public QDialog, public Ui::RXControl
{
 Q_OBJECT
public: Settings(QWidget *parent = 0);
};
und dann wieder wie oben:

Code: Alles auswählen

Settings::Settings(QWidget *parent) : QDialog(parent)
{
 setupUi(this)
}

und jetzt die Funktion:

void Settings::setSettings(struct RX_data *RX)
{
 lineEdit_1->setText(RX-Qdata1);
... usw
}
Leider passiert jetzt gar nix...
Deshalb hier meine Fragen:
1. Funktioniert das überhaupt was ich vorhabe? Kann man auch von anderen Funktionen auf GUI elemente zugreifen?

2. Wenn ja, wo habe ich den Denkfehler? Hab schon überlegt, ob das an dem QWidget parent liegt. muss ich der Klasse Settings das parent vom RXControl übergeben? Ich schätze mal bis jetzt wird in der klasse Sessions das Widget komplett neu erzeugt... weshalb ich auch nix auf meiner richtigen gui sehe...

Ach ich weiß einfach nicht weiter...
Vergebt mir meine QT Unkenntnis... ich probier halt ein bisschen rum und hab bei RXControl mehr oder weniger eine Vorlage als Gerüst genommen... und nun stoß ich an die Grenzen meines Könnens :)

Danke für eventuelle Ratschläge,

Grüße,
Franz
padreigh
Beiträge: 340
Registriert: 13. Mai 2010 10:06

Beitrag von padreigh »

Nutzt du die QLineEdits auch als Eingabe oder nur zur Ausgabe?

Du könntest << des Widgets für dein Struct überladen ... das verlagert dann aber nur das füllen der LineEdits von einem Slot in eine Operatorfkt.

Du könntest das setzen in logische Einheiten gliedern und mehrere Slots draus machen ...

Du könntest eine von QObject abgeleitete Datenklasse machen die das struct ersetzt und heir mal stöbern: http://doc.qt.nokia.com/4.6/properties.html ... aber auch das läuft dann auf (viele) lineEdit1->setText(datenhalter->getLineEdit1Text()); irgendwo in deinem Widget raus ...

Du könnntest im Designer gleich die korrekten Inhalte reinpacken, dann ist das Thema mit setupUI() gegessen ... oder dir ein von Widget geerbten Container schreiben der deine Gui enthält und in dem LineEdits mit korrekten Werten gebaut werden (ß-Sinn wenn du eh den Designer verwendest ...)
Patrick (QtCreator 1.3.1, Qt 4.6.3)
---
template = subdirs
cole-hawk
Beiträge: 6
Registriert: 1. März 2010 13:12

Beitrag von cole-hawk »

Hallo,

sorry für die später Antwort...

Ich nutze die LineEdits für die Ein- und Ausgabe. Also ich lade aus meinem Config-file die Werte in die LineEdits rein, kann sie ändern und wieder als neues config abspeichern... Also fällt das reinpacken der Werte gleich im Designer raus..

Werd mir das mit QObject mal anschauen...


Mich hat halt nur interessiert, ob das prinzipiell mit einfachen Mitteln möglich ist, ohne große Verrenkungen anstellen zu müssen...

Danke ;)
Grüße
pfid
Beiträge: 535
Registriert: 22. Februar 2008 16:59

Beitrag von pfid »

Den Code durchschaue ich nicht, daher kann ich dir nicht sagen wo dein Denkfehler liegt (ausser dass mir das alles etwas kompliziert vorkommt).

Was mir aber auffällt, ist, dass du 2x setupUi(this) aufrufst, einmal reicht aber. Ausserdem zeigt dir die Console entsprechende Fehler, wenn es einen Slot oder ein Signal nicht gibt (unter Windows: CONFIG += CONSOLE ins .pro File).
cole-hawk
Beiträge: 6
Registriert: 1. März 2010 13:12

Beitrag von cole-hawk »

Also nochmal ;)

Ich habe eine Klasse RXControl, die von QDialog und der Ui abgelitten ist... da drin habe ich einen Slot, der alle LineEdits füllt und einen anderen solt, der die Werte aus den line edits ausliest... da das eine ganze menge lineedits sind, wollte ich das auslesen in eine andere funktion auslagern, damit es ein bisschen übersichtlicher wird und ich durch das aus und einlesen nicht 300 Zeilen LineEdit1->setText() hier drin haben muss.
Also dachte ich, ich vererbe der neuen Klasse einfach die selben Dinge, also auch QDialog und Ui, damit es die Lineedits kennt und die Daten da reinschreiben kann...

Allerdings ist wohl der Denkfehler, dass es jetzt 2 Versionen oder Vererbungen von der GUI gibt, einmal an RXControl und einmal an Settings... Nur wird eben nur RXControl angezeigt und das schreiben in die LineEdits in der ausgelagerten Funktion in der Klasse Settings führt ins leere...

In der main() steht übrigens:

Code: Alles auswählen

QApplication app(argc, argv);
RXControl *dialog = new RXControl;
dialog->show();
return app.exec();
Deshalb vermute ich ja, dass meine Klasse Settings nix bewirkt...

Ich hab mich halt gefragt, ob man auf seine GUI Elemente nur von einer Klasse aus zugriff hat, oder eben auch von außen da ran kommt...

Sorry, wenn das ganze etwas verwirrend ist...
Wenn das nicht funktioniert, dann muss ichs halt sein lassen... war nur so ein Gedanke ;)
Werd nochmal bei den Sachen nachforschen, die padreigh gepostet hat.. ansonsten lass ichs, wenn keiner die zündende Idee hat ;)

Grüße
padreigh
Beiträge: 340
Registriert: 13. Mai 2010 10:06

Beitrag von padreigh »

Gemurkst ... aber so kanns gehen:

Code: Alles auswählen

#include <QtGui/QApplication>
#include "display.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MyDisplay w;
    w.show();
    return a.exec();
}

Code: Alles auswählen

#ifndef DISPLAY_H
#define DISPLAY_H

#include <QtGui>
#include "settings.h"

class MyDisplay : public QWidget
{
Q_OBJECT
public:
    explicit MyDisplay(QWidget *parent = 0) : QWidget(parent)
    {
        QGridLayout * grid = new QGridLayout (this);

        int row(0), col(0);


        foreach (QString s, settings.allNames())
        {
            QString label = s;
            label.remove("LineEditNr_");

            QLabel * lab =  new QLabel(label,this);
            QLineEdit * lin = new QLineEdit(this);
            lin->setObjectName(s);

            grid->addWidget(lab,row,col++);
            grid->addWidget(lin,row++,col--);


            lin->setText(settings.settings(s));
            connect(lin,SIGNAL(textChanged(QString)),this,SLOT(lineChanged(QString)));
        }
    }

private slots:
    void lineChanged(QString s)
    {
        QLineEdit* lin = qobject_cast<QLineEdit*>(sender());
        settings.setSettings(lin->objectName(),lin->text());;
    }

private:
    Settings settings;
};

Code: Alles auswählen

#ifndef SETTINGS_H
#define SETTINGS_H

#include <QtGui>
#include <QDebug>

class Settings : public QObject
{
    Q_OBJECT
public:
    explicit Settings(QObject *parent = 0):
            QObject(parent)
    {
        // load settings .. f.e. from xml
        mapping.insert("LineEditNr_1","LE1");
        mapping.insert("LineEditNr_2","LE2");
        mapping.insert("LineEditNr_3","LE3");
        mapping.insert("LineEditNr_4","LE4");
        mapping.insert("LineEditNr_5","LE5");
        mapping.insert("LineEditNr_6","LE6");
        mapping.insert("LineEditNr_7","LE7");
        mapping.insert("LineEditNr_8","LE8");
        mapping.insert("LineEditNr_9","LE9");
    }

    ~Settings() { /* store stuff back to xml */ }


    QString settings(QString objName)                { return mapping.value(objName, QString()); }
    QList<QString> allNames()                        { return mapping.uniqueKeys(); }

public slots:
    void setSettings(QString objName, QString value) { mapping.insert(objName,value);
                                                       qDebug() << "Changed: " << objName << " to " << value;}

private:
    QMap<QString,QString> mapping;
};
#endif // SETTINGS_H
// display.cpp

Code: Alles auswählen

#include "display.h"
// settings.cpp

Code: Alles auswählen

#include "settings.h"
Du könntest zB auch 2 Sets in Settings haben .. eines für Label, eines für LineEditInhalte die unter den selben objnamen angesprochen werden ... andererseits könntest du dein "Layout" auch gleich in ein XML schreiben und wieder einlesen ... oder QSettings nutzen welches das ganze je nach System in der Registry, in xml oder .inis ablegt ...
Patrick (QtCreator 1.3.1, Qt 4.6.3)
---
template = subdirs
Antworten