六、Qt widget应用、C++、qml混合编程之五————动态生成QML表格

    技术2022-07-12  102

    关键词:TableView,TableViewColumn,timerEvent 1、建立一个中间层TableModel类,更新qml图表的数据在这个类中完成,该类继承自QAbstractTableModel,主要是重写QAbstractTableModel类的如下方法:

    int rowCount(const QModelIndex &parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index,int role=Qt::DisplayRole) const override; QHash<int,QByteArray> roleNames() const override;

    2、TableModel.cpp代码如下: #include "tablemodel.h" #include "l_global.h"

    TableModel::TableModel(QObject *parent) : QAbstractTableModel(parent) {

     

    } TableModel::~TableModel() {

    }

    int TableModel::rowCount(const QModelIndex &parent) const{     Q_UNUSED(parent)     return m_aryData.size(); } int TableModel::columnCount(const QModelIndex &parent) const{     Q_UNUSED(parent)     return 3; }

    QVariant TableModel::data(const QModelIndex &index, int role) const{

        if(index.column()<0||columnCount()<=index.column()||             index.row()<0||rowCount()<=index.row())     {         return QVariant();     }

        switch(role)     {

        case role1:         return m_aryData[index.row()].at(0);     case role2:         return m_aryData[index.row()].at(1);     case role3:         return m_aryData[index.row()].at(2);     case role4:         return m_aryData[index.row()].at(3);     case role5:         return m_aryData[index.row()].at(4);     case role6:         return m_aryData[index.row()].at(5);     case role7:         return m_aryData[index.row()].at(6);     case role8:         return m_aryData[index.row()].at(7);     case role9:         return m_aryData[index.row()].at(8);     case role10:         return m_aryData[index.row()].at(9);     case role11:         return m_aryData[index.row()].at(10);     case role12:         return m_aryData[index.row()].at(11);     case role13:         return m_aryData[index.row()].at(12);     case role14:         return m_aryData[index.row()].at(13);     case role15:         return m_aryData[index.row()].at(14);     case role16:         return m_aryData[index.row()].at(15);     case role17:         return m_aryData[index.row()].at(16);     case role18:         return m_aryData[index.row()].at(17);     case role19:         return m_aryData[index.row()].at(18);     case role20:         return m_aryData[index.row()].at(19);     case role21:         return m_aryData[index.row()].at(20);     case role22:         return m_aryData[index.row()].at(21);     case role23:         return m_aryData[index.row()].at(22);     case role24:         return m_aryData[index.row()].at(23);     case role25:         return m_aryData[index.row()].at(24);     case role26:         return m_aryData[index.row()].at(26);     case role27:         return m_aryData[index.row()].at(26);     case role28:         return m_aryData[index.row()].at(27);     case role29:         return m_aryData[index.row()].at(28);     case role30:         return m_aryData[index.row()].at(29);     case role31:         return m_aryData[index.row()].at(30);     case role32:         return m_aryData[index.row()].at(31);     case role33:         return m_aryData[index.row()].at(32);     case role34:         return m_aryData[index.row()].at(33);     case role35:         return m_aryData[index.row()].at(34);     case role36:         return m_aryData[index.row()].at(35);     case role37:         return m_aryData[index.row()].at(36);     case role38:         return m_aryData[index.row()].at(37);     case role39:         return m_aryData[index.row()].at(38);     case role40:         return m_aryData[index.row()].at(39);     default:         return QVariant();     }

    } QHash<int,QByteArray> TableModel::roleNames() const {     QHash<int,QByteArray> roles;     roles[role1] = "r1";     roles[role2] = "r2";     roles[role3] = "r3";     roles[role4] = "r4";     roles[role5] = "r5";     roles[role6] = "r6";     roles[role7] = "r7";     roles[role8] = "r8";     roles[role9] = "r9";     roles[role10] = "r10";     roles[role11] = "r11";     roles[role12] = "r12";     roles[role13] = "r13";     roles[role14] = "r14";     roles[role15] = "r15";     roles[role16] = "r16";     roles[role17] = "r17";     roles[role18] = "r18";     roles[role19] = "r19";     roles[role20] = "r20";     roles[role21] = "r21";     roles[role22] = "r22";     roles[role23] = "r23";     roles[role24] = "r24";     roles[role25] = "r25";     roles[role26] = "r26";     roles[role27] = "r27";     roles[role28] = "r28";     roles[role29] = "r29";     roles[role30] = "r30";     roles[role31] = "r31";     roles[role32] = "r32";     roles[role33] = "r33";     roles[role34] = "r34";     roles[role35] = "r35";     roles[role36] = "r36";     roles[role37] = "r37";     roles[role38] = "r38";     roles[role39] = "r39";     roles[role40] = "r40";     return roles; }

    void TableModel::updateD(unsigned char *buffer) {     QString mValue("");     beginResetModel();     int temp;     for(int i= 0;i<colNum;i++)     {

        memcpy(&temp,buffer+i*4,4);     mValue = QString::number(temp);     m_aryData[1][i] = mValue;     }

        endResetModel(); } void TableModel::initTable(QList<QList<QVariant>> mlist) {

        m_aryData = mlist;     colNum = m_aryData.at(0).length();     rowNum = m_aryData.length();

    } 3、工程中添加一个全局头文件l_global.h,在头文件中添加如下代码,代码中的Role个数定义了表格中最大的列数,这个实例中设置了最大列数为40: enum Role{     role1 = Qt::UserRole,     role2,     role3,     role4,     role5,     role6,     role7,     role8,     role9,     role10,     role11,     role12,     role13,     role14,     role15,     role16,     role17,     role18,     role19,     role20,     role21,     role22,     role23,     role24,     role25,     role26,     role27,     role28,     role29,     role30,     role31,     role32,     role33,     role34,     role35,     role36,     role37,     role38,     role39,     role40

    };

    4、与之前讲到的实例类似,绑定数据源与QML表格,在MainWindow中添加代码:

        dataSource = new TableModel(viewer);     viewer->rootContext()->setContextProperty("Source", dataSource);

    5、为了动态生成QML表格的行数和列数,在MainWindow中添加代码:

    void MainWindow::genData() {

        QList<QList<QVariant>> marr;     QList<QVariant> headList;     QList<QVariant> valList;     QList<int> mwidth;     for(int i=0;i<10;i++)     {         headList.append("参数"+QString::number(i));         valList.append("");         mwidth.append(200);     }     marr.append(headList);     marr.append(valList);     QVariantList mroles;     for(int i=0;i<marr.at(0).length();i++){         mroles.append("r"+QString::number(i+1));     }     dataSource->initTable(marr);     QMetaObject::invokeMethod(obj, "refreshData",                               Q_ARG(QVariant, QVariant::fromValue(mwidth)),                               Q_ARG(QVariant, QVariant::fromValue(mroles)),                               Q_ARG(QVariant, QVariant::fromValue(marr.length()))); }

    6、为了动态生成QML表格,在main.qml中加入代码:     function refreshData(arr1,arr2,row){   //动态创建列

            mytable.updateColumnTable(arr1,arr2,row);     }     这个方法调用的是ParaView.qml中的方法updateColumnTable; 7、ParaView.qml的代码如下: import QtQuick 2.3 import QtQuick.Layouts 1.0 import QtQuick.Controls 1.3 import QtQuick.Controls 2.2

    Item {     width: parent.width

        property int i: 0     property string str: ""     property int mheight: 200     TableView {         id:tableview         frameVisible: false         horizontalScrollBarPolicy:             Qt.ScrollBarAlwaysOff         verticalScrollBarPolicy:             Qt.ScrollBarAlwaysOff         backgroundVisible: false         width: parent.width         height: mheight      //等于行高度×行数+边线高度×边线个数

            headerDelegate: headerDele         rowDelegate:rowDele         itemDelegate:itemDele

     

            contentFooter: Rectangle{             width: tableview.width;             height: 2             color:"white"         }

            Component{             id:headerDele             Rectangle             {                 width: tableview.width;                 height: 2                 color:"white"             }         }

            Component{             id:itemDele             Rectangle{                 id:tableCell                 anchors.leftMargin: 0                 anchors.rightMargin: 0                 anchors.fill: parent; //                anchors.margins: 0;                 color: "#00000000"                 border.color: "white"                 border.width: 2                 Text{                     anchors.fill: parent                     horizontalAlignment: Text.AlignHCenter                     verticalAlignment: Text.AlignVCenter                     text: styleData.value                     color: "white"                     font:Qt.font({weight:Font.Bold,italic:true,pointSize:18})                 }             }         }

            Component{             id:rowDele             Rectangle{                 height: 50                 color: "#00000000"                 border.color: "white"                 border.width: 2

                    ControlR {                     id:rect1                     m_x:0                 }

                    ControlR {                     id:rect2                     m_x:tableview.width-4                 }

                }

            }

            model: Source     }

        function updateColumnTable(arr1,arr2,row){     //动态创建列         var arrayWidth = arr1;         var arrayRoles = arr2;         var rownum = row         var sum = 0;         for(i=0;i<arrayWidth.length;i++){             sum += arrayWidth[i];         }

            var prefix = 'import QtQuick 2.7;import QtQuick.Controls 1.4;TableViewColumn {width:Math.round(tableview.width *';

            for(i=0;i<arrayWidth.length;i++){             str = prefix + arrayWidth[i]/sum +");role:\"" + arrayRoles[i] +"\"}";             tableview.addColumn(Qt.createQmlObject(str,tableview,"dynamicTable"));         }         mheight = rownum*(50+4)     }

    }

    8、在MainWindow.cpp中通过一个定时器,把值传给中间层TableModel类,从而完成QML表格的实时更新数据: void MainWindow::timerEvent(QTimerEvent *event) {     for(int i=0;i<10;i++)     {         memcpy(buff+i*4,&mvalue,4);         mvalue++;     }     dataSource->updateD(buff); }

    需要观看运行效果或需要完整源代码,请到www.toutiao.com/i6844549599001051659/链接评论区写上你的邮箱

     

    Processed: 0.037, SQL: 9