自定义QTableView左上角按钮内容 原创

是飞鸿呀
发布于 2023-12-15 14:30
浏览
0收藏

自定义QTableView左上角按钮内容

#include <QStyle>
#include <QPainter>
#include <QTableView>
#include <QHeaderView>
#include <QAbstractButton>
#include <QStyleOptionHeader>
#include <QItemSelectionModel>

class QTableViewCornerProxy : public QObject
{
    Q_OBJECT
public:
    using QObject::QObject;

    void attach(QTableView *view, const QString &text, const QIcon &icon = {});
    void detach(QTableView *view);

protected:
    bool eventFilter(QObject *watched, QEvent *event) override;
    void initStyleOption(QAbstractButton *button, QStyleOptionHeader *option) const;
};
void QTableViewCornerProxy::attach(QTableView *view, const QString &text, const QIcon &icon)
{
    QStyleOptionHeader option;
    QHeaderView *header = view->verticalHeader();
    for (QAbstractButton *button : view->findChildren<QAbstractButton *>(QString{}, Qt::FindDirectChildrenOnly)) {
        if (Q_UNLIKELY(!button->inherits("QTableCornerButton")))
            continue;
        button->installEventFilter(this);
        button->setText(text);
        button->setIcon(icon);
        initStyleOption(button, &option);
        connect(header->selectionModel(), &QItemSelectionModel::selectionChanged, button, qOverload<>(&QWidget::update));
        break;
    }
    const int width = view->style()->sizeFromContents(QStyle::CT_HeaderSection, &option, {}, header).width();
    header->setMinimumWidth(width);
}

void QTableViewCornerProxy::detach(QTableView *view)
{
    for (QAbstractButton *button : view->findChildren<QAbstractButton *>(QString{}, Qt::FindDirectChildrenOnly)) {
        if (Q_UNLIKELY(!button->inherits("QTableCornerButton")))
            continue;
        button->removeEventFilter(this);
        button->setText({});
        button->setIcon({});
        disconnect(view->verticalHeader()->selectionModel(), &QItemSelectionModel::selectionChanged, button, qOverload<>(&QWidget::update));
        break;
    }
}

bool QTableViewCornerProxy::eventFilter(QObject *watched, QEvent *event)
{
    Q_UNUSED(event)
    if (Q_UNLIKELY(!watched->inherits("QTableCornerButton")))
        return false;
    if (Q_LIKELY(event->type() != QEvent::Paint))
        return false;

    QAbstractButton *button = static_cast<QAbstractButton *>(watched);
    QPainter painter(button);
    QStyleOptionHeader option;
    initStyleOption(button, &option);
    button->style()->drawControl(QStyle::CE_Header, &option, &painter, button);
    return true;
}

void QTableViewCornerProxy::initStyleOption(QAbstractButton *button, QStyleOptionHeader *option) const
{
    QTableView *view = qobject_cast<QTableView *>(button->parent());
    if (Q_UNLIKELY(!view))
        return;
    QHeaderView *header = view->verticalHeader();
    option->initFrom(button);
    if (Q_UNLIKELY(header->orientation() == Qt::Horizontal))
        option->state |= QStyle::State_Horizontal;
    if (Q_LIKELY(header->isEnabled()))
        option->state |= QStyle::State_Enabled;
    if (Q_LIKELY(header->selectionModel()->hasSelection())) {
        option->state |= QStyle::State_On;
        if (Q_UNLIKELY(header->count() == header->selectionModel()->selectedRows().count()))
            option->state |= QStyle::State_Sunken;
    }

    option->section = -1;
    option->position = QStyleOptionHeader::OnlyOneSection;
    option->text = button->text();
    option->textAlignment = header->defaultAlignment();
    option->icon = button->icon();
    option->iconAlignment = Qt::AlignVCenter;
    QFont fnt  = header->font();
    fnt.setBold(true);
    option->fontMetrics = QFontMetrics(fnt);
}

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
标签
已于2023-12-15 16:56:38修改
收藏
回复
举报
回复
    相关推荐