2017-08-27 90 views
0

我做了这个简单的对话框来显示我遇到的问题,对话框只是一个QTableViewQSqlRelationalTableModel。问题是我无法保存视图,即使数据更改不是任何相关表。但是如果我注释掉关系,就像下面的代码一样,我可以更新没有问题。当有外键在场时是否有额外的步骤来保存信息?更新关系表视图

PS。以防万一是重要的,我在网络上运行一个MySql服务器。

#include "xtest.h" 
#include "ui_xtest.h" 

XTest::XTest(QWidget *parent) : QDialog(parent), ui(new Ui::XTest) 
{ 
    ui->setupUi(this); 
    modelSuppliers=new QSqlRelationalTableModel(this); 
    modelSuppliers->setTable("supplier"); 
    modelSuppliers->setEditStrategy(QSqlTableModel::OnManualSubmit); 
    modelSuppliers->setHeaderData(0,Qt::Horizontal,"ID"); 
    modelSuppliers->setHeaderData(1,Qt::Horizontal,"Name"); 
    modelSuppliers->setHeaderData(2,Qt::Horizontal,"Address"); 
    modelSuppliers->setHeaderData(3,Qt::Horizontal,"Address1"); 
    modelSuppliers->setHeaderData(4,Qt::Horizontal,"City"); 
    modelSuppliers->setHeaderData(5,Qt::Horizontal,"User"); 
    modelSuppliers->setHeaderData(6,Qt::Horizontal,"Country"); 
    modelSuppliers->setHeaderData(7,Qt::Horizontal,"Sta/Reg"); 
    modelSuppliers->setHeaderData(8,Qt::Horizontal,"Active"); 
// modelSuppliers->setRelation(5,QSqlRelation("user","iduser","email")); 
// modelSuppliers->setRelation(6,QSqlRelation("country","idcountry","name")); 
// modelSuppliers->setRelation(7,QSqlRelation("sta_reg","idsta_reg","name")); 
    modelSuppliers->select(); 

    ui->suppliers->setModel(modelSuppliers); 
    ui->suppliers->resizeColumnsToContents(); 
    ui->suppliers->resizeRowsToContents(); 
    ui->suppliers->setItemDelegate(new QSqlRelationalDelegate(ui->suppliers)); 
    ui->suppliers->show(); 
} 

XTest::~XTest() 
{ 
    delete ui; 
} 

void XTest::on_save_clicked() 
{ 
    modelSuppliers->submitAll(); 
} 

我一直在玩这一段时间,我发现了一些可能相关的东西。我将模型更新之前的信号连接到一个显示行和QSqlRecord的函数。我做了两次关系“用户”激活的运行,另一次没有激活。在第5行,在我看来,模型试图用相关表的描述来更新记录,而不是用密钥。第二轮,更新的那个,在那个位置上有关键。这是QT的错误吗?

2 
QSqlRecord(9) 
0: QSqlField("idsupplier", int, length: 11, precision: 0, required: yes, generated: no, typeID: 3, autoValue: true, readOnly: false) "4" 
1: QSqlField("name", QString, length: 180, precision: 0, required: no, generated: no, typeID: 253, autoValue: false, readOnly: false) "Other" 
2: QSqlField("address", QString, length: 180, precision: 0, required: no, generated: no, typeID: 253, autoValue: false, readOnly: false) "Direccion" 
3: QSqlField("address1", QString, length: 180, precision: 0, required: no, generated: yes, typeID: 253, autoValue: false, readOnly: false) "dddd" 
4: QSqlField("city", QString, length: 180, precision: 0, required: no, generated: no, typeID: 253, autoValue: false, readOnly: false) "Santiago" 
5: QSqlField("iduser", int, length: 11, precision: 0, required: yes, generated: no, typeID: 3, autoValue: false, readOnly: false) "N/A" 
6: QSqlField("idcountry", int, length: 11, precision: 0, required: yes, generated: no, typeID: 3, autoValue: false, readOnly: false) "2" 
7: QSqlField("idsta_reg", int, length: 11, precision: 0, required: yes, generated: no, typeID: 3, autoValue: false, readOnly: false) "5" 
8: QSqlField("active", char, length: 4, precision: 0, required: no, generated: no, typeID: 1, autoValue: false, readOnly: false) "1" 
"" 

. 
    2 
    QSqlRecord(9) 
    0: QSqlField("idsupplier", int, length: 11, precision: 0, required: yes, generated: no, typeID: 3, autoValue: true, readOnly: false) "4" 
    1: QSqlField("name", QString, length: 180, precision: 0, required: no, generated: no, typeID: 253, autoValue: false, readOnly: false) "Other" 
    2: QSqlField("address", QString, length: 180, precision: 0, required: no, generated: no, typeID: 253, autoValue: false, readOnly: false) "Direccion" 
    3: QSqlField("address1", QString, length: 180, precision: 0, required: no, generated: yes, typeID: 253, autoValue: false, readOnly: false) "dddd" 
    4: QSqlField("city", QString, length: 180, precision: 0, required: no, generated: no, typeID: 253, autoValue: false, readOnly: false) "Santiago" 
    5: QSqlField("iduser", int, length: 11, precision: 0, required: yes, generated: no, typeID: 3, autoValue: false, readOnly: false) "1" 
    6: QSqlField("idcountry", int, length: 11, precision: 0, required: yes, generated: no, typeID: 3, autoValue: false, readOnly: false) "2" 
    7: QSqlField("idsta_reg", int, length: 11, precision: 0, required: yes, generated: no, typeID: 3, autoValue: false, readOnly: false) "5" 
    8: QSqlField("active", char, length: 4, precision: 0, required: no, generated: no, typeID: 1, autoValue: false, readOnly: false) "1" 

回答

-1

您还可以提供您的表格定义吗?这是SQLITE的一个最基本的工作示例。

mainwindow.cpp:

#include "mainwindow.hpp" 
#include "ui_mainwindow.h" 

#include <QSqlDatabase> 
#include <QSqlRelationalTableModel> 
#include <QSqlRelationalDelegate> 
#include <QSqlQuery> 
#include <QSqlError> 
#include <QFile> 
#include <QMessageBox> 

MainWindow::MainWindow(QWidget *parent) : 
    QMainWindow(parent), 
    ui(new Ui::MainWindow) 
{ 
    ui->setupUi(this); 

    QString fileName = "test.sqlite"; 
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); 
    db.setDatabaseName(fileName); 
    // This part is just to have sample data ... 
    if (!QFile(fileName).exists()) { 
     db.open(); 

     QSqlQuery query; 
     query.exec("DROP TABLE SUPPLIER"); 
     query.exec("DROP TABLE USER"); 

     query.exec("CREATE TABLE USER(id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(40) NOT NULL)"); 
     query.exec("CREATE TABLE SUPPLIER(id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(40) NOT NULL, userId INTEGER NOT NULL, FOREIGN KEY (userId) REFERENCES USER)"); 

     query.exec("INSERT INTO USER(name) VALUES('USER_1'), ('USER_2'), ('USER_3')"); 
     query.exec("INSERT INTO SUPPLIER(name, userId) VALUES('SUPPLIER_1', 1), ('SUPPLIER_2', 2), ('SUPPLIER_3', 3)"); 

     db.close(); 
    } 
    // End of part for sample data. 

    QSqlRelationalTableModel *model = new QSqlRelationalTableModel(this); 
    model->setTable("SUPPLIER"); 
    model->setEditStrategy(QSqlTableModel::OnManualSubmit); 
    model->setHeaderData(0,Qt::Horizontal,"ID"); 
    model->setHeaderData(1,Qt::Horizontal,"NAME"); 
    model->setRelation(2,QSqlRelation("USER", "id", "name")); 
    model->select(); 

    ui->tableView->setModel(model); 
    ui->tableView->setItemDelegate(new QSqlRelationalDelegate(this)); 

    connect(ui->pushButton, &QPushButton::clicked, [=]() { 
     model->submitAll(); 
    }); 
} 

MainWindow::~MainWindow() 
{ 
    delete ui; 
} 

mainwindow.ui:

<?xml version="1.0" encoding="UTF-8"?> 
<ui version="4.0"> 
<class>MainWindow</class> 
<widget class="QMainWindow" name="MainWindow"> 
    <property name="geometry"> 
    <rect> 
    <x>0</x> 
    <y>0</y> 
    <width>400</width> 
    <height>300</height> 
    </rect> 
    </property> 
    <property name="windowTitle"> 
    <string>MainWindow</string> 
    </property> 
    <widget class="QWidget" name="centralWidget"> 
    <layout class="QVBoxLayout" name="verticalLayout"> 
    <item> 
    <widget class="QTableView" name="tableView"/> 
    </item> 
    <item> 
    <widget class="QPushButton" name="pushButton"> 
     <property name="text"> 
     <string>Commit</string> 
     </property> 
    </widget> 
    </item> 
    </layout> 
    </widget> 
    <widget class="QMenuBar" name="menuBar"> 
    <property name="geometry"> 
    <rect> 
    <x>0</x> 
    <y>0</y> 
    <width>400</width> 
    <height>22</height> 
    </rect> 
    </property> 
    </widget> 
    <widget class="QToolBar" name="mainToolBar"> 
    <attribute name="toolBarArea"> 
    <enum>TopToolBarArea</enum> 
    </attribute> 
    <attribute name="toolBarBreak"> 
    <bool>false</bool> 
    </attribute> 
    </widget> 
    <widget class="QStatusBar" name="statusBar"/> 
</widget> 
<layoutdefault spacing="6" margin="11"/> 
<resources/> 
<connections/> 
</ui> 

希望帮助!

问候

+0

显示的.ui文件是没有必要的,在OP在谈论如何与QSqlRelationalTableModel做到这一点,利用QSqlQuery是这样做的一个老式的方法,因为它需要上千行的,而不是几十个,如果你正确使用QSqlRelationalTableModel。 – eyllanesc

+0

请阅读以下内容以改进您的答案。 [我如何写出一个好的答案?](https://stackoverflow.com/help/how-to-answer) – eyllanesc

+0

数据库是使用模型工具直接在MySql上创建的。'supplier',它只有一个主键有3个外键链接到OP中注释掉的表。 – Dan3460