20200116-01 QML Table List 实现 delegate 基于 QT5.14

说明

在 QML 表格类实现类时 QWidget 那样的自定义委托(也就是插入自定义控件)
在这里插入图片描述
输出函数位于 testsub.cpp/ setValue 中

源码

//file: main.cpp
#include <QGuiApplication>
#include <QQmlAppliction>
#include "testsub.h"
#include "testModel.h"

Q_DECLARE_METATYPE(TestSub*) //向 QML 声明指针

int main(int argc, char *argv[]) {
    QGuiApplication app(argc, argv);
    
    qmlRegisterType<TestModel>("MyDataModel", 1, 0, "TableModel");
    qmlRegisterType<TestSub>();  //声明 TestSub 类型 Qt5.13 及以下版本使用
    //qmlRegisterAnonymousType<TestSub>("MyDataModel", 1): //声明 TestSub 类型 Qt5.14 启用
    
    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc::/main.qml"));
    return app.exec();
}

Q_DECLARE_METATYPE 主要用于向 QML 注册已经声明类型的指针样式
qmlRegisterType 向 QML 注册(继承 QObject) 的类型(不支持摸板)

//file: main.qml
/*
这部分请按照自身 Qt 版本添加
import QtQuick 2.14
import QtQuick.Controls 1.4
import MyDataModel 1.0
*/
Window {
    visible: true
    width: 300
    height: 480
    
    TableView {
        anchors.fill: parent
        model: TableModel {
            id: testModel
        }
        TableViewColumn {
            role: "set"  //取自 testmodel.cpp 中 roleNames() 函数定义
            width: 100
            delegate: TextInput {
                property value workObj: null
                anchors.fill: parent
                Component.onCompleted : {
                    workObj = testModel.getItem(styleData.row, styData.column) //styleData 是 TableView 在 delegate 中自带变量,具体可以看官方文档
                    text = workObj.value
                }
                onTextEdited: {
                    workObj.value =text
                }
            }
        }
    }
}

由于是自定义控件,就直接使用 styleData 变量的属性值即可,当然这里使用了比较老的 TableViewColumn 也可以使用其它最新控件,使用方式类似

//file: testmodel.h
#include <QAbstractTableModel>
#include "testsub.h"

class TestModel : public QAbstractTableModel 
{
    Q_OBJECT
    Q_ENUMS(TN) //向 QML 声明
    public:
        explicit TestModel(QObject *parent = nullptr);
        ~TestModel();
        
        enum TN {
            kSet = Qt::UserRole + 1, //由于 Qt 在宏已经定义了很多枚举类型,那么最好在 Qt::UserRole 之后再添加

        }
        
        int rowCount(const QModelIndex &parent = QModelIndex()) const override;
        int columnCount(const QModelIndex &parent = QModelIndex()) const override;
        QVariant data(const QModelIdex &index, int role = Qt::DisplayRole) const override;
        QHash<int, QByteArray> roleNames() const override;
        Q_INVOKABLE TestSub* getItem(const int& row, const int& columns);
        
    private:
        QList <QHash<int, TestSub*>> mRecords;
};

rowCount columnCOunt data 都是对父类的重写
roleNames() 是 QML 下最为重要的函数,在 QML 中没有列的概念通过 role 代替
Q_INVOKABLE 就是声明这是一个槽 与在 public slots 下声明效果一样

//file: testmodel.cpp
#include "testmodel.h"
TestModel::TestModel(QObject *parent) : QAbstractTableModel(parent) {
    int i = 0;
    for (int j = 0; j < 10; ++j ) {
        i++;
        QHash<int, TestSub*> t;
        t[0] = new TestSub(QString::number(i));
        mRecords.append(t);
    }
}

TestModel::~TestModel() {

}

int TestModel:: rowCount(const QModelIndex &parent) const {
    return mRecords.count();
}
/// \brief 由于在 QML 没有列的概念但是必须要返回一个 >0 的数字,所以选择 1 具体看官方文档说明
int TestModel::columnCount(const QModelIndex &parent) const {
    return 1;
}
/// \remark 这不我不需要使用其内部传值,所以直接返回空
QVariant TestModel:: data(const QModelIndex &index, int role) const {
    return QVariant();
}
/// \remark 向QML 注册role 的名称和个数
QHash<int, QByteArray> TestModel::roleNames() const {
    QHash<int, QByteArray> t;
    t[kSet] = "set";
    return t;
}

TestSub* TestModel::getItem(const int& row, const int& column) {
    return mRecords.at(row)[kSet+column);
}
//file: testsub.h
#include <QObject>
class TestSub: public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString value READ getValue WRITE setValue NOTIFY valueChanged)
    public:
        TestSub(const QString& _val, QObject *parent = nullptr);
        ~TestSub() ;
        
        QString getValue();
        void setValue(const QString& val);
        
    private:
        QString value;
};

//file: testsub.cpp
#include "testsub.h"
#include <QDebug>
TestSub::TestSub(const QString &_val, QObject *parent) : QObject (parent), value(_val) {
    
}
TestSub::~TestSub() {

}
QString TestSub::getValue() {
    return value;
}
void TestSub::setValue() {
    value = val;
    qDebug() << "set value :" << value;
    emit valueChanged();
}
发布了120 篇原创文章 · 获赞 27 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/qq_24890953/article/details/104005216
今日推荐