学习QT之模型(Model)

本文介绍如何在Qt中通过继承QAbstractTableModel类实现自定义数据模型,展示了一个具体的代码示例,包括如何使用QMap关联数据代码和真实含义,以及如何通过虚函数设置行列数和数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实现自定义模型可以通过QAbstractItemModel类继承,也可以通过QAbstractListModel和QAbstractTableModel类继承实现列表模型或者表格模型。
在数据库中,通常需要首先将一些复杂的文字字段使用数据代码保存,然后通过外键关联操作来查找其真实的含义,这一方法是为了避免冗余。

一、效果展示

在这里插入图片描述

二、具体代码

modelexample.h

#ifndef MODELEXAMPLE_H
#define MODELEXAMPLE_H

#include <QAbstractTableModel>
#include <QVector>
#include <QMap>
#include <QStringList>

class ModelExample : public QAbstractTableModel
{
public:
    explicit ModelExample(QObject *parent = 0);
    //虚函数声明
    virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
    virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
    QVariant data(const QModelIndex &index, int role) const;
    QVariant headerData(int section, Qt::Orientation orientation, int role) const;

private:
    QVector<short> army;
    QVector<short> weaponType;
    QMap<short,QString> armyMap;
    QMap<short,QString> weaponTypeMap;
    QStringList weapon;
    QStringList header;
    void populateModel();
};

#endif // MODELEXAMPLE_H

注意rowCount()、columnCount()、data()和返回表头数据的headerData()函数是QAbstractTableModel类的纯虚函数。
modelexample.cpp

#include "modelexample.h"

ModelExample::ModelExample(QObject *parent) : QAbstractTableModel(parent)
{
    armyMap[1]=tr("空军");
    armyMap[2]=tr("海军");
    armyMap[3]=tr("陆军");
    armyMap[4]=tr("海军陆站队");
    weaponTypeMap[1]=tr("轰战机");
    weaponTypeMap[2]=tr("战斗机");
    weaponTypeMap[3]=tr("航空母舰");
    weaponTypeMap[4]=tr("驱逐舰");
    weaponTypeMap[5]=tr("直升机");
    weaponTypeMap[6]=tr("坦克");
    weaponTypeMap[7]=tr("两栖攻击舰");
    weaponTypeMap[8]=tr("两栖战车");
    populateModel();
}

void ModelExample::populateModel()
{
    header<<tr("军种")<<tr("种类")<<tr("武器");
    army<<1<<2<<3<<4<<2<<4<<3<<1;
    weaponType<<1<<3<<5<<7<<4<<8<<6<<2;
    weapon<<tr("B-2")<<tr("尼米磁级")<<tr("阿帕奇")<<tr("黄蜂级")<<tr("阿利伯克级")<<tr("AAAV")<<tr("M1A1")<<tr("F-22");
}

int ModelExample::columnCount(const QModelIndex &parent) const
{
    return 3;
}

int ModelExample::rowCount(const QModelIndex &parent) const
{
    return army.size();
}

QVariant ModelExample::data(const QModelIndex &index, int role) const
{
    if(!index.isValid())
        return QVariant();
    if(role==Qt::DisplayRole)  //(a)
    {
        switch (index.column()) {
        case 0:
            return armyMap[army[index.row()]];
            break;
        case 1:
            return weaponTypeMap[weaponType[index.row()]];
            break;
        case 2:
            return weapon[index.row()];
            break;
        default:
            return QVariant();
        }
    }

    return QVariant();
}

QVariant ModelExample::headerData(int section, Qt::Orientation orientation, int role) const
{
    if(role==Qt::DisplayRole && orientation==Qt::Horizontal)
    {
        return header[section];
    }

    return QAbstractTableModel::headerData(section,orientation,role);
}

注意
(a):role==Qt::DisplayRole:模型中的条目能够有不同的角色,这样可以在不同的情况下提供不同的数据。例如,Qt::DisplayRole用来存取视图中显示的文字,角色由枚举类Qt::ItemDataRole定义。
下表列出了Item主要的角色及其描述:

常量描述
Qt::DisplayRole显示文字
Qt::DecorationRole绘制装饰数据(通常是图标)
Qt::EditRole在编辑器中编辑的数据
Qt::ToolTipRole工具提示
Qt::StatusTipRole状态栏提示
Qt::WhatsThisRoleWhat’s This文字
Qt::SizeHintRole尺寸提示
Qt::FontRole默认代理的绘制使用的字体
Qt::TextAlignmentRole默认代理的对齐方式
Qt::BackgroundRole默认代理的背景画刷
Qt::ForegroundRole默认代理的前景画刷
Qt::CheckStateRole默认代理的检查框状态
Qt::UserRole用户自定义的数据的起始位置
main.cpp
#include "modelexample.h".h"
#include <QApplication>
#include <QTableView>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    ModelExample modelEx;
    QTableView view;
    view.setModel(&modelEx);
    view.setWindowTitle(QObject::tr("ModelEx"));
    view.resize(400,400);
    view.show();
    return a.exec();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

贝勒里恩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值