207 lines
5.1 KiB
C++
207 lines
5.1 KiB
C++
|
|
#include "TableHeaderView.h"
|
|||
|
|
#include <QCheckBox>
|
|||
|
|
#include <QApplication>
|
|||
|
|
#include <QMouseEvent>
|
|||
|
|
#include <qmessagebox.h>
|
|||
|
|
|
|||
|
|
#ifdef _MSC_VER
|
|||
|
|
#pragma execution_character_set("utf-8")
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
#define CHECK_BOX_COLUMN 0
|
|||
|
|
TableHeaderView::TableHeaderView(Qt::Orientation orientation, QWidget *parent)
|
|||
|
|
: QHeaderView(orientation, parent),
|
|||
|
|
m_bPressed(false),
|
|||
|
|
m_bChecked(false),
|
|||
|
|
m_bTristate(false),
|
|||
|
|
m_bNoChange(false),
|
|||
|
|
m_bMoving(false)
|
|||
|
|
|
|||
|
|
{
|
|||
|
|
setSectionsClickable(true); // 响应鼠标
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
TableHeaderView::~TableHeaderView()
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 槽函数,用于更新复选框状态
|
|||
|
|
void TableHeaderView::onStateChanged(int state)
|
|||
|
|
{
|
|||
|
|
if (state == Qt::PartiallyChecked) {
|
|||
|
|
m_bTristate = true;
|
|||
|
|
m_bNoChange = true;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_bNoChange = false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
m_bChecked = (state != Qt::Unchecked);
|
|||
|
|
update();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 绘制复选框
|
|||
|
|
void TableHeaderView::paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const
|
|||
|
|
{
|
|||
|
|
painter->save();
|
|||
|
|
QHeaderView::paintSection(painter, rect, logicalIndex);
|
|||
|
|
painter->restore();
|
|||
|
|
|
|||
|
|
if (logicalIndex == CHECK_BOX_COLUMN )
|
|||
|
|
{
|
|||
|
|
QStyleOptionButton option;
|
|||
|
|
option.initFrom(this);
|
|||
|
|
|
|||
|
|
if (m_bChecked)
|
|||
|
|
option.state |= QStyle::State_Sunken;
|
|||
|
|
|
|||
|
|
if (m_bTristate && m_bNoChange)
|
|||
|
|
option.state |= QStyle::State_NoChange;
|
|||
|
|
else
|
|||
|
|
option.state |= m_bChecked ? QStyle::State_On : QStyle::State_Off;
|
|||
|
|
if (testAttribute(Qt::WA_Hover) && underMouse()) {
|
|||
|
|
if (m_bMoving)
|
|||
|
|
option.state |= QStyle::State_MouseOver;
|
|||
|
|
else
|
|||
|
|
option.state &= ~QStyle::State_MouseOver;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
QCheckBox checkBox;
|
|||
|
|
option.iconSize = QSize(20, 20);
|
|||
|
|
option.rect = rect;
|
|||
|
|
style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &option, painter, &checkBox);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 鼠标按下表头
|
|||
|
|
void TableHeaderView::mousePressEvent(QMouseEvent *event)
|
|||
|
|
{
|
|||
|
|
int nColumn = logicalIndexAt(event->pos());
|
|||
|
|
if ((event->buttons() & Qt::LeftButton) && (nColumn == CHECK_BOX_COLUMN))
|
|||
|
|
{
|
|||
|
|
m_bPressed = true;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
QHeaderView::mousePressEvent(event);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 鼠标从表头释放,发送信号,更新model数据
|
|||
|
|
void TableHeaderView::mouseReleaseEvent(QMouseEvent *event)
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
if (m_bPressed)
|
|||
|
|
{
|
|||
|
|
if (m_bTristate && m_bNoChange)
|
|||
|
|
{
|
|||
|
|
m_bChecked = true;
|
|||
|
|
m_bNoChange = false;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
m_bChecked = !m_bChecked;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
update();
|
|||
|
|
|
|||
|
|
Qt::CheckState state = m_bChecked ? Qt::Checked : Qt::Unchecked;
|
|||
|
|
|
|||
|
|
emit stateChanged(state);
|
|||
|
|
|
|||
|
|
updateSection(0);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
QHeaderView::mouseReleaseEvent(event);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
m_bPressed = false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 鼠标滑过、离开,更新复选框状态
|
|||
|
|
bool TableHeaderView::event(QEvent *event)
|
|||
|
|
{
|
|||
|
|
updateSection(0);
|
|||
|
|
if (event->type() == QEvent::Enter || event->type() == QEvent::Leave)
|
|||
|
|
{
|
|||
|
|
QMouseEvent *pEvent = static_cast<QMouseEvent *>(event);
|
|||
|
|
int nColumn = logicalIndexAt(pEvent->x());
|
|||
|
|
if (nColumn == CHECK_BOX_COLUMN)
|
|||
|
|
{
|
|||
|
|
m_bMoving = (event->type() == QEvent::Enter);
|
|||
|
|
|
|||
|
|
update();
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return QHeaderView::event(event);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
CheckBoxDelegate::CheckBoxDelegate(QObject *parent) :QStyledItemDelegate(parent)
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
CheckBoxDelegate::~CheckBoxDelegate()
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 绘制复选框
|
|||
|
|
void CheckBoxDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
|||
|
|
{
|
|||
|
|
QStyleOptionViewItem viewOption(option);
|
|||
|
|
initStyleOption(&viewOption, index);
|
|||
|
|
if (option.state.testFlag(QStyle::State_HasFocus))
|
|||
|
|
viewOption.state = viewOption.state ^ QStyle::State_HasFocus;
|
|||
|
|
|
|||
|
|
QStyledItemDelegate::paint(painter, viewOption, index);
|
|||
|
|
|
|||
|
|
if (index.column() == CHECK_BOX_COLUMN )
|
|||
|
|
{
|
|||
|
|
bool data = index.model()->data(index, Qt::UserRole).toBool();
|
|||
|
|
|
|||
|
|
QStyleOptionButton checkBoxStyle;
|
|||
|
|
checkBoxStyle.state = data ? QStyle::State_On : QStyle::State_Off;
|
|||
|
|
checkBoxStyle.state |= QStyle::State_Enabled;
|
|||
|
|
checkBoxStyle.iconSize = QSize(20, 20);
|
|||
|
|
checkBoxStyle.rect = option.rect;
|
|||
|
|
|
|||
|
|
QCheckBox checkBox;
|
|||
|
|
checkBoxStyle.iconSize = QSize(20, 20);
|
|||
|
|
checkBoxStyle.rect = option.rect;
|
|||
|
|
QApplication::style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &checkBoxStyle, painter, &checkBox);
|
|||
|
|
|
|||
|
|
checkBox.setEnabled(false);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 响应鼠标事件,更新数据
|
|||
|
|
bool CheckBoxDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
|
|||
|
|
{
|
|||
|
|
QRect decorationRect = option.rect;
|
|||
|
|
|
|||
|
|
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
|
|||
|
|
if (event->type() == QEvent::MouseButtonPress && decorationRect.contains(mouseEvent->pos()))
|
|||
|
|
{
|
|||
|
|
if (index.column() == CHECK_BOX_COLUMN )
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
bool data = model->data(index, Qt::UserRole).toBool();
|
|||
|
|
model->setData(index, !data, Qt::UserRole);
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return QStyledItemDelegate::editorEvent(event, model, option, index);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|