当前位置: 首页 > news >正文

微网站作用宁波seo搜索引擎优化公司

微网站作用,宁波seo搜索引擎优化公司,抖音餐厅代运营方案,ps网页模板前言 此篇博客写的小项目与之前写的一篇《QTableWidget》类似,只是使用了不同的方法进行实现。但是推荐使用此篇播放的方法;因为高效,低耗能。 当然,项目中还涉及到使用委托添加控件,即在单元格中添加控件&#xff0…

前言

此篇博客写的小项目与之前写的一篇《QTableWidget》类似,只是使用了不同的方法进行实现。但是推荐使用此篇播放的方法;因为高效,低耗能。

当然,项目中还涉及到使用委托添加控件,即在单元格中添加控件,使其双击后才显示出来。 具体操作请看此篇博客:使用委托QItemDelegate 于 QTableView单元格添加控件。

QAbstractTableModel的父类QABstractItemModel,他从父类中继承下来了大量方法,我们需要使用该类的话,也是需要继承与他(QAbstractTableModel),然后进行重写其里面的方法。

项目实现效果:
在这里插入图片描述
在这里插入图片描述

总体来说,继承于QAbstractTableModel实现起来还是蛮容易的,重写方法,根据自己的项目需求进行编写,对于数据的管理也是挺友好的。
相比于QTableWidget,QAbstractTableModel使用的内存更少,数据管理更方便。


定义

需要包含头文件:#include <QAbstractTableModel>

  1. 继承自QAbstractTableModel

    class TableModel : public QAbstractTableModel {
    public:// ...private:// 16列,对应16个链表存储数据QStringList m_No;QStringList m_Reference;QStringList m_X;QStringList m_Y;QStringList m_Z;QStringList m_R;QStringList m_Part;QStringList m_Feeder;QStringList m_Nozzle;QStringList m_HD;QMap<int, Qt::CheckState> m_CS;QStringList m_CY;QMap<int, Qt::CheckState> m_SK;QStringList m_AR;QMap<int, Qt::CheckState> m_FID;QStringList m_BL;// 存储水平方向头数据QStringList m_HorizontalHead;
    }
    

    这里我们需求是有16列,所以得定义16个数据变量来存储。

  2. 重写以下方法

    // 返回行个数
    virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    // 返回列个数
    virtual int columnCount(const QModelIndex &parent = QModelIndex()) const override;
    // 返回头文本
    virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
    // 返回索引数据
    virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
    // 返回模型索引
    virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
    // 返回模型索引的编辑方式
    virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
    // 设置模型索引数据
    virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
    // 插入行
    virtual bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
    // 删除行
    virtual bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
    
  3. 实现方法体
    (1). rowCount
    此方法的作用:见名之意,此方法是返回行的个数。

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

    (2). columnCount
    此方法的作用:见名之意,此方法是返回列的个数。

    // 返回列个数
    int TableModel::columnCount(const QModelIndex &parent) const {
    // 项目代码中,我们再头文件里写了一个对于列表头索引的枚举,所以这里直接使用枚举的个数来进行返回。return COLUMN_HEAD_INDEX::COLUMN;
    }
    

    (3). headerData
    此方法的作用:设置表头文本,并返回文本内容

    // 返回头文本
    QVariant TableModel::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);
    }
    

    根据参数role角色判定,再进行下一步操作。

    (4). data
    此方法的作用:返回索引的数据。

    // 返回索引数据
    QVariant TableModel::data(const QModelIndex &index, int role) const {// 不存在则返回默认if (!index.isValid()) return QVariant();// 如果角色为显示和编辑模式if (role == Qt::DisplayRole || role == Qt::EditRole) {// 此处省略一万行代码...// 否则如果角色为选中模式(即多选框)} else if (role == Qt::CheckStateRole) {// 此处省略一万行代码...}return QVariant();
    }
    

    省略处的代码将在下方进行展示。每个参数都有其特殊意义。

    (5). index
    此方法的作用:返回行和列对应单元格的索引。

    // 返回模型索引
    QModelIndex TableModel::index(int row, int column, const QModelIndex &parent) const {// 行和列的合法性检查if (row < 0 || row >= this->m_No.size() || column < 0 || column >= COLUMN_HEAD_INDEX::COLUMN) {return QModelIndex();}// 此处省略一万行代码...// 新建一个索引并绑定指针数据返回(指针数据可有可无)// return createIndex(row, column);return createIndex(row, column);
    }
    

    省略处的代码将在下方进行展示。根据行和列新建一个索引并返回。

    (6). flags
    此方法的作用:根据索引,返回其的编辑模式。

    // 返回模型索引的编辑方式
    Qt::ItemFlags TableModel::flags(const QModelIndex &index) const {if (!index.isValid()) {// 返回用户可以与界面进行交互return Qt::ItemIsEnabled | Qt::ItemIsSelectable;}// 此处省略一万行代码...	// 返回用户可以进行编辑// return QAbstractItemModel::flags(index) | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    }
    

    省略处的代码将在下方进行展示。根据索引的列返回编辑方式。

    (7). setData
    此方法的作用:将参数value索引存入对应列的数据变量中。

    // 设置模型索引数据
    bool TableModel::setData(const QModelIndex &index, const QVariant &value, int role) {if (index.isValid() && role == Qt::EditRole) {// 此处省略一万行代码...// 设置完成后发射信号告诉视图数据有修改emit dataChanged(index, index);	// 参数是左上角和右下角的模型索引(这里是相同的)return true;} else if (index.isValid() && role == Qt::CheckStateRole) {// 此处省略一万行代码...// 设置完成后发射信号告诉视图数据有修改emit dataChanged(index, index);	// 参数是左上角和右下角的模型索引(这里是相同的)return true;}return false;
    }
    

    省略处的代码将在下方进行展示。存储完后,得发射信号,告诉视图数据有修改。

    (8). insertRows
    此方法的作用:插入一行或多行数据。

    // 插入行	参数:插入的位置;插入的行数;父项的模型索引
    bool TableModel::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_No.insert(row + addCount, "");this->m_Reference.insert(row + addCount, "");this->m_X.insert(row + addCount, "");this->m_Y.insert(row + addCount, "");this->m_Z.insert(row + addCount, "");this->m_R.insert(row + addCount, "");this->m_Part.insert(row + addCount, "");this->m_Feeder.insert(row + addCount, "");this->m_Nozzle.insert(row + addCount, "");this->m_HD.insert(row + addCount, "");this->m_CS.insert(row + addCount, Qt::CheckState::Unchecked);this->m_CY.insert(row + addCount, "");this->m_SK.insert(row + addCount, Qt::CheckState::Unchecked);this->m_AR.insert(row + addCount, "");this->m_FID.insert(row + addCount, Qt::CheckState::Unchecked);this->m_BL.insert(row + addCount, "");}// 结束插入行endInsertRows();return true;
    }
    

    使用beginInsertRows()开始插入,endInsertRows()结束插入。
    插入后,存储数据的链表也得对应插入空数据,或者插入默认数据;这才能保证数据的同步性。

    (9). removeRows
    此方法的作用:删除一行或者多行数据。

    // 删除行
    bool TableModel::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_No.removeAt(row);this->m_Reference.removeAt(row);this->m_X.removeAt(row);this->m_Y.removeAt(row);this->m_Z.removeAt(row);this->m_R.removeAt(row);this->m_Part.removeAt(row);this->m_Feeder.removeAt(row);this->m_Nozzle.removeAt(row);this->m_HD.removeAt(row);this->m_CS.remove(row + removeCount);this->m_CY.removeAt(row);this->m_SK.remove(row + removeCount);this->m_AR.removeAt(row);this->m_FID.remove(row + removeCount);this->m_BL.removeAt(row);}endRemoveRows();return true;
    }
    

    使用beginRemoveRows()开始删除,endRemoveRows()结束删除。
    删除后,存储数据的链表也得删除对应的数据;这才能保证数据的同步性。

好了,到了这里,说明前期准备工作已经做得差不多了,接下来就可以去使用这个类了。


使用

另外新建类HzcTableEdit

ui文件:
在这里插入图片描述

再构造函数中new对象将其与TableView进行绑定即可。

TableModel *m_tableModel = new TableModel;
ui.tableView->setModel(this->m_tableModel);

至于插入、删除等功能,实现按钮的槽方法,再使用m_tableModel对象调用插入和删除的方法即可;具体实现按照具体项目需求即可。

QTableView 零碎知识点

设置水平头文本居中
ui.tableView->horizontalHeader()->setDefaultAlignment(Qt::AlignHCenter);

设置隔行变色
ui.tableView->setAlternatingRowColors(true);

设置最后一列填满表格剩余空间
ui.tableView->horizontalHeader()->setStretchLastSection(true);

设置表格行高
ui.tableView->verticalHeader()->setDefaultSectionSize(30);

设置表格列宽
ui.tableView->setColumnWidth(column, 40);

设置用户可以拖动行
ui.tableView->verticalHeader()->setSectionsMovable(true);

设置固定行高
ui.tableView->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed);
ui.tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);

设置表头样式表颜色

// 设置行表头背景颜色样式为浅黄色
ui.tableView->horizontalHeader()->setStyleSheet("QHeaderView::section{background:#ffff9b;}");
// 设置列表头背景颜色样式为浅蓝色
ui.tableView->verticalHeader()->setStyleSheet("QHeaderView::section{background:#a7fffa;}");
// 设置左上角两个表头相交的区域的颜色样式为浅灰色
ui.tableView->setStyleSheet("QTableCornerButton::section{background:#c2c2c2;}");

全部实现代码

TableModel.h

#pragma once
#include <QAbstractTableModel>#pragma execution_character_set("utf-8") // qt支持显示中文enum COLUMN_HEAD_INDEX {No = 0,Reference = 1,X = 2,Y = 3,Z = 4,R = 5,Part = 6,Feeder = 7,Nozzle = 8,HD = 9,CS = 10,CY = 11,SK = 12,AR = 13,FID = 14,BL = 15,COLUMN = 16
};class TableModel : public QAbstractTableModel {public:TableModel(QAbstractTableModel *parent = nullptr);~TableModel();// 返回行个数virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override;// 返回列个数virtual int columnCount(const QModelIndex &parent = QModelIndex()) const override;// 返回头文本virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;// 返回索引数据virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;// 返回模型索引virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;// 返回模型索引的编辑方式virtual Qt::ItemFlags flags(const QModelIndex &index) const override;// 设置模型索引数据virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;// 插入行virtual bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;// 删除行virtual bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;private:// 16列,对应16个链表存储数据QStringList m_No;QStringList m_Reference;QStringList m_X;QStringList m_Y;QStringList m_Z;QStringList m_R;QStringList m_Part;QStringList m_Feeder;QStringList m_Nozzle;QStringList m_HD;QMap<int, Qt::CheckState> m_CS;QStringList m_CY;QMap<int, Qt::CheckState> m_SK;QStringList m_AR;QMap<int, Qt::CheckState> m_FID;QStringList m_BL;// 存储水平方向头数据QStringList m_HorizontalHead;
};

TableModel.cpp

#include "TableModel.h"TableModel::TableModel(QAbstractTableModel *parent) : QAbstractTableModel(parent) {this->m_HorizontalHead.append("No.");this->m_HorizontalHead.append("Reference");this->m_HorizontalHead.append("X");this->m_HorizontalHead.append("Y");this->m_HorizontalHead.append("Z");this->m_HorizontalHead.append("R");this->m_HorizontalHead.append("Part");this->m_HorizontalHead.append("Feeder");this->m_HorizontalHead.append("Nozzle");this->m_HorizontalHead.append("HD");this->m_HorizontalHead.append("CS");this->m_HorizontalHead.append("CY");this->m_HorizontalHead.append("SK");this->m_HorizontalHead.append("AR");this->m_HorizontalHead.append("FID");this->m_HorizontalHead.append("BL");
}TableModel::~TableModel() {}// 返回行个数
int TableModel::rowCount(const QModelIndex &parent) const {return this->m_No.size();
}// 返回列个数
int TableModel::columnCount(const QModelIndex &parent) const {return COLUMN_HEAD_INDEX::COLUMN;
}// 返回头文本
QVariant TableModel::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 TableModel::data(const QModelIndex &index, int role) const {// 不存在则返回默认if (!index.isValid()) return QVariant();if (role == Qt::DisplayRole || role == Qt::EditRole) {switch (index.column()) {case COLUMN_HEAD_INDEX::No:return this->m_No[index.row()];break;case COLUMN_HEAD_INDEX::Reference:return this->m_Reference[index.row()];break;case COLUMN_HEAD_INDEX::X:return this->m_X[index.row()];break;case COLUMN_HEAD_INDEX::Y:return this->m_Y[index.row()];break;case COLUMN_HEAD_INDEX::Z:return this->m_Z[index.row()];break;case COLUMN_HEAD_INDEX::R:return this->m_R[index.row()];break;case COLUMN_HEAD_INDEX::Part:return this->m_Part[index.row()];break;case COLUMN_HEAD_INDEX::Feeder:return this->m_Feeder[index.row()];break;case COLUMN_HEAD_INDEX::Nozzle:return this->m_Nozzle[index.row()];break;case COLUMN_HEAD_INDEX::HD:return this->m_HD[index.row()];break;case COLUMN_HEAD_INDEX::CY:return this->m_CY[index.row()];break;case COLUMN_HEAD_INDEX::AR:return this->m_AR[index.row()];break;case COLUMN_HEAD_INDEX::BL:return this->m_BL[index.row()];default:return QVariant();break;}} else if (role == Qt::CheckStateRole) {switch (index.column()) {case COLUMN_HEAD_INDEX::CS:return this->m_CS[index.row()] == Qt::Checked ? Qt::Checked : Qt::Unchecked;break;case COLUMN_HEAD_INDEX::SK:return this->m_SK[index.row()] == Qt::Checked ? Qt::Checked : Qt::Unchecked;break;case COLUMN_HEAD_INDEX::FID:return this->m_FID[index.row()] == Qt::Checked ? Qt::Checked : Qt::Unchecked;break;default:return QVariant();break;}}return QVariant();
}// 返回模型索引
QModelIndex TableModel::index(int row, int column, const QModelIndex &parent) const {// 行和列的合法性检查if (row < 0 || row >= this->m_No.size() || column < 0 || column >= COLUMN_HEAD_INDEX::COLUMN) {return QModelIndex();}switch (column) {case COLUMN_HEAD_INDEX::No:// 获取对应行和列单元格的数据//QString str = this->m_No[row];// 新建一个索引并绑定指针数据返回return createIndex(row, column/*, &str*/);break;case COLUMN_HEAD_INDEX::Reference://QString str = this->m_Reference[row];return createIndex(row, column/*, &str*/);break;case COLUMN_HEAD_INDEX::X://QString str = this->m_X[row];return createIndex(row, column/*, &str*/);break;case COLUMN_HEAD_INDEX::Y://QString str = this->m_Y[row];return createIndex(row, column/*, &str*/);break;case COLUMN_HEAD_INDEX::Z://QString str = this->m_Z[row];return createIndex(row, column/*, &str*/);break;case COLUMN_HEAD_INDEX::R://QString str = this->m_R[row];return createIndex(row, column/*, &str*/);break;case COLUMN_HEAD_INDEX::Part://QString str = this->m_Part[row];return createIndex(row, column/*, &str*/);break;case COLUMN_HEAD_INDEX::Feeder://QString str = this->m_Feeder[row];return createIndex(row, column/*, &str*/);break;case COLUMN_HEAD_INDEX::Nozzle://QString str = this->m_Nozzle[row];return createIndex(row, column/*, &str*/);break;case COLUMN_HEAD_INDEX::HD://QString str = this->m_HD[row];return createIndex(row, column/*, &str*/);break;case COLUMN_HEAD_INDEX::CS://QString str = this->m_CS[row];return createIndex(row, column/*, &str*/);break;case COLUMN_HEAD_INDEX::CY://QString str = this->m_CY[row];return createIndex(row, column/*, &str*/);break;case COLUMN_HEAD_INDEX::SK://QString str = this->m_SK[row];return createIndex(row, column/*, &str*/);break;case COLUMN_HEAD_INDEX::AR://QString str = this->m_AR[row];return createIndex(row, column/*, &str*/);break;case COLUMN_HEAD_INDEX::FID://QString str = this->m_FID[row];return createIndex(row, column/*, &str*/);break;case COLUMN_HEAD_INDEX::BL://QString str = this->m_BL[row];return createIndex(row, column/*, &str*/);break;default:return createIndex(row, column);break;}return createIndex(row, column);
}// 返回模型索引的编辑方式
Qt::ItemFlags TableModel::flags(const QModelIndex &index) const {if (!index.isValid()) {// 返回用户可以与界面进行交互return Qt::ItemIsEnabled | Qt::ItemIsSelectable;}switch (index.column()) {case COLUMN_HEAD_INDEX::No:// 返回用户可以与界面进行交互return Qt::ItemIsEnabled | Qt::ItemIsSelectable;break;case COLUMN_HEAD_INDEX::Reference:// 返回用户可以进行编辑return QAbstractItemModel::flags(index) | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;break;case COLUMN_HEAD_INDEX::X:return QAbstractItemModel::flags(index) | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;break;case COLUMN_HEAD_INDEX::Y:return QAbstractItemModel::flags(index) | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;break;case COLUMN_HEAD_INDEX::Z:return QAbstractItemModel::flags(index) | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;break;case COLUMN_HEAD_INDEX::R:return QAbstractItemModel::flags(index) | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;break;case COLUMN_HEAD_INDEX::Part:return QAbstractItemModel::flags(index) | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;break;case COLUMN_HEAD_INDEX::Feeder:return QAbstractItemModel::flags(index) | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;break;case COLUMN_HEAD_INDEX::Nozzle:return QAbstractItemModel::flags(index) | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;break;case COLUMN_HEAD_INDEX::HD:return QAbstractItemModel::flags(index) | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;break;case COLUMN_HEAD_INDEX::CS:return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;break;case COLUMN_HEAD_INDEX::CY:return Qt::ItemIsEnabled | Qt::ItemIsSelectable;break;case COLUMN_HEAD_INDEX::SK:return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;break;case COLUMN_HEAD_INDEX::AR:return Qt::ItemIsEnabled | Qt::ItemIsSelectable;break;case COLUMN_HEAD_INDEX::FID:return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;break;case COLUMN_HEAD_INDEX::BL:return Qt::ItemIsEnabled | Qt::ItemIsSelectable;default:return Qt::ItemIsEnabled | Qt::ItemIsSelectable;break;}return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}// 设置模型索引数据
bool TableModel::setData(const QModelIndex &index, const QVariant &value, int role) {if (index.isValid() && role == Qt::EditRole) {switch (index.column()) {case COLUMN_HEAD_INDEX::No:this->m_No[index.row()] = value.toString();break;case COLUMN_HEAD_INDEX::Reference:this->m_Reference[index.row()] = value.toString();break;case COLUMN_HEAD_INDEX::X:this->m_X[index.row()] = value.toString();break;case COLUMN_HEAD_INDEX::Y:this->m_Y[index.row()] = value.toString();break;case COLUMN_HEAD_INDEX::Z:this->m_Z[index.row()] = value.toString();break;case COLUMN_HEAD_INDEX::R:this->m_R[index.row()] = value.toString();break;case COLUMN_HEAD_INDEX::Part:this->m_Part[index.row()] = value.toString();break;case COLUMN_HEAD_INDEX::Feeder:this->m_Feeder[index.row()] = value.toString();break;case COLUMN_HEAD_INDEX::Nozzle:this->m_Nozzle[index.row()] = value.toString();break;case COLUMN_HEAD_INDEX::HD:this->m_HD[index.row()] = value.toString();break;//case COLUMN_HEAD_INDEX::CS://	//this->m_CS[index.row()] = value.toString();//	this->m_CS[index.row()] = (value.toInt() == Qt::Checked ? Qt::Checked : Qt::Unchecked);//	break;case COLUMN_HEAD_INDEX::CY:this->m_CY[index.row()] = value.toString();break;/*case COLUMN_HEAD_INDEX::SK:this->m_SK[index.row()] = value.toString();break;*/case COLUMN_HEAD_INDEX::AR:this->m_AR[index.row()] = value.toString();break;/*case COLUMN_HEAD_INDEX::FID:this->m_FID[index.row()] = value.toString();break;*/case COLUMN_HEAD_INDEX::BL:this->m_BL[index.row()] = value.toString();default:break;}// 设置完成后发射信号告诉视图数据有修改emit dataChanged(index, index);	// 参数是左上角和右下角的模型索引(这里是相同的)return true;} else if (index.isValid() && role == Qt::CheckStateRole) {switch (index.column()) {case COLUMN_HEAD_INDEX::CS:this->m_CS[index.row()] = (value.toInt() == Qt::Checked ? Qt::Checked : Qt::Unchecked);break;case COLUMN_HEAD_INDEX::SK:this->m_SK[index.row()] = (value.toInt() == Qt::Checked ? Qt::Checked : Qt::Unchecked);break;case COLUMN_HEAD_INDEX::FID:this->m_FID[index.row()] = (value.toInt() == Qt::Checked ? Qt::Checked : Qt::Unchecked);break;default:break;}// 设置完成后发射信号告诉视图数据有修改emit dataChanged(index, index);	// 参数是左上角和右下角的模型索引(这里是相同的)return true;}return false;
}// 插入行	参数:插入的位置;插入的行数;父项的模型索引
bool TableModel::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_No.insert(row + addCount, "");this->m_Reference.insert(row + addCount, "");this->m_X.insert(row + addCount, "");this->m_Y.insert(row + addCount, "");this->m_Z.insert(row + addCount, "");this->m_R.insert(row + addCount, "");this->m_Part.insert(row + addCount, "");this->m_Feeder.insert(row + addCount, "");this->m_Nozzle.insert(row + addCount, "");this->m_HD.insert(row + addCount, "");this->m_CS.insert(row + addCount, Qt::CheckState::Unchecked);this->m_CY.insert(row + addCount, "");this->m_SK.insert(row + addCount, Qt::CheckState::Unchecked);this->m_AR.insert(row + addCount, "");this->m_FID.insert(row + addCount, Qt::CheckState::Unchecked);this->m_BL.insert(row + addCount, "");}// 结束插入行endInsertRows();return true;
}// 删除行
bool TableModel::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_No.removeAt(row);this->m_Reference.removeAt(row);this->m_X.removeAt(row);this->m_Y.removeAt(row);this->m_Z.removeAt(row);this->m_R.removeAt(row);this->m_Part.removeAt(row);this->m_Feeder.removeAt(row);this->m_Nozzle.removeAt(row);this->m_HD.removeAt(row);this->m_CS.remove(row + removeCount);this->m_CY.removeAt(row);this->m_SK.remove(row + removeCount);this->m_AR.removeAt(row);this->m_FID.remove(row + removeCount);this->m_BL.removeAt(row);}endRemoveRows();return true;
}

==

==

HzcTableEdit.h

#pragma once#include <QtWidgets/QWidget>
#include "ui_HzcTableEdit.h"
#include "TableModel.h"
#include "WidgetDelegate.h"#include <QMenu>class HzcTableEdit : public QWidget {Q_OBJECTpublic:HzcTableEdit(QWidget *parent = Q_NULLPTR);private:void setInsertRowData(int _row);bool isSelectionRows();// 右键显示菜单事件void contextMenuEvent(QContextMenuEvent * event);private slots:void on_selectBtn_clicked();void on_cancelBtn_clicked();void on_insertBtn_clicked();void on_removeBtn_clicked();void onCheckBox();void onUnCheckBox();void onCheckAndUnCheckBox(Qt::CheckState State);private:Ui::HzcTableEditClass ui;TableModel *m_tableModel;// QComboBoxQMap<int, WidgetDelegate *> m_cBoxDelegateArray;// 列的初始默认数据QMap<int, QString> m_columnData;// No.列int m_no;// 存储查找显示的索引QModelIndexList m_showList;// 菜单QMenu *m_menu;};

HzcTableEdit.cpp

#include "HzcTableEdit.h"#include <QDebug>
#include <QMessageBox>HzcTableEdit::HzcTableEdit(QWidget *parent) : QWidget(parent) {ui.setupUi(this);this->m_no = 1;// 单元格的宽度int headWidth[COLUMN_HEAD_INDEX::COLUMN] = { 40, 100, 80, 80, 80, 80, 100, 120, 100, 40, 30, 30, 30, 30, 30, 30 };QStringList part, feederList, nozzleList, HDList;part << "";feederList << "" << "A";nozzleList << "" << "A" << "EMPTY" << "CN020" << "CN030" << "CN040" << "CN065" << "CN140" << "CN220" << "CN400";HDList << "" << "1" << "2" << "3" << "4" << "5" << "6" << "7";// 行的初始数据this->m_columnData.insert(COLUMN_HEAD_INDEX::X, "0.000");this->m_columnData.insert(COLUMN_HEAD_INDEX::Y, "0.000");this->m_columnData.insert(COLUMN_HEAD_INDEX::Z, "0.000");this->m_columnData.insert(COLUMN_HEAD_INDEX::R, "0.000");this->m_columnData.insert(COLUMN_HEAD_INDEX::CY, "1");this->m_columnData.insert(COLUMN_HEAD_INDEX::AR, "1");this->m_columnData.insert(COLUMN_HEAD_INDEX::BL, "0");this->m_tableModel = new TableModel;ui.tableView->setModel(this->m_tableModel);this->m_cBoxDelegateArray.insert(COLUMN_HEAD_INDEX::Part, new WidgetDelegate(part));this->m_cBoxDelegateArray.insert(COLUMN_HEAD_INDEX::Feeder, new WidgetDelegate(feederList));this->m_cBoxDelegateArray.insert(COLUMN_HEAD_INDEX::Nozzle, new WidgetDelegate(nozzleList));this->m_cBoxDelegateArray.insert(COLUMN_HEAD_INDEX::HD, new WidgetDelegate(HDList));// 添加委托ui.tableView->setItemDelegateForColumn(COLUMN_HEAD_INDEX::Part, this->m_cBoxDelegateArray.value(COLUMN_HEAD_INDEX::Part));ui.tableView->setItemDelegateForColumn(COLUMN_HEAD_INDEX::Feeder, this->m_cBoxDelegateArray.value(COLUMN_HEAD_INDEX::Feeder));ui.tableView->setItemDelegateForColumn(COLUMN_HEAD_INDEX::Nozzle, this->m_cBoxDelegateArray.value(COLUMN_HEAD_INDEX::Nozzle));ui.tableView->setItemDelegateForColumn(COLUMN_HEAD_INDEX::HD, this->m_cBoxDelegateArray.value(COLUMN_HEAD_INDEX::HD));// 设置水平头文本居中ui.tableView->horizontalHeader()->setDefaultAlignment(Qt::AlignHCenter);//设置隔行变色ui.tableView->setAlternatingRowColors(true);// 设置最后一列填满表格剩余空间ui.tableView->horizontalHeader()->setStretchLastSection(true);// 设置表格行高ui.tableView->verticalHeader()->setDefaultSectionSize(30);for (int i = 0; i < COLUMN_HEAD_INDEX::COLUMN; i++) {// 设置表格列宽ui.tableView->setColumnWidth(i, headWidth[i]);}// 设置用户可以拖动行//ui.tableView->verticalHeader()->setSectionsMovable(true);// 设置固定行高ui.tableView->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed);//ui.tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);// 设置行表头背景颜色样式为浅黄色ui.tableView->horizontalHeader()->setStyleSheet("QHeaderView::section{background:#ffff9b;}");// 设置列表头背景颜色样式为浅蓝色ui.tableView->verticalHeader()->setStyleSheet("QHeaderView::section{background:#a7fffa;}");// 设置左上角两个表头相交的区域的颜色样式为浅灰色ui.tableView->setStyleSheet("QTableCornerButton::section{background:#c2c2c2;}");this->m_menu = new QMenu(this);QMenu *childMenu = new QMenu("填充原件");// 定义菜单子项QAction *addRowAction = new QAction("插入行");QAction *removeRowAction = new QAction("删除行");QAction *skipPointsAction = new QAction("跳过点");QAction *cancleSkipPointsAction = new QAction("取消跳过点");QAction *skipJointBoardAction = new QAction("跳过拼版");QAction *separator = this->m_menu->addSeparator();	// 返回一个分隔符this->m_menu->addAction(addRowAction);this->m_menu->addAction(removeRowAction);this->m_menu->addAction(skipPointsAction);this->m_menu->addAction(cancleSkipPointsAction);this->m_menu->addAction(separator);this->m_menu->addAction(skipJointBoardAction);this->m_menu->addMenu(childMenu);connect(addRowAction, SIGNAL(triggered()), this, SLOT(on_insertBtn_clicked()));connect(removeRowAction, SIGNAL(triggered()), this, SLOT(on_removeBtn_clicked()));connect(skipPointsAction, SIGNAL(triggered()), this, SLOT(onCheckBox()));connect(cancleSkipPointsAction, SIGNAL(triggered()), this, SLOT(onUnCheckBox()));
}void HzcTableEdit::on_selectBtn_clicked() {// 清空链表this->m_showList.clear();QString lineEdit = ui.lineEdit->text();QString rowStr = "";// 为空则显示所有行if (lineEdit.isEmpty()) {for (int row = 0; row < m_tableModel->rowCount(); row++) {ui.tableView->showRow(row);}	return;}// 遍历所有行for (int row = 0; row < m_tableModel->rowCount(); row++) {// 获得Reference单元格的文本QModelIndex index = m_tableModel->index(row, COLUMN_HEAD_INDEX::Reference);rowStr = m_tableModel->data(index).toString();if (rowStr.isEmpty()) {// 隐藏当前行ui.tableView->hideRow(row);} else {// Reference列的文本是否与输入框中的文本相等if (lineEdit.contains(rowStr)) {ui.tableView->showRow(row);// 将显示的行索引存入链表中this->m_showList.append(index);} else {ui.tableView->hideRow(row);}}}
}void HzcTableEdit::on_cancelBtn_clicked() {ui.lineEdit->setText("");// 显示所有行for (int row = 0; row < m_tableModel->rowCount(); row++) {ui.tableView->showRow(row);}// 点击了取消按钮,链表需要清空this->m_showList.clear();
}void HzcTableEdit::on_insertBtn_clicked() {if (!isSelectionRows()) {QMessageBox::information(this, "提示", "请选中一行!");return;}// 获取所有选中的索引QModelIndexList indexs = ui.tableView->selectionModel()->selectedIndexes();if (indexs.size() == 0) {m_tableModel->insertRows(m_tableModel->rowCount(), 1);setInsertRowData(m_tableModel->rowCount() - 1);return;}// 获得最后一个索引的行int row = indexs.last().row();m_tableModel->insertRows(row + 1, 1);setInsertRowData(row + 1);
}void HzcTableEdit::on_removeBtn_clicked() {if (!isSelectionRows()) {QMessageBox::information(this, "提示", "请选中一行!");return;}// 移除用户查询后选中的行if (this->m_showList.size() != 0) {// 从后往前移除for (int row = m_showList.size() - 1; row >= 0; row--) {m_tableModel->removeRow(m_showList[row].row());}m_showList.clear();return;}// 获取所有选中列的行(不重复)QModelIndexList indexs = ui.tableView->selectionModel()->selectedRows();if (indexs.size() == 0) return;// 检测用户选择的项是否是连续的bool successionFlag = true;for (int row = 0; row < indexs.size(); row++) {if (row + 1 == indexs.size()) break;if (indexs[row].row() + 1 != indexs[row + 1].row()) {successionFlag = false;break;}}if (successionFlag) {m_tableModel->removeRows(indexs.first().row(), indexs.size());} else {for (int row = indexs.size() - 1; row >= 0; row--) {m_tableModel->removeRow(indexs[row].row());	// 实际是调用removeRows(indexs[row].row(), 1),进行删除一行}}// 删除完后,对No列进行排序this->m_no = m_tableModel->rowCount();for (int row = 0; row < m_no; row++) {QModelIndex index = m_tableModel->index(row, 0);m_tableModel->setData(index, QString("%1").arg(row + 1));}this->m_no += 1;}// 为插入的行设置初始数据
void HzcTableEdit::setInsertRowData(int _row) {QString value = "";QModelIndex index0 = m_tableModel->index(_row, COLUMN_HEAD_INDEX::No);m_tableModel->setData(index0, QString("%1").arg(m_no++));static int ref = 1;QModelIndex index1 = m_tableModel->index(_row, COLUMN_HEAD_INDEX::Reference);m_tableModel->setData(index1, QString("%1").arg(ref++));QModelIndex index2 = m_tableModel->index(_row, COLUMN_HEAD_INDEX::X);m_tableModel->setData(index2, m_columnData.value(COLUMN_HEAD_INDEX::X));QModelIndex index3 = m_tableModel->index(_row, COLUMN_HEAD_INDEX::Y);m_tableModel->setData(index3, m_columnData.value(COLUMN_HEAD_INDEX::Y));QModelIndex index4 = m_tableModel->index(_row, COLUMN_HEAD_INDEX::Z);m_tableModel->setData(index4, m_columnData.value(COLUMN_HEAD_INDEX::Z));QModelIndex index5 = m_tableModel->index(_row, COLUMN_HEAD_INDEX::R);m_tableModel->setData(index5, m_columnData.value(COLUMN_HEAD_INDEX::R));QModelIndex index6 = m_tableModel->index(_row, COLUMN_HEAD_INDEX::Part);value = this->m_cBoxDelegateArray[COLUMN_HEAD_INDEX::Part]->getCurrentComboBoxData(0);m_tableModel->setData(index6, value);QModelIndex index7 = m_tableModel->index(_row, COLUMN_HEAD_INDEX::Feeder);value = this->m_cBoxDelegateArray[COLUMN_HEAD_INDEX::Feeder]->getCurrentComboBoxData(1);m_tableModel->setData(index7, value);QModelIndex index8 = m_tableModel->index(_row, COLUMN_HEAD_INDEX::Nozzle);value = this->m_cBoxDelegateArray[COLUMN_HEAD_INDEX::Nozzle]->getCurrentComboBoxData(6);m_tableModel->setData(index8, value);QModelIndex index9 = m_tableModel->index(_row, COLUMN_HEAD_INDEX::HD);value = this->m_cBoxDelegateArray[COLUMN_HEAD_INDEX::HD]->getCurrentComboBoxData(1);m_tableModel->setData(index9, value);QModelIndex index10 = m_tableModel->index(_row, COLUMN_HEAD_INDEX::CS);m_tableModel->setData(index10, Qt::CheckState::Unchecked);QModelIndex index11 = m_tableModel->index(_row, COLUMN_HEAD_INDEX::CY);m_tableModel->setData(index11, m_columnData.value(COLUMN_HEAD_INDEX::CY));QModelIndex index12 = m_tableModel->index(_row, COLUMN_HEAD_INDEX::SK);m_tableModel->setData(index12, Qt::CheckState::Unchecked);QModelIndex index13 = m_tableModel->index(_row, COLUMN_HEAD_INDEX::AR);m_tableModel->setData(index13, m_columnData.value(COLUMN_HEAD_INDEX::AR));QModelIndex index14 = m_tableModel->index(_row, COLUMN_HEAD_INDEX::FID);m_tableModel->setData(index14, Qt::CheckState::Unchecked);QModelIndex index15 = m_tableModel->index(_row, COLUMN_HEAD_INDEX::BL);m_tableModel->setData(index15, m_columnData.value(COLUMN_HEAD_INDEX::BL));
}// 检查是否选中一整行
bool HzcTableEdit::isSelectionRows() {// 获取所有选中的索引QModelIndexList list = ui.tableView->selectionModel()->selectedIndexes();// 存储被选中的所有行QVector<int> selectedRows;// 获得所有选中单元格的行for each (QModelIndex index in list) {selectedRows.append(index.row());}// 进行排序std::sort(selectedRows.begin(), selectedRows.end());// 去除容器内重复元素auto it = std::unique(selectedRows.begin(), selectedRows.end());selectedRows.erase(it, selectedRows.end());// 遍历所有行的单元格,存在有一个单元格没有被选中,则返回falsebool selectedFlag = true;for (int row = 0; row < selectedRows.count(); row++) {for (int column = 0; column < COLUMN_HEAD_INDEX::COLUMN; column++) {QModelIndex index = m_tableModel->index(selectedRows.at(row), column);// 检测该索引是否被选中if (ui.tableView->selectionModel()->isSelected(index) == false) {selectedFlag = false;break;}}// 为false,直接返回结果if (selectedFlag == false) return  selectedFlag;}/* 此处为良好BUG :当用于没有选中任何单元格,也会返回true,是为了默认在行末尾连续插入行 */return selectedFlag;
}// 鼠标右键显示菜单事件
void HzcTableEdit::contextMenuEvent(QContextMenuEvent * event) {if (!isSelectionRows()) {return;}// 菜单出现的位置为当前鼠标的位置this->m_menu->exec(QCursor::pos());
}// 跳过点
void HzcTableEdit::onCheckBox() {onCheckAndUnCheckBox(Qt::CheckState::Checked);
}// 取消跳过点
void HzcTableEdit::onUnCheckBox() {onCheckAndUnCheckBox(Qt::CheckState::Unchecked);
}void HzcTableEdit::onCheckAndUnCheckBox(Qt::CheckState State) {// 获取所有选中的索引QModelIndexList list = ui.tableView->selectionModel()->selectedIndexes();if (list.size() == 0) return;// 存储被选中的所有行QVector<int> selectedRows;// 获得所有选中单元格的行for each (QModelIndex index in list) {selectedRows.append(index.row());}// 进行排序std::sort(selectedRows.begin(), selectedRows.end());// 去除容器内重复元素auto it = std::unique(selectedRows.begin(), selectedRows.end());selectedRows.erase(it, selectedRows.end());for each (int row in selectedRows) {// 获取到对应的索引QModelIndex index = m_tableModel->index(row, COLUMN_HEAD_INDEX::SK);// 将设置索引数据为选中状态m_tableModel->setData(index, State, Qt::CheckStateRole);qDebug() << m_tableModel->data(index, Qt::CheckStateRole).toBool();}
}

如果想拷贝代码下来运行,还得将文章开头链接委托里的代码也一并考下来,方可运行。


总结:
此篇博客也当做是代码记录吧。项目具体实现有兴趣的朋友得自己去看代码了,代码量太多,实在是不知道怎么写。
小项目结合了重写了委托QItemDelegate、模型QAbstractTableModel类,还有QTableVIew的使用方法,三者结合才有此小项目。如果你也有这方面的需求,真的可以研究一下此小项目的代码。

http://www.ritt.cn/news/2944.html

相关文章:

  • 科大讯飞哪些做教学资源的网站seo排名优化方式
  • 我做百度_上面有手机网站的_为什么还要做手机网站网页在线代理翻墙
  • 自己做网站可以用私有云吗seo 服务
  • 网站风格特点百度搜索优化平台
  • facebook做网站推广安卓优化大师全部版本
  • 以公司做网站如何做企业网页
  • 威海精神文明建设办公室网站近三天重大新闻摘抄
  • 网站关停公告怎么做今日重点新闻
  • 卖网格布怎样做网站电脑优化软件哪个好用
  • 上海专业高端网站建设服务公司河北关键词seo排名
  • 维基百科建设网站产品推广营销
  • 番禺网站建设开发竞价如何屏蔽恶意点击
  • 开封淘宝网站建设百度推广一个月多少钱
  • 企业咨询服务合同模板免费seo咨询服务价格
  • 公司网站招聘费如何做会计分录中国国家培训网正规吗
  • 如何做直播做菜视频网站哪个公司要做网络推广
  • 行业自助建站优化营商环境条例心得体会
  • 如何做一个网站平台房地产销售
  • wordpress建售卖产品的网站线上培训平台
  • 做网站排名软件1688如何搜索关键词排名
  • 网站建设季度考核评价工作总结山西疫情最新情况
  • gta5网站建设中站长之家app
  • 网站广告位代码黑马培训价目表
  • 中小企业网站制作过程中要注意什么网络销售怎么做才能做好
  • php网站设计杭州百度优化
  • 网站推广公司傻大白nba最新消息交易情况
  • 中国空间站航天员首次出舱网络运营培训
  • 想做个网站 怎么做的做一个电商平台大概需要多少钱
  • 二级已备案域名免费使用关于华大18年专注seo服务网站制作应用开发
  • 网站建设属那种营业百度ai开放平台