前沿
工作中遇到一种问题:需要一种表格,第一例单元格为全选CheckBox,点击这个CheckBox,勾选一行之后的单元格。
整体效果如下图:
实现描述
- 直接继承QAstractTableViewModel,主要重写6个关键性的虚函数:
虚函数 | 函数描述 |
---|---|
headerData(int section, Qt::Orientation orientation, int role) | 根据role属性返回内部调用者横竖表头单元格的一些属性:字体、文本、颜色、居中等 |
int rowCount(const QModelIndex& parent) | 告诉内部调用者表格行数,一般为容器成员变量count |
int columnCount(const QModelIndex &parent | 告诉内部调用者表格列数,一般为表头字段数 |
QVariant data(const QModelIndex &index, int role) | 根据role返回内部调用者每个单元格的属性数据QVariant |
bool setData(const QModelIndex &index, const QVariant &value, int role) | 界面数据发生修改,内部调用者调用该接口会根据role重新设置每个单元格的属性数据 |
Qt::ItemFlags flags(const QModelIndex &index) | 告诉调用者该单元格的使能、可选择性、可勾选等标志 |
QVariant MultiCheckModel::headerData(int section, Qt::Orientation orientation, int role) const
{
// FIXME: Implement me!
QVariant retVal;
switch (role) {
case Qt::TextAlignmentRole:
{
retVal = QVariant(Qt::AlignLeft | Qt::AlignHCenter);
break;
}
case Qt::DisplayRole:
{
if (orientation == Qt::Horizontal)
{
if(section == static_cast<int>(HeaderCheckItem::Col_SelectAll))
{
retVal = tr("Select All");
}
if(section == static_cast<int>(HeaderCheckItem::Col_ItemMax))
{
retVal = tr("Max");
}
if(section == static_cast<int>(HeaderCheckItem::Col_ItemAvg))
{
retVal = tr("Avg");
}
if(section == static_cast<int>(HeaderCheckItem::Col_ItemMin))
{
retVal = tr("Min");
}
}
break;
}
default:
break;
}
return retVal;
}
int MultiCheckModel::rowCount(const QModelIndex &parent) const
{
if (parent.isValid())
return 0;
// FIXME: Implement me!
return m_listData.count();
}
int MultiCheckModel::columnCount(const QModelIndex &parent) const
{
if (parent.isValid())
return 0;
// FIXME: Implement me!
return static_cast<int>(HeaderCheckItem::Col_Total);
}
QVariant MultiCheckModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
// FIXME: Implement me!
QVariant retVal;
int nRow = index.row();
int nColumn = index.column();
const ModelItem& itemChooseState = m_listData.at(nRow);
switch (role) {
case Qt::CheckStateRole:
{
bool bState = false;
if(nColumn == static_cast<int>(HeaderCheckItem::Col_SelectAll))
{
bState = itemChooseState.bShowmin && itemChooseState.bShowavg && itemChooseState.bShowmax;
}
if(nColumn == static_cast<int>(HeaderCheckItem::Col_ItemMax))
{
bState = itemChooseState.bShowmax;
}
if(nColumn == static_cast<int>(HeaderCheckItem::Col_ItemAvg))
{
bState = itemChooseState.bShowavg;
}
if(nColumn == static_cast<int>(HeaderCheckItem::Col_ItemMin))
{
bState = itemChooseState.bShowmin;
}
retVal = bState ? Qt::Checked : Qt::Unchecked;
}
}
return retVal;
}
bool MultiCheckModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (!index.isValid())
return false;
// FIXME: Implement me!
QVariant retVal;
int nColumn = index.column();
ModelItem& item = m_listData[index.row()];
switch (role) {
case Qt::CheckStateRole:
{
if(nColumn == static_cast<int>(HeaderCheckItem::Col_SelectAll))
{
item.bShowmin = item.bShowavg = item.bShowmax = (value.toInt() == Qt::Checked);
emit dataChanged(index, index);
return true;
}
if(nColumn == static_cast<int>(HeaderCheckItem::Col_ItemMax))
{
item.bShowmax = (value.toInt() == Qt::Checked);
emit dataChanged(index, index);
return true;
}
if(nColumn == static_cast<int>(HeaderCheckItem::Col_ItemAvg))
{
item.bShowavg = (value.toInt() == Qt::Checked);
emit dataChanged(index, index);
return true;
}
if(nColumn == static_cast<int>(HeaderCheckItem::Col_ItemMin))
{
item.bShowmin = (value.toInt() == Qt::Checked);
emit dataChanged(index, index);
return true;
}
break;
}
}
return false;
}
Qt::ItemFlags MultiCheckModel::flags(const QModelIndex &index) const
{
if(!index.isValid())
{
return QAbstractItemModel::flags(index);
}
Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
int nColumn = index.column();
if(nColumn == static_cast<int>(HeaderCheckItem::Col_SelectAll)
|| nColumn == static_cast<int>(HeaderCheckItem::Col_ItemMax)
|| nColumn == static_cast<int>(HeaderCheckItem::Col_ItemAvg)
|| nColumn == static_cast<int>(HeaderCheckItem::Col_ItemMin))
{
flags |= Qt::ItemIsUserCheckable;
}
return flags;
}
- 编写一个设置接口setShowData,将上层数据传递到QAstractTableViewModel中
beginResetModel() 和 endResetModel() 用来通知表格重绘刷新
void MultiCheckModel::setShowData(const QList<MultiCheckModel::ModelItem> &list)
{
m_listData = list;
// 刷新列表数据
beginResetModel();
endResetModel();
}
- 界面勾选发生改变时,连接dataChanged信号,槽函数继续调用 beginResetModel() 和 endResetModel() 用来通知表格重绘刷新
void MultiCheckModel::initConnect()
{
connect(this, &QAbstractItemModel::dataChanged, [=]
{
// 刷新列表数据
beginResetModel();
endResetModel();
});
}
代码的话之后上传GitHub,下次修改时,上传url