网站首页 全球最实用的IT互联网站!

人工智能P2P分享Wind搜索发布信息网站地图标签大全

当前位置:诺佳网 > 软件工程 > 后端开发 > C++ >

Qt表格入门(优化篇)

时间:2026-03-21 22:53

人气:

作者:admin

标签:

导读:为提升大数据量下的渲染性能,本文通过 QStyledItemDelegate 直接绘制单选按钮(使用 QStyleOptionButton 和 drawControl),并在 editorEvent 中处理点击逻辑,避免创建真实控件,显著优化了加载与...

摘要:
    为提升大数据量下的渲染性能,本文通过 QStyledItemDelegate 直接绘制单选按钮(使用 QStyleOptionButtondrawControl),并在 editorEvent 中处理点击逻辑,避免创建真实控件,显著优化了加载与显示效率。

关键词:
    QStyledItemDelegateQStyleOptionButtondrawControleditorEvent、优化、渲染

版本:Qt5.14.2

问题描述:

    在上一篇文章中,使用样式代理类QStyledItemDelegate和基础组件(QRadioButtonQWidget)的组合比较简易地实现了功能,但是在后续使用中发现,大量数据导致视图渲染卡顿,需要对代码进一步优化。

代码如下:

// 优化代理类
class RadioDelegateV2 : public QStyledItemDelegate
{
    Q_OBJECT
public:
    RadioDelegateV2(QObject *parent = nullptr);
    ~RadioDelegateV2();

protected:
    void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
    QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
    bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) override;
};

RadioDelegateV2::RadioDelegateV2(QObject *parent) : QStyledItemDelegate(parent)
{

}

RadioDelegateV2::~RadioDelegateV2()
{

}

void RadioDelegateV2::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    int state = index.data(Qt::DisplayRole).toInt(); // 0=女, 1=男

    // 分割矩形为左右两半
    QRect rect = option.rect;
    QRect leftRect(rect.left(), rect.top(), rect.width() / 2, rect.height());
    QRect rightRect(rect.left() + rect.width() / 2, rect.top(), rect.width() / 2, rect.height());

    // 绘制“男”按钮(左)
    QStyleOptionButton btnOn;
    btnOn.rect = leftRect;
    btnOn.text = "男";
    btnOn.state |= QStyle::State_Enabled;
    if (state == 1) {
        btnOn.state |= QStyle::State_Sunken | QStyle::State_On;
    } else {
        btnOn.state |= QStyle::State_Raised;
    }

    // 绘制“女”按钮(右)
    QStyleOptionButton btnOff;
    btnOff.rect = rightRect;
    btnOff.text = "女";
    btnOff.state |= QStyle::State_Enabled;
    if (state == 0) {
        btnOff.state |= QStyle::State_Sunken | QStyle::State_On;
    } else {
        btnOff.state |= QStyle::State_Raised;
    }

    QApplication::style()->drawControl(QStyle::CE_RadioButton, &btnOn,  painter);
    QApplication::style()->drawControl(QStyle::CE_RadioButton, &btnOff, painter);
}

QSize RadioDelegateV2::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    Q_UNUSED(index);
    // 返回足够宽以容纳两个按钮
    QFontMetrics fm(option.font);
    int width = fm.horizontalAdvance("男") + fm.horizontalAdvance("女") + 40; // 加 padding
    int height = qMax(fm.height() + 8, 24);
    return QSize(width, height);
}

bool RadioDelegateV2::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
{
    if (event->type() == QEvent::MouseButtonPress) {
        QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
        QPoint pos = mouseEvent->pos();

        QRect rect = option.rect;
        int half = rect.width() / 2;

        int newState;
        if (pos.x() < rect.left() + half) {
            newState = 1; // 点击左侧 → 男
        } else {
            newState = 0; // 点击右侧 → 女
        }

        // 更新模型
        model->setData(index, newState, Qt::DisplayRole);

        return true;
    }
    return false;
}


代码说明:

  1. paint()函数中,创建两个QStyleOptionButton并设置属性;两个按钮根据数据(性别)设置不同的状态;然后使用drawControl()函数绘制按钮;
  2. sizeHint()函数中,计算可以容纳下两个按钮的宽度;
  3. editorEvent()函数中,对编辑事件进行操作,判断点击区域,然后更新数据。

其他说明:

  1. openPersistentEditor()函数调用可以全部优化掉 ;
  2. 如果数据变化有连接的信号,可以使用QStandardItemModel void itemChanged(QStandardItem *item)信号修改。

参考文献:




作者:薄暮知秋

本文来自博客园,转载请注明原文链接:https://www.cnblogs.com/wsry/p/19749661

上一篇:

下一篇:没有了

温馨提示:以上内容整理于网络,仅供参考,如果对您有帮助,留下您的阅读感言吧!
相关阅读
本类排行
相关标签
本类推荐

CPU | 内存 | 硬盘 | 显卡 | 显示器 | 主板 | 电源 | 键鼠 | 网站地图

Copyright © 2025-2035 诺佳网 版权所有 备案号:赣ICP备2025066733号
本站资料均来源互联网收集整理,作品版权归作者所有,如果侵犯了您的版权,请跟我们联系。

关注微信