【嵌入式——QT】QAbstractTableModel继承

发布时间:2024年01月12日

QT中表格制作继承QAbstractTableModel与重新相关方法示例,这边文章主要是给自己做一个记录。
当然这个是存在问题的,就是在表格中添加的复选框在debug模式下是可以选择的,但是在release模式下是不可以被选择的,当时我也在博客中提了问题,所以选择了另一种方式来实现复选框。

在Qt的QAbstractItemModel中,CheckStateRole用于处理与复选框相关的功能。默认情况下,CheckStateRole仅在编辑模式下可用,而在非编辑模式下是只读的。
当你在Debug模式下运行时,Qt会提供更多的开发者工具和信息,允许你查看和修改模型的各个属性和角色。因此,在Debug模式下,你可以选择CheckStateRole并更改其状态。
然而,在Release模式下,Qt会进行优化以提高性能和减小生成的可执行文件的大小。为此,Qt可能不会提供完整的开发者工具和信息,并且某些功能和角色可能会被禁用或限制。这就是为什么在Release模式下,CheckStateRole不能被选择和修改的原因。

如果你需要在Release模式下也能够选择CheckStateRole并进行操作,你可以考虑修改你的代码或自定义模型来满足你的需求。例如,你可以通过实现自定义的代理(QStyledItemDelegate或QItemDelegate)来处理复选框的状态,并根据用户操作更新模型数据

QStyledItemDelegate示例

需要重写的方法


    // 返回行个数
    int rowCount(const QModelIndex& parent = QModelIndex()) const override;
    // 返回列个数
    int columnCount(const QModelIndex& parent = QModelIndex()) const override;
    // 返回头文本
    QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
    // 返回索引数据
    QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
    // 返回模型索引
    QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override;
    // 返回模型索引的编辑方式
    Qt::ItemFlags flags(const QModelIndex& index) const override;
    // 设置模型索引数据
    bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override;
    // 插入行
    bool insertRows(int row, int count, const QModelIndex& parent = QModelIndex()) override;
    // 删除行
    bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex()) override;

完整代码
EditableTableModel.h

#pragma warning(disable:4819)
#ifndef EDITABLETABLEMODEL_H
#define EDITABLETABLEMODEL_H

#include <QObject>
#include <QAbstractTableModel>
#include <QCheckBox>
#include <QList>
#define COLUMN_NUM 10

enum COLUMN_HEAD_INDEX {
    CheckBox = 0,
    Id = 1,
    Format=2,
    Type=3,
    SendMode = 4,
    Length=5,
    Data=6,
    SendTimes=7,
    Interval=8,
    Count = 9,
    CANType = 10,
    BRS = 11
};


class EditableTableModel : public QAbstractTableModel
{
    Q_OBJECT
public:

    explicit EditableTableModel(QObject* parent, int column);

    // 返回行个数
    int rowCount(const QModelIndex& parent = QModelIndex()) const override;
    // 返回列个数
    int columnCount(const QModelIndex& parent = QModelIndex()) const override;
    // 返回头文本
    QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
    // 返回索引数据
    QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
    // 返回模型索引
    QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override;
    // 返回模型索引的编辑方式
    Qt::ItemFlags flags(const QModelIndex& index) const override;
    // 设置模型索引数据
    bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override;
    // 插入行
    bool insertRows(int row, int count, const QModelIndex& parent = QModelIndex()) override;
    // 删除行
    bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex()) override;



private:
    QList<int> m_CheckBox;
    QStringList m_Id;
    QStringList m_Alias;
    QStringList m_Format;
    QStringList m_Type;
    QStringList m_Length;
    QStringList m_Data;
    QStringList m_Frames;
    QStringList m_SendTimes;
    QStringList m_Interval;
    QStringList m_IDRule;
    QStringList m_DataRule;
    QStringList m_Comment;
    QStringList m_CANType;
    QStringList m_BRS;
    QStringList m_Count;
    QStringList m_SendMode;



    // 存储水平方向头数据
    QStringList m_HorizontalHead;

    int m_column;
};

#endif // EDITABLETABLEMODEL_H

EditableTableModel.cpp

#include "EditableTableModel.h"
#include <QDebug>
EditableTableModel::EditableTableModel(QObject* parent, int column)
    : QAbstractTableModel(parent),  m_column(column)
{
    this->m_HorizontalHead.append(tr(" "));
    this->m_HorizontalHead.append(tr("Id"));
    this->m_HorizontalHead.append(tr("Format"));
    this->m_HorizontalHead.append(tr("Type"));
    this->m_HorizontalHead.append(tr("SendMode"));
    this->m_HorizontalHead.append(tr("Length"));
    this->m_HorizontalHead.append(tr("Data(HEX)"));
    this->m_HorizontalHead.append(tr("Send Times"));
    this->m_HorizontalHead.append(tr("Interval(ms)"));
    this->m_HorizontalHead.append(tr("Count"));
    if(column > COLUMN_NUM) {
        this->m_HorizontalHead.append(tr("CANType"));
        this->m_HorizontalHead.append(tr("BRS"));
    }
}

int EditableTableModel::rowCount(const QModelIndex& parent) const
{
    // 某一列的数据个数即是行数
    return this->m_Id.size();
}

int EditableTableModel::columnCount(const QModelIndex& parent) const
{
    return m_column;
}

QVariant EditableTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if(role != Qt::DisplayRole) { // 返回一个默认数据的表头
        return QAbstractTableModel::headerData(section, orientation, role);
    }
    // 仅仅只是返回水平方向的表头
    if(orientation == Qt::Orientation::Horizontal) {
        return this->m_HorizontalHead[section];
    }
    return QAbstractTableModel::headerData(section, orientation, role);
}

QVariant EditableTableModel::data(const QModelIndex& index, int role) const
{
    // 不存在则返回默认
    if(!index.isValid()) {
        return QVariant();
    }
    // 如果角色为显示和编辑模式
    if(role == Qt::DisplayRole || role == Qt::EditRole) {
        switch(index.column()) {
            case Id:
                return this->m_Id[index.row()];
                break;
            case Format:
                return this->m_Format[index.row()];
                break;
            case Type:
                return this->m_Type[index.row()];
                break;
            case Length:
                return this->m_Length[index.row()];
                break;
            case Data:
                return this->m_Data[index.row()];
                break;
            case SendTimes:
                return this->m_SendTimes[index.row()];
                break;
            case Interval:
                return this->m_Interval[index.row()];
                break;
            case Count:
                return this->m_Count[index.row()];
                break;
            case CANType:
                return this->m_CANType[index.row()];
                break;
            case BRS:
                return this->m_BRS[index.row()];
                break;
            case SendMode:
                return this->m_SendMode[index.row()];
                break;
            default:
                break;
        }
    } else if(role == Qt::CheckStateRole) {
        switch(index.column()) {
            case CheckBox:
                return this->m_CheckBox[index.row()];
                break;
            default:
                break;
        }
    }
    return QVariant();
}

QModelIndex EditableTableModel::index(int row, int column, const QModelIndex& parent) const
{
    // 行和列的合法性检查
    if(row < 0 || row >= this->m_Id.size() || column < 0 || column >= m_column) {
        return QModelIndex();
    }
    QString str = "";
    switch(column) {
        case CheckBox:
            str = this->m_CheckBox[row];
            return  createIndex(row, column, &str);
            break;
        case Id:
            str= this->m_Id[row];
            return  createIndex(row, column, &str);
            break;
        case Format:
            str= this->m_Format[row];
            return  createIndex(row, column, &str);
            break;
        case Type:
            str= this->m_Type[row];
            return  createIndex(row, column, &str);
            break;
        case Length:
            str= this->m_Length[row];
            return  createIndex(row, column, &str);
            break;
        case Data:
            str= this->m_Data[row];
            return  createIndex(row, column, &str);
            break;
        case SendTimes:
            str= this->m_SendTimes[row];
            return  createIndex(row, column, &str);
            break;
        case Interval:
            str= this->m_Interval[row];
            return  createIndex(row, column, &str);
            break;
        case Count:
            str= this->m_Count[row];
            return  createIndex(row, column, &str);
            break;
        case CANType:
            str= this->m_CANType[row];
            return  createIndex(row, column, &str);
            break;
        case BRS:
            str= this->m_BRS[row];
            return  createIndex(row, column, &str);
            break;
        case SendMode:
            str= this->m_SendMode[row];
            return  createIndex(row, column, &str);
            break;
        default:
            break;
    }
    return createIndex(row, column);
}

Qt::ItemFlags EditableTableModel::flags(const QModelIndex& index) const
{
    if(!index.isValid()) {
        // 返回用户可以与界面进行交互
        return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    }
    // 返回用户可以进行编辑 ItemIsEnabled可以点击   ItemIsEditable可以编辑  ItemIsSelectable可以选中
    switch(index.column()) {
        case Id:
            return QAbstractItemModel::flags(index) | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;
            break;
        case Format:
            return QAbstractItemModel::flags(index) | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
            break;
        case Type:
            return QAbstractItemModel::flags(index) | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
            break;
        case Length:
            return QAbstractItemModel::flags(index) | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
            break;
        case Data:
            return QAbstractItemModel::flags(index) | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;
            break;
        case SendTimes:
            return QAbstractItemModel::flags(index) | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;
            break;
        case Interval:
            return QAbstractItemModel::flags(index) | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;
            break;
        case CANType:
            return QAbstractItemModel::flags(index) | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
            break;
        case BRS:
            return QAbstractItemModel::flags(index) | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
            break;
        case Count:
            return QAbstractItemModel::flags(index) | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
            break;
        case CheckBox:
            return QAbstractItemModel::flags(index) | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
            // return QAbstractItemModel::flags(index) | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;
            break;
        case SendMode:
            return QAbstractItemModel::flags(index) | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
            break;
        default:
            return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
            break;
    }
}

bool EditableTableModel::setData(const QModelIndex& index, const QVariant& value, int role)
{
    qDebug()<<"setData====value"<<value<<"role"<<role;
    if(index.isValid() && role == Qt::EditRole) {
        switch(index.column()) {
            case Id:
                this->m_Id[index.row()]= value.toString();
                break;
            case Format:
                this->m_Format[index.row()]= value.toString();
                break;
            case Type:
                this->m_Type[index.row()]= value.toString();
                break;
            case Length:
                this->m_Length[index.row()]= value.toString();
                break;
            case Data:
                this->m_Data[index.row()]= value.toString();
                break;
            case SendTimes:
                this->m_SendTimes[index.row()]= value.toString();
                break;
            case Interval:
                this->m_Interval[index.row()]= value.toString();
                break;
            case CANType:
                this->m_CANType[index.row()]= value.toString();
                break;
            case BRS:
                this->m_BRS[index.row()]= value.toString();
                break;
            case Count:
                this->m_Count[index.row()]= value.toString();
                break;
            case SendMode:
                this->m_SendMode[index.row()]= value.toString();
                break;
            default:
                break;
        }
        // 设置完成后发射信号告诉视图数据有修改
        emit dataChanged(index, index);
        return true;
    } else if(index.isValid() && role == Qt::CheckStateRole) {
        switch(index.column()) {
            case CheckBox:
                qDebug()<<"value.toString();"<<value.toString();
                this->m_CheckBox[index.row()] = value.toInt();
                break;
            default:
                break;
        }
        // 设置完成后发射信号告诉视图数据有修改
        emit dataChanged(index, index);
        return true;
    }
    return false;
}

bool EditableTableModel::insertRows(int row, int count, const QModelIndex& parent)
{
    // 如果插入零行,则返回false,表示插入失败
    if(count == 0) {
        return false;
    }
    // 没有父类
    if(!parent.isValid()) {
        // 从row开始插入行,直到row + count - 1处
        beginInsertRows(QModelIndex(), row, row + count - 1);
        // 有父类
    } else {
        // 从row开始插入行,直到row + count - 1处
        beginInsertRows(parent, row, row + count - 1);
    }
    // 按照位置在链表对应位置进行插入数据
    for(int addCount = 0; addCount < count; addCount++) {
        this->m_CheckBox.insert(row + addCount, 0);
        this->m_Id.insert(row + addCount, "");
        this->m_Format.insert(row + addCount, "");
        this->m_Type.insert(row + addCount, "");
        this->m_SendMode.insert(row + addCount, "");
        this->m_Length.insert(row + addCount, "");
        this->m_Data.insert(row + addCount, "");
        this->m_SendTimes.insert(row + addCount, "");
        this->m_Interval.insert(row + addCount, "");
        this->m_Count.insert(row + addCount, "");
        if(m_column > COLUMN_NUM) {
            this->m_CANType.insert(row + addCount, "");
            this->m_BRS.insert(row + addCount, "");
        }
    }
    // 结束插入行
    endInsertRows();
    return true;
}

bool EditableTableModel::removeRows(int row, int count, const QModelIndex& parent)
{
    if(count == 0) {
        return false;
    }
    if(!parent.isValid()) {
        beginRemoveRows(QModelIndex(), row, row + count - 1);
    } else {
        beginInsertRows(parent, row, row + count - 1);
    }
    // 按照位置在链表对应位置进行移除数据
    for(int removeCount = 0; removeCount < count; removeCount++) {
        this->m_CheckBox.removeAt(row);
        this->m_Id.removeAt(row);
        this->m_Format.removeAt(row);
        this->m_Type.removeAt(row);
        this->m_SendMode.removeAt(row);
        this->m_Length.removeAt(row);
        this->m_Data.removeAt(row);
        this->m_SendTimes.removeAt(row);
        this->m_Interval.removeAt(row);
        this->m_Count.removeAt(row);
        if(m_column > COLUMN_NUM) {
            this->m_CANType.removeAt(row);
            this->m_BRS.removeAt(row);
        }
    }
    endRemoveRows();
    return true;
}





文章来源:https://blog.csdn.net/weixin_39723539/article/details/135518087
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。