QSqlRelationalTableModel & QDataWidgetMapper

Alles rund um die Programmierung mit Qt
Antworten
QtGuy
Beiträge: 8
Registriert: 21. Februar 2012 13:53

QSqlRelationalTableModel & QDataWidgetMapper

Beitrag von QtGuy »

Hallo,

ich möchte ein Eingabeformular-Widget für eine Tabelle ("Stunden") einer bestehenden MySQL-Datenbank basteln, welches neben Text- und TimeEdits auch 3 ComboBoxen zur Auswahl von Objekten aus 2 weiteren bestehenden, verknüpften Tabellen enthält. Ich halte mich dabei an den Code aus dem QtExample "sqlwidgetmapper", welchen ich dazu erweitert habe.

Die 3 ComboBoxen mappen dabei Informationen aus den 3 bestehenden Tabellen "Projekte", "Subprojekte" und "Taetigkeiten".

Das Problem ist nun, dass die ComboBox für die Subprojekte alle vorhandenen Subprojekte der bestehenden Tabelle "Subprojekte" anzeigt, unabhängig vom ausgewählten Projekt in der ComboBox davor. In Wirklichkeit sind die Subprojekte aber immer einem bestimmten Projekt zugeordnet. Die Tabelle "Subprojekte" hat dazu eine Spalte "Projekt_ID".

Wenn ich nun ein Projekt in der ersten ComboBox (Projekte) auswähle, sollen in der 2. ComboBox (Subprojekte) nur diejenigen Subprojekte angezeigt werden, bei denen der Fremdschlüssel "Projekt_ID" mit dem Primärschlüssel "ID" der Tabelle "Projekte" übereinstimmt.

Wie kann ich das anhand von QSqlRelations umsetzen?

Hier die relevaten Teile meines Codes:

Code: Alles auswählen

relationalModel = new QSqlRelationalTableModel(this);
            relationalModel->setTable("stunden");
            relationalModel->setEditStrategy(QSqlTableModel::OnFieldChange);

            project_Index = relationalModel->fieldIndex("projekt_id");
            subproject_Index = relationalModel->fieldIndex("subprojekt_id");
            taetigkeit_Index = relationalModel->fieldIndex("taetigkeit_id");

            relationalModel->setRelation(project_Index,
                   QSqlRelation("projekte", "id", "name"));

            relationalModel->setRelation(subproject_Index,
                   QSqlRelation("subprojekte", "id", "name"));

            relationalModel->setRelation(taetigkeit_Index,
                   QSqlRelation("taetigkeiten", "id", "name"));

            relationalModel->select();

QSqlTableModel *relProjektModel = relationalModel->relationModel(project_Index);
    QSqlTableModel *relSubprojektModel = relationalModel->relationModel(subproject_Index);
    QSqlTableModel *relTaetigkeitModel = relationalModel->relationModel(taetigkeit_Index);

    ui->cB_Pro->setModel(relProjektModel);
    ui->cB_Pro->setModelColumn(relProjektModel->fieldIndex("name"));

    ui->cB_Sub->setModel(relSubprojektModel);
    ui->cB_Sub->setModelColumn(relSubprojektModel->fieldIndex("name"));

    ui->cB_Tat->setModel(relTaetigkeitModel);
    ui->cB_Tat->setModelColumn(relTaetigkeitModel->fieldIndex("name"));

    mapper = new QDataWidgetMapper(this);
    mapper->setModel(relationalModel);
    mapper->setItemDelegate(new QSqlRelationalDelegate(this));

    mapper->addMapping(ui->timeEdit, relationalModel->fieldIndex("dauer"));
    mapper->addMapping(ui->textEdit, relationalModel->fieldIndex("kommentar"));
    mapper->addMapping(ui->cB_Pro, relationalModel->fieldIndex("project"));
    mapper->addMapping(ui->cB_Sub, relationalModel->fieldIndex("subprojekt"));
    mapper->addMapping(ui->cB_Tat, relationalModel->fieldIndex("taetigkeit"));
QtGuy
Beiträge: 8
Registriert: 21. Februar 2012 13:53

Re: QSqlRelationalTableModel & QDataWidgetMapper

Beitrag von QtGuy »

Habe wohl zu kompliziert gedacht. Bin nicht sicher, ob es die eleganteste Lösung ist, aber ich wende nun einfach einen Filter auf das Datenmodell der ComboBox für die Subprojekte an, jedes Mal, wenn ein Projekt ausgewählt wird. Der Filter entspricht in etwa einer Select-Anweisung in SQL, wobei der Filter-String dem Teil hinter dem "WHERE" des SQL-Select-Strings entspricht.

Code: Alles auswählen

void CW_FormWidget::on_cB_Pro_currentIndexChanged(int index)
{
    tblMdl_SubprojektModel->setFilter(QString("subprojekte.projekt_id = ").append(QString().setNum(index+1)));
}
Trotzdem danke und sorry, wenn die Frage zu blöd war=)

EDIT: Das ist übrigens keine generelle Lösung, sondern klappt so nur in meinem Fall, bzw. wenn die projekt_ID des gewählten Items der Projekt-ComboBox in fester Relation zum Index des Items in der ComboBox steht. Ansonsten muss man erst die tatsächliche ID des Projektes aus der entsprechenden Tabelle abfragen und danach filtern.

Viele Grüße!
Antworten