Daten in einer Tabellenansicht darstellen

Die Klassen „ QSqlQueryModel “, „ QSqlTableModel “ und „ QSqlRelationalTableModel “ können als Datenquelle für Qt-Ansichtsklassen wie „ QListView “, „ QTableView “ und „ QTreeView “ verwendet werden. In der Praxis ist „ QTableView “ bei weitem die häufigste Wahl, da ein SQL-Ergebnissatz im Wesentlichen eine zweidimensionale Datenstruktur ist.

Eine Tabellenansicht, die ein QSqlTableModel anzeigt

Das folgende Beispiel erstellt eine Ansicht auf der Grundlage eines SQL-Datenmodells:

    QTableView *view = new QTableView;
    view->setModel(model);
    view->show();

Handelt es sich um ein Lese-Schreib-Modell (z. B. QSqlTableModel), ermöglicht die Ansicht dem Benutzer, die Felder zu bearbeiten. Sie können diese Funktion deaktivieren, indem Sie

    view->setEditTriggers(QAbstractItemView::NoEditTriggers);

Sie können dasselbe Modell als Datenquelle für mehrere Ansichten verwenden. Wenn der Benutzer das Modell über eine der Ansichten bearbeitet, werden die Änderungen sofort in den anderen Ansichten übernommen. Das Beispiel „Tabellenmodell“ zeigt, wie dies funktioniert.

Ansichtsklassen zeigen oben eine Kopfzeile an, um die Spalten zu beschriften. Um die Texte der Kopfzeile zu ändern, rufen Sie ` setHeaderData()` für das Modell auf. Standardmäßig entsprechen die Beschriftungen der Kopfzeile den Feldnamen der Tabelle. Beispiel:

    model->setHeaderData(0, Qt::Horizontal, QObject::tr("ID"));
    model->setHeaderData(1, Qt::Horizontal, QObject::tr("Name"));
    model->setHeaderData(2, Qt::Horizontal, QObject::tr("City"));
    model->setHeaderData(3, Qt::Horizontal, QObject::tr("Country"));

QTableView verfügt außerdem über eine vertikale Kopfzeile auf der linken Seite mit Zahlen, die die Zeilen kennzeichnen. Wenn Sie Zeilen programmgesteuert mit ` QSqlTableModel::insertRows()` einfügen, werden die neuen Zeilen mit einem Sternchen (*) markiert, bis sie mit ` submitAll()` übermittelt werden oder automatisch, wenn der Benutzer zu einem anderen Datensatz wechselt (vorausgesetzt, die ` edit strategy ` lautet ` QSqlTableModel::OnRowChange`).

Eine Zeile in ein Modell einfügen

Ebenso werden Zeilen, die Sie mit ` removeRows()` entfernen, mit einem Ausrufezeichen (!) markiert, bis die Änderung übermittelt wird.

Die Elemente in der Ansicht werden mithilfe eines Delegaten gerendert. Der Standarddelegat „ QStyledItemDelegate “ verarbeitet die gängigsten Datentypen (int, QString, QImage usw.). Der Delegat ist außerdem dafür zuständig, Editor-Widgets (z. B. eine Combobox) bereitzustellen, wenn der Benutzer mit der Bearbeitung eines Elements in der Ansicht beginnt. Sie können eigene Delegaten erstellen, indem Sie eine Unterklasse von ` QAbstractItemDelegate ` oder ` QStyledItemDelegate` definieren. Weitere Informationen finden Sie unter „Modell-/Ansichtsprogrammierung “.

QSqlTableModel ist für die Bearbeitung jeweils einer einzelnen Tabelle optimiert. Wenn Sie ein Lese-Schreib-Modell benötigen, das auf einer beliebigen Ergebnismenge arbeitet, können Sie eine Unterklasse von „ QSqlQueryModel “ erstellen und die Methoden „ flags()“ sowie „ setData()“ neu implementieren, um es les- und schreibfähig zu machen. Die folgenden beiden Funktionen machen die Felder 1 und 2 eines Abfragemodells bearbeitbar:

Qt::ItemFlags EditableSqlModel::flags(const QModelIndex &index) const
{
    Qt::ItemFlags flags = QSqlQueryModel::flags(index);
    if (index.column() == 1 || index.column() == 2)
        flags |= Qt::ItemIsEditable;
    return flags;
}

bool EditableSqlModel::setData(const QModelIndex &index, const QVariant &value, int /* role */)
{
    if (index.column() < 1 || index.column() > 2)
        return false;

    QModelIndex primaryKeyIndex = QSqlQueryModel::index(index.row(), 0);
    int id = data(primaryKeyIndex).toInt();

    clear();

    bool ok;
    if (index.column() == 1)
        ok = setFirstName(id, value.toString());
    else
        ok = setLastName(id, value.toString());
    refresh();
    return ok;
}

Die Hilfsfunktion `setFirstName()` ist wie folgt definiert:

bool EditableSqlModel::setFirstName(int personId, const QString &firstName)
{
    QSqlQuery query;
    query.prepare("update person set firstname = ? where id = ?");
    query.addBindValue(firstName);
    query.addBindValue(personId);
    return query.exec();
}

Die Funktion `setLastName()` ist ähnlich aufgebaut. Den vollständigen Quellcode finden Sie im Beispiel „Abfragemodell “.

Durch die Unterklassifizierung eines Modells lässt es sich auf vielfältige Weise anpassen: Sie können Tooltips für die Elemente bereitstellen, die Hintergrundfarbe ändern, berechnete Werte bereitstellen, unterschiedliche Werte für die Anzeige und die Bearbeitung bereitstellen, Nullwerte speziell behandeln und vieles mehr. Weitere Informationen finden Sie unter „Model/View-Programmierung“ sowie in der Referenzdokumentation zu „ QAbstractItemView “.

Wenn Sie lediglich eine Fremdschlüsselbeziehung in eine besser lesbare Zeichenfolge umwandeln möchten, können Sie „ QSqlRelationalTableModel “ verwenden. Für optimale Ergebnisse sollten Sie zusätzlich „ QSqlRelationalDelegate “ einsetzen, einen Delegaten, der Combobox-Editoren zur Bearbeitung von Fremdschlüsseln bereitstellt.

Bearbeiten eines Fremdschlüssels in einer relationalen Tabelle

Das Beispiel „Relational Table Model“ veranschaulicht, wie Sie „ QSqlRelationalTableModel “ in Verbindung mit „ QSqlRelationalDelegate “ verwenden, um Tabellen mit Fremdschlüsselunterstützung auszustatten.

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.