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

7.qsqlquerymodel 与 qtableview使用

目录

  • qtableview 委托
  • QStyledItemDelegate
  • QAbstractItemDelegate
  • CheckBoxItemDelegate
  • 使用

qtableview 委托


//设置单元格委托
void setItemDelegate(QAbstractItemDelegate *delegate);
QAbstractItemDelegate *itemDelegate() const;

//设置列委托
void setItemDelegateForColumn(int column, QAbstractItemDelegate *delegate);
QAbstractItemDelegate *itemDelegateForColumn(int column) const;

//设置行委托
void setItemDelegateForRow(int row, QAbstractItemDelegate *delegate);
QAbstractItemDelegate *itemDelegateForRow(int row) const;

QStyledItemDelegate

查看qtableview源码会发现itemdelegate默认就是QStyledItemDelegate
如果要自己写自定义的委托请尽量参考QStyledItemDelegate

显示事件

void QStyledItemDelegate::paint(QPainter *painter,
        const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    Q_ASSERT(index.isValid());

    QStyleOptionViewItem opt = option;
    initStyleOption(&opt, index);

    const QWidget *widget = QStyledItemDelegatePrivate::widget(option);
    QStyle *style = widget ? widget->style() : QApplication::style();
    style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, widget);
}

初始化绘制参数配置

void QStyledItemDelegate::initStyleOption(QStyleOptionViewItem *option,
                                         const QModelIndex &index) const
{
    QVariant value = index.data(Qt::FontRole);
    if (value.isValid() && !value.isNull()) {
        option->font = qvariant_cast<QFont>(value).resolve(option->font);
        option->fontMetrics = QFontMetrics(option->font);
    }

    value = index.data(Qt::TextAlignmentRole);
    if (value.isValid() && !value.isNull())
        option->displayAlignment = Qt::Alignment(value.toInt());

    value = index.data(Qt::ForegroundRole);
    if (value.canConvert<QBrush>())
        option->palette.setBrush(QPalette::Text, qvariant_cast<QBrush>(value));

    option->index = index;
    value = index.data(Qt::CheckStateRole);
    if (value.isValid() && !value.isNull()) {
        option->features |= QStyleOptionViewItem::HasCheckIndicator;
        option->checkState = static_cast<Qt::CheckState>(value.toInt());
    }

    value = index.data(Qt::DecorationRole);
    if (value.isValid() && !value.isNull()) {
        option->features |= QStyleOptionViewItem::HasDecoration;
        switch (value.type()) {
        case QVariant::Icon: {
            option->icon = qvariant_cast<QIcon>(value);
            QIcon::Mode mode;
            if (!(option->state & QStyle::State_Enabled))
                mode = QIcon::Disabled;
            else if (option->state & QStyle::State_Selected)
                mode = QIcon::Selected;
            else
                mode = QIcon::Normal;
            QIcon::State state = option->state & QStyle::State_Open ? QIcon::On : QIcon::Off;
            QSize actualSize = option->icon.actualSize(option->decorationSize, mode, state);
            // For highdpi icons actualSize might be larger than decorationSize, which we don't want. Clamp it to decorationSize.
            option->decorationSize = QSize(qMin(option->decorationSize.width(), actualSize.width()),
                                           qMin(option->decorationSize.height(), actualSize.height()));
            break;
        }
        case QVariant::Color: {
            QPixmap pixmap(option->decorationSize);
            pixmap.fill(qvariant_cast<QColor>(value));
            option->icon = QIcon(pixmap);
            break;
        }
        case QVariant::Image: {
            QImage image = qvariant_cast<QImage>(value);
            option->icon = QIcon(QPixmap::fromImage(image));
            option->decorationSize = image.size() / image.devicePixelRatio();
            break;
        }
        case QVariant::Pixmap: {
            QPixmap pixmap = qvariant_cast<QPixmap>(value);
            option->icon = QIcon(pixmap);
            option->decorationSize = pixmap.size() / pixmap.devicePixelRatio();
            break;
        }
        default:
            break;
        }
    }

    value = index.data(Qt::DisplayRole);
    if (value.isValid() && !value.isNull()) {
        option->features |= QStyleOptionViewItem::HasDisplay;
        option->text = displayText(value, option->locale);
    }

    option->backgroundBrush = qvariant_cast<QBrush>(index.data(Qt::BackgroundRole));

    // disable style animations for checkboxes etc. within itemviews (QTBUG-30146)
    option->styleObject = 0;
}

当然有些列子https://blog.csdn.net/c1s2d3n4cs/article/details/143203486

行委托一般用来作为背景委托
列委托与单元格委托是一组,就是简单的优先级
列委托优先级》单元格委托

QAbstractItemDelegate

那么为了自定义qtableview 需要使用到这个QAbstractItemDelegate委托类
在这里插入图片描述

很遗憾,官方没给我们提供checkboxitemdelegate或者comboboxdelegate之类的委托
那么我们就需要自己去写一个
请参考https://blog.csdn.net/Gerald_Jones/article/details/106594052

CheckBoxItemDelegate

继承QItemDelegate需要实现一下几个虚函数

编辑模式,因为我们使用qsqlquerymodel 只读模型 所以可以不用写

// 创建编辑器
	virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
	// 设置编辑器数据
	virtual void setEditorData(QWidget *editor, const QModelIndex &index) const override;
	// 更新编辑器集合属性
	virtual void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
	// 设置模型数据
	virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override;

//如果是只读的组件那么我们只需要以下两个方法

CheckBoxItemDelegate.h

#ifndef CHECKBOXITEMDELEGATE_H
#define CHECKBOXITEMDELEGATE_H

#include <QObject>
#include <QItemDelegate>
#include <QStyledItemDelegate>
#include <QCheckBox>
#include <QStylePainter>
#include <QDebug>
#include <QStyleOptionButton>

class CheckBoxItemDelegate : public QItemDelegate
{
    Q_OBJECT
public:
    explicit CheckBoxItemDelegate(QObject *parent = nullptr);
    ~CheckBoxItemDelegate();

    //---只读
    void paint(QPainter *painter,
               const QStyleOptionViewItem &option,
               const QModelIndex &index) const override;

    bool editorEvent(QEvent *event,
                     QAbstractItemModel *model,
                     const QStyleOptionViewItem &option,
                     const QModelIndex &index) override;

    //---编辑模式
    // 创建编辑器 ---- 返回组件
    //     QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
    //    // 设置编辑器数据 ---- 初始化组件数据
    //     void setEditorData(QWidget *editor, const QModelIndex &index) const override;
    //    // 更新编辑器集合属性 --- 设置位置
    //     void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
    //    // 设置模型数据 ---- 修改数据模型数据
    //     void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override;

signals:

protected:
    void initStyleOption(QStyleOptionButton *option,
                         const QStyleOptionViewItem *copy,
                         const QModelIndex &index) const;

private:
    bool m_checked = false;


};

#endif // CHECKBOXITEMDELEGATE_H


CheckBoxItemDelegate.cpp

#include "CheckBoxItemDelegate.h"
#include <QApplication>


CheckBoxItemDelegate::CheckBoxItemDelegate(QObject *parent) : QItemDelegate(parent)
{
    qDebug()<< __FUNCTION__;
}

CheckBoxItemDelegate::~CheckBoxItemDelegate()
{
    qDebug()<< __FUNCTION__;
}

void CheckBoxItemDelegate::paint(QPainter *painter,
                                 const QStyleOptionViewItem &option,
                                 const QModelIndex &index) const
{
    QStyleOptionButton opt;
    initStyleOption(&opt, &option, index);


    const QWidget *widget = option.widget;
    QStyle *style = widget ? widget->style() : QApplication::style();
    style->drawControl(QStyle::CE_CheckBox, &opt, painter, widget);
}

bool CheckBoxItemDelegate::editorEvent(QEvent *event,
                                       QAbstractItemModel *model,
                                       const QStyleOptionViewItem &option,
                                       const QModelIndex &index)
{
    //选中或者取消选中
    m_checked = true;

    return false;
}

//QWidget *CheckBoxItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
//{

//    return new QCheckBox(parent);
//}

//void CheckBoxItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
//{
//    QCheckBox *cb = static_cast<QCheckBox *>(editor);
//    cb->setChecked(true);
//}

//void CheckBoxItemDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
//{
//    editor->setGeometry(option.rect);
//}

//void CheckBoxItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
//{
//    //    QCheckBox *cb = static_cast<QCheckBox *>(editor);
//    //    model->setData(index, cb->isChecked());
//}

void CheckBoxItemDelegate::initStyleOption(QStyleOptionButton *option,
                                           const QStyleOptionViewItem *copy,
                                           const QModelIndex &index) const
{
    QRect boxRect = QApplication::style()->subElementRect(QStyle::SE_CheckBoxIndicator,option);
    option->rect = copy->rect;
    option->rect.setLeft(copy->rect.left()+(copy->rect.width()-boxRect.width())/2); //居中
    //option->rect.setTop(copy->rect.top()+(copy->rect.height()-option->rect.height())/2);
    option->state = m_checked? QStyle::State_On: QStyle::State_Off;
}

至于初始化选中状态由外部的section管理器来决定来决定
所以我们需要
实现一个选择管理器(支持单选,多选,跨页选)
我好想又看到qml有一个TableViewSelection.qml
至于c++有没有这个选择管理器还得自己去实现

使用

    QTableView *view = new QTableView(this);
    CheckBoxItemDelegate* cb_delegate = new CheckBoxItemDelegate(this);
    view->setModel(model);
    view->move(0,400);
    view->setItemDelegateForColumn(0,cb_delegate);

http://www.kler.cn/a/382004.html

相关文章:

  • 教培行业数字化未来:一站​式开发在线教育系统源码与网校APP详解
  • vue3标签中的ref属性如何使用$refs获取元素
  • 【从零开始入门unity游戏开发之——unity篇02】unity6基础入门——软件下载安装、Unity Hub配置、安装unity编辑器、许可证管理
  • 羊城杯2020 easycon
  • C++中的字符串实现
  • Postman接口测试工具使用详解
  • HBuilderx修改主题色-改变编辑器背景颜色等
  • 【AI换装整合包及教程】OOTDiffusion: AI换装工具的革命性创新
  • 浅谈QT中Tab键的切换逻辑
  • C++工厂模式全解析:从简单工厂到抽象工厂的进阶之路
  • 【案例】旗帜飘动
  • 详解原型模式
  • 光伏设计软件如何快速上手?
  • IntelliJ Idea设置自定义快捷键
  • 跳蚤市场之商品发布功能
  • AI之硬件对比:据传英伟达Nvidia2025年将推出RTX 5090-32GB/RTX 5080-24GB、华为2025年推出910C/910D
  • 设计模式之——简单工厂模式
  • 树状数组(Binary Indexed Tree/Fenwick Tree)详解
  • ORA-00054: 资源正忙, 但指定以 NOWAIT 方式获取资源 或者超时失效
  • Java并发常见面试题总结(下)
  • 25.停车场管理系统(基于web的Java项目)
  • SpringBoot day 1105
  • springcloud各组件说明
  • ctfshow(89,90,92,93)--PHP特性--intval函数
  • 【RDD算子的分类】RDD的转换算子和触发算子(行为算子)、以及各个算子的作用,对比sql中的关键字
  • 【系统架构设计师(第2版)】十一、未来信息综合技术