QHeaderView添加复选框以及样式
实现这个效果,需要重写`paintSection`来实现效果,同时重写`mousePressEvent`来执行是否勾选复选框。
paintSection实现一些复选框样式
void CheckBoxHeaderView::paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const
{
if (m_logicalIndex.contains(logicalIndex))
{
painter->save();
QHeaderView::paintSection(painter, rect, logicalIndex);
painter->restore();
QStyleOptionButton checkBoxOption;
QRect checkBoxRect = style()->subElementRect(QStyle::SE_CheckBoxIndicator, &checkBoxOption);
checkBoxOption.rect = rect;
checkBoxOption.rect.setLeft(rect.left() + (rect.width() - checkBoxRect.width()) / 2);
checkBoxOption.rect.setTop(rect.top() + (rect.height() - checkBoxRect.height()) / 2);
checkBoxOption.state = m_logicalIndex.value(logicalIndex) ? QStyle::State_On :QStyle::State_Off;
checkBoxOption.state |= QStyle::State_Enabled;
QCheckBox checkBox;
checkBox.setStyleSheet(m_strStyleSheet);
checkBox.style()->drawControl(QStyle::CE_CheckBox, &checkBoxOption, painter, &checkBox);
//style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &checkBoxOption, painter,&checkBox);
}
else
{
QHeaderView::paintSection(painter, rect, logicalIndex);
}
}
或者通过QWidget的render()来实现
void CheckBoxHeaderView::paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const
{
if (m_logicalIndex.contains(logicalIndex))
{
painter->save();
QHeaderView::paintSection(painter, rect, logicalIndex);
painter->restore();
QStyleOptionButton checkBoxOption;
QRect checkBoxRect = style()->subElementRect(QStyle::SE_CheckBoxIndicator, &checkBoxOption);
int x = rect.left() + (rect.width() - checkBoxRect.width()) / 2;
int y = rect.top() + (rect.height() - checkBoxRect.height()) / 2;
QCheckBox checkBox;
checkBox.setCheckState(m_logicalIndex.value(logicalIndex) ?Qt::Checked:Qt::Unchecked);
checkBox.setStyleSheet(m_strStyleSheet);
checkBox.setGeometry(checkBoxRect);
painter->save();
painter->translate(x, y);
checkBox.render(painter);
painter->restore();
}
else
{
QHeaderView::paintSection(painter, rect, logicalIndex);
}
}
mousePressEvent实现点击时是否勾选复选框
void CheckBoxHeaderView::mousePressEvent(QMouseEvent *event)
{
if (!(event->buttons() & Qt::LeftButton)){
QHeaderView::mousePressEvent(event);
return ;
}
int idx = this->logicalIndexAt(event->pos());
if (!m_logicalIndex.contains(idx)){
QHeaderView::mousePressEvent(event);
return ;
}
m_logicalIndex[idx] = !m_logicalIndex[idx];
viewport()->update();
emit stateChanged(m_logicalIndex[idx], idx);
return;
}
为了能够更好的设置QHeaderView中某个单元格是否拥有复选框功能,所以添加以下这些操作。
QHash<int,bool> m_logicalIndex;
signals:
void stateChanged(bool bChecked, int index);
void CheckBoxHeaderView::setCheckable(QList<int> allIndex)
{
bool bUpdate = false;
for (int i=0; i<allIndex.size(); ++i)
{
int id = allIndex.at(i);
if (!m_logicalIndex.contains(id)){
m_logicalIndex[id] = false;
bUpdate = true;
}
}
if (bUpdate){
viewport()->update();
}
}
void CheckBoxHeaderView::setCheckable(int idx)
{
if (!m_logicalIndex.contains(idx)){
m_logicalIndex[idx] = false;
viewport()->update();
}
}
void CheckBoxHeaderView::setUncheckable(QList<int> allIndex)
{
bool bUpdate = false;
for (int i=0; i<allIndex.size(); ++i)
{
int id = allIndex.at(i);
if (m_logicalIndex.contains(id)){
m_logicalIndex.remove(id);
bUpdate = true;
}
}
if (bUpdate){
viewport()->update();
}
}
void CheckBoxHeaderView::setUncheckable(int idx)
{
if (m_logicalIndex.contains(idx)){
m_logicalIndex.remove(idx);
viewport()->update();
}
}
void CheckBoxHeaderView::setChecked(bool check, int idx)
{
if (m_logicalIndex.contains(idx))
{
if (m_logicalIndex[idx] != check){
m_logicalIndex[idx] = check;
viewport()->update();
}
}
}
bool CheckBoxHeaderView::isChecked(int idx) const
{
if (m_logicalIndex.contains(idx)) {
return m_logicalIndex[idx];
}
return false;
}