2016-09-08 16 views
1

ローカルのdb-FileからSQLデータをQML-Tableviewに表示し、SQLデータベースを編集したいと思っています。 約3週間後に私ができること:QML-Tableviewに自分のデータを表示する。私は本当にQSqlTableModelをサブクラス化する必要があるかどうかはわかりません。サブクラス化がまったく必要でない場合、私は間違いなく喜んでいます。サブクラス化QSqlTableModel新しい値を挿入

私のmain.cppで私のモデルを作成し、直接レコードを追加する必要があります。

// Create an instance of the SqlModel for accessing the data 
    SqlDataModel *sqlModel; 
    sqlModel = new SqlDataModel(0,base.database()); 
    sqlModel->setTable("diaBaneDatabase"); 
    sqlModel->setSort(0, Qt::AscendingOrder); 
    sqlModel->setEditStrategy(QSqlTableModel::OnFieldChange); 

    sqlModel->select(); 


    QSqlRecord record(sqlModel->record()); 
    record.setValue(0,50); 
    record.setValue(3,222); 
    sqlModel->insertRecord(-1, record); 
    sqlModel->submitAll(); 

これにより、4番目の列に222が追加されます。しかし、何が私のsqlDatabaseに保存されません

マイSqlDataModel :: setDataメソッドloolksこのように:

bool SqlDataModel::setData(const QModelIndex &index, const QVariant &value, int role) 
    { 
     qDebug() << index.column() << " " << index.row() << " " << value << " ---- " << role; 


     qDebug() << roles[Qt::UserRole + 1]; 

     //qDebug() << QSqlTableModel::setData(modelIndex, value); 

     qDebug() << QSqlQueryModel::setData(index, value); 
     return false; 

    } 

出力は次のようになります。

0  39  QVariant(int, 50) ---- 2 
    "id" 
    false 
    1  39  QVariant(QString, "") ---- 2 
    "id" 
    false 
    2  39  QVariant(QString, "") ---- 2 
    "id" 
    false 
    3  39  QVariant(int, 222) ---- 2 
    "id" 
    false 
    4  39  QVariant(double, 0) ---- 2 
    "id" 
    false 
    5  39  QVariant(int, 0) ---- 2 
    "id" 
    false 
    6  39  QVariant(double, 0) ---- 2 
    "id" 
    false 
    7  39  QVariant(double, 0) ---- 2 
    "id" 
    false 

私のsetDataメソッドが間違っていることを確認するために、私ドンそこで何が起こるべきかを理解していないし、これについての例は見つけられなかった。

QSqlTableModelをサブクラス化してモデルをQQmlContextを通してQMLに配置する必要があると誤っています。私の列名のような名前のロールで列を表示するのですか?そうでなければ私はQMLTableviewの列1の内容を置くことができる方法:

 TableViewColumn { 
      role: "id" // what should be the role if I don't subclass??? 
      title: "ID" 
      width: 80 
     } 

私は任意のヘルプ、コメント、たとえば、他の支柱またはさらに前方に私をもたらします何のために満足している...おかげ

+0

【こちら】(https://wiki.qt.io/QML_and_QSqlTableModel)あなたが良い例を持っています。 – Tarod

+0

残念ながら、この例は、SQLデータを表示しながら、私が見つけることができる最大限のように終わります。しかし、私が探しているのは、 "setData-Method"でSQLデータベースにデータを編集または追加することです。 –

+0

OK私はすべてが正しいと理解していないようです。 setDataをサブクラス化する必要はありません。私はこれを書きました: 'QSqlRecord record = sqlModel-> record(); record.setValue( "id"、87); // qDebug()<< record.fieldName(0)<< "_" << record.value(0); qDebug()<< sqlModel-> insertRecord(-1、record); qDebug()<< sqlModel-> submitAll(); 'これは時々ジョブを行いますが、submitAll()はfalseを返します。私はそれがときどき行を塗りつぶし、時にはうまくいかない理由を理解していません。 –

答えて

2

I一例を取り上げています。

いくつかの注意:

  • などTableViewなどQMLアイテムはモデルを必要とするので、私はQSqlTableModelは非常に良い選択肢だと思います。もちろん、データ項目を処理するために使用できるyou have other models
  • クラスMySqlTableModelには、必要なロール名が表示されます。 MySqlTableModelは、ロール名を公開するためにroleNames()を再実装し、QMLを介してアクセスできるようにします。
  • MySqlTableModelsetDataメソッドを再実装できますが、QSqlTableModelで提供されるメソッドinsertRecordを使用する方が良いと思います。

この例は、エラーを修正するのに役立ちます。

main.cppに

#include <QApplication> 
#include <QQmlApplicationEngine> 
#include <QQmlContext> 
#include "mysqltablemodel.h" 

int main(int argc, char *argv[]) 
{ 
    QApplication app(argc, argv); 

    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); 
    db.setDatabaseName("mydb"); 

    if(!db.open()) { 
     qDebug() << db.lastError().text(); 
     return 0; 
    } 

    QSqlQuery query(db); 

    if(!query.exec("DROP TABLE IF EXISTS mytable")) { 
     qDebug() << "create table error: " << query.lastError().text(); 
     return 0; 
    } 

    if(!query.exec("CREATE TABLE IF NOT EXISTS mytable \ 
        (id integer primary key autoincrement, name varchar(15), salary integer)")) { 
     qDebug() << "create table error: " << query.lastError().text(); 
     return 0; 
    } 

    MySqlTableModel *model = new MySqlTableModel(0, db); 
    model->setTable("mytable"); 
    model->setEditStrategy(QSqlTableModel::OnManualSubmit); 
    model->select(); 

    QSqlRecord rec = model->record(); 
    rec.setValue(1, "peter"); 
    rec.setValue(2, 100); 
    model->insertRecord(-1, rec); 
    rec.setValue(1, "luke"); 
    rec.setValue(2, 200); 
    model->insertRecord(-1, rec); 

    if(model->submitAll()) { 
     model->database().commit(); 
    } else { 
     model->database().rollback(); 
     qDebug() << "database error: " << model->lastError().text(); 
    } 

    QQmlApplicationEngine engine; 

    QQmlContext *ctxt = engine.rootContext(); 
    ctxt->setContextProperty("myModel", model); 

    engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); 

    return app.exec(); 
} 

mysqltablemodel.h

#ifndef MYSQLTABLEMODEL_H 
#define MYSQLTABLEMODEL_H 

#include <QSqlTableModel> 
#include <QSqlRecord> 
#include <QSqlError> 
#include <QSqlQuery> 
#include <QDebug> 

class MySqlTableModel : public QSqlTableModel 
{ 
    Q_OBJECT 

public: 
    MySqlTableModel(QObject *parent = 0, QSqlDatabase db = QSqlDatabase()); 
    Q_INVOKABLE QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const; 
    Q_INVOKABLE void addItem(const QString &name, const QString &salary); 

protected: 
    QHash<int, QByteArray> roleNames() const; 

private: 
    QHash<int, QByteArray> roles; 
}; 

#endif // MYSQLTABLEMODEL_H 

mysqltablemodel.cpp

#include "mysqltablemodel.h" 

MySqlTableModel::MySqlTableModel(QObject *parent, QSqlDatabase db): QSqlTableModel(parent, db) {} 

QVariant MySqlTableModel::data (const QModelIndex & index, int role) const 
{ 
    if(index.row() >= rowCount()) { 
     return QString(""); 
    } 
    if(role < Qt::UserRole) { 
     return QSqlQueryModel::data(index, role); 
    } 
    else { 
     return QSqlQueryModel::data(this->index(index.row(), role - Qt::UserRole), Qt::DisplayRole); 
    } 
} 

QHash<int, QByteArray> MySqlTableModel::roleNames() const 
{ 
    QHash<int, QByteArray> roles; 
    roles[Qt::UserRole + 1] = "name"; 
    roles[Qt::UserRole + 2] = "salary"; 
    return roles; 
} 

void MySqlTableModel::addItem(const QString &name, const QString &salary) 
{ 
    QSqlRecord rec = this->record(); 
    rec.setValue(1, name); 
    rec.setValue(2, salary.toInt()); 
    this->insertRecord(-1, rec); 

    if(this->submitAll()) { 
     this->database().commit(); 
    } else { 
     this->database().rollback(); 
     qDebug() << "database error: " << this->lastError().text(); 
    } 
} 

メイン。QML

import QtQuick 2.4 
import QtQuick.Controls 1.3 
import QtQuick.Window 2.2 
import QtQuick.Dialogs 1.2 

ApplicationWindow { 
    title: qsTr("Hello World") 
    width: 640 
    height: 480 
    visible: true 

    TableView { 
     id: tableView 

     anchors.fill: parent 

     TableViewColumn { 
      role: "name" 
      title: "Name" 
      width: 200 
     } 

     TableViewColumn { 
      role: "salary" 
      title: "Salary" 
      width: 200 
     } 

     model: myModel 
    } 

    Button { 
     id: addButton 

     anchors.verticalCenter: parent.verticalCenter 

     text: "Add item" 

     onClicked: { 
      if (nameBox.text || salaryBox.text) { 
       myModel.addItem(nameBox.text, salaryBox.text) 
      } 
     } 
    } 
    TextField { 
     id: nameBox 
     placeholderText: "name" 

     anchors.verticalCenter: parent.verticalCenter 
     anchors.left: addButton.right 
     anchors.leftMargin: 5 
    } 

    TextField { 
     id: salaryBox 
     placeholderText: "salary" 

     anchors.verticalCenter: parent.verticalCenter 
     anchors.left: nameBox.right 
     anchors.leftMargin: 5 
    } 
} 
+0

あなたのサブミット、コミットルーチンを使って、lastErrorが私の問題にすばやく導いてくれてありがとうございました!私はIDだけでデータベースを埋めるようにしようとしましたが、他の値は "NULL"でしたので、私のデータベースには許可されていません。すべての値を少なくとも0に設定すると、今は正常に動作します!私が言ったように、ありがとう! :) –

+0

私は手伝ってくれてうれしいです!良い仕事と幸せなコーディング! :) – Tarod

関連する問題