4

私は次のことを実装しようとしています:

値を持つ2dテーブルがあります。データを表示して編集するための UI を実装する必要があります。UI からの編集とバックエンドからのテーブル更新との間の同期を簡素化するために、コミットされていない編集済みの値をモデルに保存し、保留中の変更を受け入れる/拒否するいくつかのメソッドを公開する必要があります。

私が理解していることから、これは QtWidgets + モデルでかなり簡単に行うことができます:

QAbstractTableModel の基本モデル。保留中の変更を保存/クエリするためのロールをいくつか追加します。QTableView をカスタム アイテム デリゲートで使用します。これにより、セルが編集可能かどうかをモデルにクエリしたり、コミットされていない変更を表示したりできます。

しかし、QtQuick.Controls.TableView を実装する方法については困惑しています。私の実験によると、TableView は QAbstractTableModel では機能しません。モデルの最初の列を反復処理し、ロールを使用して 2 番目の次元をシミュレートします。

TableView を QAbstractTableModel で正しく動作させる方法はありますか? 別の方法として、列にロールを使用するようにモデルを変更できますが、セル データの他の側面 (変更されたフラグ、コミットされていない値など) を処理する方法がわかりません。私がこれまでに持っている唯一のアイデアは、各セルの複合 (辞書) 値を返すことです。たとえば、QMap または QJsonObject を「cell」の値として返し、QML 側で解釈します。

それを行う他の方法はありますか?QMap と QJsonObject の 2 番目のソリューションを実装するとしたら、どちらがより効果的でしょうか?

4

1 に答える 1

1

これは一例ですが、参考になれば幸いです

「nom」(テキスト)、「prenom」(テキスト)、「image」(テキストとしてのURL)の3つの列を持つテーブル「mytable」を含むsqliteデータベースがあるとします。

--------------------------- PRESENCEMODEL.h

#include <QSqlTableModel>
typedef  QHash<int,QByteArray> qMyHash  ;

class PresenceModel : public QSqlTableModel {

    Q_OBJECT
    Q_PROPERTY(QStringList dictionary READ dictionary NOTIFY dictionaryChanged)
    Q_PROPERTY(QString filterString READ filterString WRITE setFilterString NOTIFY filterStringChanged)
    Q_PROPERTY(qMyHash roles READ roles NOTIFY rolesChanged)

public:

    PresenceModel(QSqlDatabase, QObject* parent = 0);
    void generateRoleNames();

    QString filterString() const { return p_filterString; }
    void setFilterString(const QString&);

    Q_INVOKABLE QStringList getData(int currentRow);

    QVariant data(const QModelIndex&, int role) const;

    Q_INVOKABLE void insert(const QString& url, const QString& title);
    void populate();

    QHash<int, QByteArray> roleNames() const;
    Q_INVOKABLE void p_setTable(const QString &tableName);
    QStringList dictionary() const;
    void setDictionary(const QStringList &value);
    QHash<int, QByteArray> roles() const;



Q_SIGNALS:

    void dataChanged();
    void gotData();

    void rolesChanged();

private:


    enum ColumnRH {
        nom= Qt::UserRole + 1,
        prenom= Qt::UserRole + 2,
        image= Qt::UserRole + 3
    };

    QHash<int, QByteArray> p_roles;
    QString p_filterString;
    QStringList p_dictionary;
};

--------------------------- PRESENCEMODEL.cpp

#include "presencemodel.h"
#include <QtCore/QDateTime>
#include <QtSql/QSqlError>
#include <QtSql/QSqlQuery>
#include <QtSql/QSqlRecord>
#include <QDebug>

PresenceModel::PresenceModel(QSqlDatabase database, QObject *parent)
    : QSqlTableModel(parent,  database)
{
}

void PresenceModel::generateRoleNames()
{

    p_roles[nom] = "nom";
    p_roles[prenom] = "prenom";
    p_roles[image] = "image";
}



void PresenceModel::populate()
{

    select();

}

void PresenceModel::insert(const QString& url, const QString& title)
{

}



QVariant PresenceModel::data(const QModelIndex& index, int role) const
{
    if (role < Qt::UserRole)
        return QSqlQueryModel::data(index, role);

    const int columnId = role - Qt::UserRole;
    const QModelIndex modelIndex = createIndex(index.row(), columnId-1);
    return QSqlTableModel::data(modelIndex, Qt::DisplayRole);

}



QStringList PresenceModel::getData(int currentRow)
{
    QStringList rowDataList;

    for (int i=0;i<columnCount();i++)

        rowDataList.append(data(this->index(currentRow,i),Qt::DisplayRole).toString());

    emit gotData();

    return rowDataList;
}


QHash<int, QByteArray> PresenceModel::roleNames() const
{
    return p_roles;
}


QHash<int, QByteArray> PresenceModel::roles() const
{
    return roleNames();
}

--------------------------- main.cpp

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

 QQmlApplicationEngine engine;

 QSqlDatabase m_database = QSqlDatabase::addDatabase("QSQLITE");

 m_database.setDatabaseName("/.../mydatabase.sqlite");


 PresenceModel  *p_pModel= new PresenceModel(m_database);

 p_pModel->setTable("mytable");

 m_database.open(); 

 QQmlContext *ctxt = engine.rootContext();

 ctxt->setContextProperty("ppModel", (PresenceModel*) p_pModel);

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

 return app.exec();

  }

QML

--------------------------- main.qml

Rectangle {

    Component.OnCompleted : ppModel.populate()
    TableView{
        id:tableview_actes
        TableViewColumn{ role: "nom"  ; title: "nom" ; width: 330 }
        TableViewColumn{ role: "prenom" ; title: "prénom" ; width: 65}
        TableViewColumn{ role: "image" ; title: "Photo" ; width:65}

        model:ppModel
        onCurrentRowChanged:  {
            var list=   myModel.getData(currentRow)   // invoke c++ function                                    

            console.log(list[0])



        }
        Listview{
            model:ppModel
            delegate:
                Item {
                Text{

                    text: nom + " " +prenom // our roles 
                }

                Image{
                    source : image // image : url in our table 
                }
            }


        }

    }
}
于 2014-03-08T04:57:50.510 に答える