QSqlRelationalTable如何在具有外键的列中显示其他表中的值?

问题描述 投票:-1回答:1

我有一个带有两个表的SQLite数据库:

vertex(ID int primary key, name varchar(64));
edge(ID int primary key, sourceID int references vertex(ID), targetID int references vertex(ID));

在我的桌面应用程序中,我正在使用模型/视图的自定义类

MyTableView : public QTableView
VertexTableModel : public QSqlTableModel
EdgeTableModel : public QSqlRelationalTableModel

我正在这样设置它们:

GraphyEditor::GraphyEditor(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::GraphyEditor),
        vertexModel(new VertexTableModel(parent)),
        edgeModel(new EdgeTableModel(parent)) {
    ui->setupUi(this);

    vertexModel->setTable("vertex");
    ui->vertices->setModel(vertexModel); //  ui->vertices is *MyTableView

    edgeModel->setTable("edge");
    //TODO find fix to the issue
//    edgeModel->setRelation(1, QSqlRelation("vertex", "ID", "name"));
//    edgeModel->setRelation(2, QSqlRelation("vertex", "ID", "name"));

    ui->edges->setModel(edgeModel); //  ui->egdes is *MyTableView
}

此代码可以正常工作并正确显示数据,但我想将sourceID中的第1列和第2列(targetIDedgeModel)从vertex.ID替换为vertex.name

我进行了一些搜索,找到了setRelation方法(我在代码中注释了同样的方法,但是当我使用它时,edgeModel表未显示任何边缘。

是因为我的表模式,还是我的代码有问题?

我该如何实现?

编辑:

因为似乎问题出在代码中的其他地方,所以这里是带有完整代码的仓库:https://github.com/jaro2gw/Graphy

c++ qt qtableview qsqltablemodel qsqlrelationaltablemodel
1个回答
0
投票

您的问题可能隐藏在项目中您未提供的其他地方,但没有隐藏在使用QSqlRelationalTableModel的代码中。

您的(注释)代码中只有一个最小的问题:两个替换的列将具有相同的名称:“名称”,但是您可以在定义QSqlRelation时重命名两个列。

这里是先生。以说明如何处理您的两个表和一个QSqlRelationalTableModel,以防万一其他人来stackoverflow询问类似的问题。

SQLite数据库转储:

PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE `vertex` (
        `ID`    INTEGER,
        `name`  TEXT,
        PRIMARY KEY(`ID`)
);
INSERT INTO vertex VALUES(1,'one');
INSERT INTO vertex VALUES(2,'two');
INSERT INTO vertex VALUES(3,'three');
INSERT INTO vertex VALUES(4,'four');
INSERT INTO vertex VALUES(5,'five');
INSERT INTO vertex VALUES(6,'six');
INSERT INTO vertex VALUES(7,'seven');
INSERT INTO vertex VALUES(8,'eight');
INSERT INTO vertex VALUES(9,'nine');
CREATE TABLE IF NOT EXISTS "edge" (
        "ID"    INTEGER,
        "sourceID"      INTEGER,
        "targetID"      INTEGER,
        FOREIGN KEY("targetID") REFERENCES "vertex"("ID"),
        PRIMARY KEY("ID"),
        FOREIGN KEY("sourceID") REFERENCES "vertex"("ID")
);
INSERT INTO edge VALUES(1,1,4);
INSERT INTO edge VALUES(2,2,5);
INSERT INTO edge VALUES(3,3,6);
INSERT INTO edge VALUES(4,4,7);
INSERT INTO edge VALUES(5,5,8);
INSERT INTO edge VALUES(6,6,9);
COMMIT;

test.pro

QT = core sql
CONFIG += c++11 console
SOURCES += main.cpp

main.cpp

#include <QCoreApplication>
#include <QTextStream>
#include <QSqlDatabase>
#include <QSqlError>
#include <QSqlRelationalTableModel>
#include <QSqlRecord>
#include <QSqlField>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QTextStream cout(stdout, QIODevice::WriteOnly);
    QTextStream cerr(stderr, QIODevice::WriteOnly);
    auto db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("test.db");
    if (!db.open()) {
        cerr << db.lastError().text() << endl;
        return 1;
    }

    QSqlRelationalTableModel model;
    model.setTable("edge");
    model.setRelation(1, QSqlRelation("vertex", "ID", "name as sourceName"));
    model.setRelation(2, QSqlRelation("vertex", "ID", "name as targetName"));
    model.select();
    auto rec = model.record();
    // headers output
    cout << qSetFieldWidth(15);
    for(int i=0; i<rec.count(); ++i) {
         cout << rec.field(i).name();
    }
    cout << endl;
    // rows output
    for(int i=0; i<model.rowCount(); ++i) {
        rec = model.record(i);
        cout << rec.value("ID").toInt() << rec.value("sourceName").toString() << rec.value("targetName").toString() << endl;
    }
}

这是程序的输出:

         ID     sourceName     targetName              
          1            one           four              
          2            two           five              
          3          three            six              
          4           four          seven              
          5           five          eight              
          6            six           nine         
© www.soinside.com 2019 - 2024. All rights reserved.