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

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;
}


http://www.kler.cn/news/367421.html

相关文章:

  • pytorch调用手写CUDA算子和pybind11的使用
  • type C 引脚定义
  • 传输层TCP
  • OPPO携手比亚迪共同探索手机与汽车互融新时代
  • 2024软考网络工程师笔记 - 第8章.网络安全
  • Harmony 开发与H5进行交互
  • R语言机器学习算法实战系列(十四): CatBoost分类算法+SHAP值 (categorical data gradient boosting)
  • LeetCode练习-删除链表的第n个结节
  • 医院信息化与智能化系统(10)
  • Nuxt.js交流社区,欢迎加入!
  • 报表工具怎么选?山海鲸VS帆软,哪个更适合你?
  • “循环购模式:革新消费体验,解锁收益新篇章“
  • 单值集合总复习
  • MySQL-DQL练习题
  • 2024.10.27 直接插入排序 非递归后序遍历(复杂版)
  • 基于STM32的智能寝室控制系统设计(论文+源码)
  • Spring Boot环境下论坛网站的架构与优化
  • idea 无法输入中文 快速解决
  • 2024 BuildCTF 公开赛|MISC
  • 【好玩的经典游戏】Docker环境下部署网页小游戏网站
  • 媒小象 1.7.2 | 完全免费的内容创作二创工具
  • uniapp 发起post和get请求!uni.request(OBJECT)
  • PouchDB - 免费开源的 JavaScript 数据库,轻量易用,用于离线保存数据的场景
  • 联想笔记本电脑睡眠后打开黑屏解决方法
  • 路由器 相关知识
  • 【Android】浅析OkHttp(1)