TableView自定义代理QStyledItemDelegate实现ComboBox

0 958
索鸟 2021-04-23
需要:0索币

在上一节中,导入数据文件进行编辑时, QTableView组件为每个单元格提供的是缺省的代理编辑组件,就是一个QLineedit组件。在编辑框里可以输入任何数据,所以比较通用。但是有些情况下,希望根据数据的类型限定使用不同的编辑组件,例如在上节的实例的数据中,第1列“测深”是整数,使用 QSpinBox作为编辑组件更合适;“垂深”“方位”“总位移”是浮点数,使用 QDoubleSpin Box更合适;而“固井质量”使用一个 ComboBox,从一组列表文字中选择更合适。要实现这些功能,就需要为 TableView的某列或某个单元格设置自定义代理组件

在上节中的例子中增加代理类的效果如下

2自定义代理类的基本设计要求

    Qt中有关代理的几个类的层次结构如图

QAbstractltem Delegate是所有代理类的抽象基类, QStyledltemDelegate是视图组件使用的缺

省的代理类, QItemDelegate也是类似功能的类。QStyledItemDelegate与 QItemDelegate的差别在于:QStyledltemDelegate可以使用当前的样式表设置来绘制组件,因此建议使用 QStyledltemDelegate作为自定义代理组件的基类。

不管从 QStyledltemDelegate还是 QItemDelegate继承设计自定义代理组件,都必须实现如下

的4个函数:

    createEditor函数创建用于编辑模型数据的 widget组件,如一个 QSpinBox组件,或一个

ComboBox组件;

    setEditorData函数从数据模型获取数据,供 widget组件进行编辑;

    setModelData将 widget上的数据更新到数据模型;

    updateEditorGeometry用于给 widget组件设置一个合适的大小

在上节的例子中新增三个类,QComboBoxDelegate、QFloatSpinDelegate、QIntSpinDelegate

QComboBoxDelegate类的设计代码如下:

#pragma once

#include <QItemDelegate>

class QComboBoxDelegate : public QItemDelegate

{

       Q_OBJECT

public:

       QComboBoxDelegate(QObject* parent = 0);

       ~QComboBoxDelegate();

       //自定义代理组件必须继承以下4个函数

       QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option,

              const QModelIndex& index) const Q_DECL_OVERRIDE;

       void setEditorData(QWidget* editor, const QModelIndex& index) const  Q_DECL_OVERRIDE;

       void setModelData(QWidget* editor, QAbstractItemModel* model,

              const QModelIndex& index) const Q_DECL_OVERRIDE;

       void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem&  option,

              const QModelIndex& index) const Q_DECL_OVERRIDE;

};

#include "QComboBoxDelegate.h"

#include <QComboBox>

QComboBoxDelegate::QComboBoxDelegate(QObject *parent)

       : QItemDelegate(parent)

{

}

QComboBoxDelegate::~QComboBoxDelegate()

{

}

QWidget* QComboBoxDelegate::createEditor(QWidget* parent,

    const QStyleOptionViewItem& option, const QModelIndex& index) const

{

    QComboBox* editor = new QComboBox(parent);

    editor->addItem(QStringLiteral("优"));

    editor->addItem(QStringLiteral("良"));

    editor->addItem(QStringLiteral("一般"));

    editor->addItem(QStringLiteral("不合格"));

    return editor;

}

void QComboBoxDelegate::setEditorData(QWidget* editor, const QModelIndex& index)  const

{

    QString str = index.model()->data(index, Qt::EditRole).toString();

    QComboBox* comboBox = static_cast<QComboBox*>(editor);

    comboBox->setCurrentText(str);

}

void QComboBoxDelegate::setModelData(QWidget* editor, QAbstractItemModel* model,  const QModelIndex& index) const

{

    QComboBox* comboBox = static_cast<QComboBox*>(editor);

    QString str = comboBox->currentText();

    model->setData(index, str, Qt::EditRole);

}

void QComboBoxDelegate::updateEditorGeometry(QWidget* editor,

    const QStyleOptionViewItem& option, const QModelIndex& index) const

{

    editor->setGeometry(option.rect);

}

QFloatSpinDelegate类的设计代码如下

#pragma once

#include <QStyledItemDelegate>

class QFloatSpinDelegate : public QStyledItemDelegate

{

       Q_OBJECT

public:

       QFloatSpinDelegate(QObject* parent = 0);

       ~QFloatSpinDelegate();

       //自定义代理组件必须继承以下4个函数

       QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option,

              const QModelIndex& index) const Q_DECL_OVERRIDE;

       void setEditorData(QWidget* editor, const QModelIndex& index) const  Q_DECL_OVERRIDE;

       void setModelData(QWidget* editor, QAbstractItemModel* model,

              const QModelIndex& index) const Q_DECL_OVERRIDE;

       void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem&  option,

              const QModelIndex& index) const Q_DECL_OVERRIDE;

};

#include "QFloatSpinDelegate.h"

#include  <QDoubleSpinBox>

QFloatSpinDelegate::QFloatSpinDelegate(QObject *parent)

       : QStyledItemDelegate(parent)

{

}

QFloatSpinDelegate::~QFloatSpinDelegate()

{

}

QWidget* QFloatSpinDelegate::createEditor(QWidget* parent,

    const QStyleOptionViewItem& option, const QModelIndex& index) const

{

    Q_UNUSED(option);

    Q_UNUSED(index);

    QDoubleSpinBox* editor = new QDoubleSpinBox(parent);

    editor->setFrame(false);

    editor->setMinimum(0);

    editor->setDecimals(2);

    editor->setMaximum(10000);

    return editor;

}

void QFloatSpinDelegate::setEditorData(QWidget* editor,

    const QModelIndex& index) const

{

    float value = index.model()->data(index, Qt::EditRole).toFloat();

    QDoubleSpinBox* spinBox = static_cast<QDoubleSpinBox*>(editor);

    spinBox->setValue(value);

}

void QFloatSpinDelegate::setModelData(QWidget* editor, QAbstractItemModel* model,  const QModelIndex& index) const

{

    QDoubleSpinBox* spinBox = static_cast<QDoubleSpinBox*>(editor);

    spinBox->interpretText();

    float value = spinBox->value();

    QString str = QString::asprintf("%.2f", value);

    model->setData(index, str, Qt::EditRole);

}

void QFloatSpinDelegate::updateEditorGeometry(QWidget* editor, const  QStyleOptionViewItem& option, const QModelIndex& index) const

{

    editor->setGeometry(option.rect);

}

QIntSpinDelegate类的设计代码如下:

#pragma once

#include <QStyledItemDelegate>

class QIntSpinDelegate : public QStyledItemDelegate

{

       Q_OBJECT

public:

       QIntSpinDelegate(QObject* parent = 0);

       ~QIntSpinDelegate();

       //自定义代理组件必须继承以下4个函数

       //创建编辑组件

       QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option,

              const QModelIndex& index) const Q_DECL_OVERRIDE;

       //从数据模型获取数据,显示到代理组件中

       void setEditorData(QWidget* editor, const QModelIndex& index) const  Q_DECL_OVERRIDE;

       //将代理组件的数据,保存到数据模型中

       void setModelData(QWidget* editor, QAbstractItemModel* model,

              const QModelIndex& index) const Q_DECL_OVERRIDE;

       //更新代理编辑组件的大小

       void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem&  option,

              const QModelIndex& index) const Q_DECL_OVERRIDE;

};

#include "QIntSpinDelegate.h"

#include <QSpinBox>

QIntSpinDelegate::QIntSpinDelegate(QObject *parent)

       : QStyledItemDelegate(parent)

{

}

QIntSpinDelegate::~QIntSpinDelegate()

{

}

QWidget* QIntSpinDelegate::createEditor(QWidget* parent,

    const QStyleOptionViewItem& option, const QModelIndex& index) const

{

    //创建代理编辑组件

    Q_UNUSED(option);

    Q_UNUSED(index);

    QSpinBox* editor = new QSpinBox(parent); //创建一个QSpinBox

    editor->setFrame(false); //设置为无边框

    editor->setMinimum(0);

    editor->setMaximum(10000);

    return editor;  //返回此编辑器

}

void QIntSpinDelegate::setEditorData(QWidget* editor,

    const QModelIndex& index) const

{

    //从数据模型获取数据,显示到代理组件中

    //获取数据模型的模型索引指向的单元的数据

    int value = index.model()->data(index, Qt::EditRole).toInt();

    QSpinBox* spinBox = static_cast<QSpinBox*>(editor);

回帖
  • 消灭零回复
相关主题
2020年最新最新Kubernetes视频教程(K8s)教程 2
程序员转型之制作网课变现,月入过万告别996 1
索鸟快传2.0发布啦 1
两个不同网络的电脑怎么实现文件的互相访问呢? 1
网盘多账号登录软件 1
Java实战闲云旅游项目基于vue+element-ui 1
单点登录技术解决方案基于OAuth2.0的网关鉴权RSA算法生成令牌 1
QT5获取剪贴板上文本信息QT设置剪贴板内容 1
springboot2实战在线购物系统电商系统 1
python web实战之爱家租房项目 1
windows COM实用入门教程 1
C++游戏开发之C++实现的水果忍者游戏 1
计算机视觉库opencv教程 1
node.js实战图书管理系统express框架实现 1
C++实战教程之远程桌面远程控制实战 1
相关主题
PHP7报A non well formed numeric value encountered 0
Linux系统下关闭mongodb的几种命令分享 0
mongodb删除数据、删除集合、删除数据库的命令 0
Git&Github极速入门与攻坚实战课程 0
python爬虫教程使用Django和scrapy实现 0
libnetsnmpmibs.so.31: cannot open shared object file 0
数据结构和算法视频教程 0
redis的hash结构怎么删除数据呢? 0
C++和LUA解析器的数据交互实战视频 0
mongodb errmsg" : "too many users are authenticated 0
C++基础入门视频教程 0
用30个小时精通C++视频教程可能吗? 0
C++分布式多线程游戏服务器开发视频教程socket tcp boost库 0
C++培训教程就业班教程 0
layui的util工具格式时间戳为字符串 0
C++实战教程之远程桌面远程控制实战 1
网络安全培训视频教程 0
LINUX_C++软件工程师视频教程高级项目实战 0
C++高级数据结构与算法视频教程 0
跨域问题很头疼?通过配置nginx轻松解决ajax跨域问题 0