TableView自定义代理QStyledItemDelegate实现ComboBox

suoniao 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);  //强制类型转换

    spinBox->setValue(value); //设置编辑器的数值

}

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

{

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

    QSpinBox* spinBox = static_cast<QSpinBox*>(editor); //强制类型转换

    spinBox->interpretText(); //解释数据,如果数据被修改后,就触发信号

    int value = spinBox->value(); //获取spinBox的值

    model->setData(index, value, Qt::EditRole); //更新到数据模型

}

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

{

    //设置组件大小

    Q_UNUSED(index);

    editor->setGeometry(option.rect);

}

4、以上几个自定义代理类的使用

    在上节中主窗口的头文件中定义如下

//添加头文件

  #include "QIntSpinDelegate.h"

  #include "QFloatSpinDelegate.h"

  #include "QComboBoxDelegate.h"

  //在头文件中添加下面三个声明

  QIntSpinDelegate    m_intSpinDelegate; //整型数

  QFloatSpinDelegate  m_floatSpinDelegate; //浮点数

  QComboBoxDelegate   m_comboBoxDelegate; //列表选择

  //在源文件中添加为各列设置自定义代理组件

  ui.tableViewStandardModel->setItemDelegateForColumn(0, &m_intSpinDelegate);   //测深,整数

  ui.tableViewStandardModel->setItemDelegateForColumn(1, &m_floatSpinDelegate);   //浮点数

  ui.tableViewStandardModel->setItemDelegateForColumn(2, &m_floatSpinDelegate);  //浮点数

  ui.tableViewStandardModel->setItemDelegateForColumn(3, &m_floatSpinDelegate);  //浮点数

  ui.tableViewStandardModel->setItemDelegateForColumn(4, &m_comboBoxDelegate);  //Combbox选择型


原文地址 https://mp.weixin.qq.com/s/MsMqQMmcbjK63-V16Qc9MA

回帖
  • 消灭零回复
相关主题
Qt利用QLabel组件来显示图片 0
TableView自定义代理QStyledItemDelegate实现ComboBox 0
Qt利用QGraphicsView类实现图片放大缩小平移显示 0
Qt实现非阻塞延迟方法sleep 0
Qt实现webdav客户端功能支持https协议的webdav客户端 0
Qt操作windows注册表的方法 bat从注册表中将键值删除 0
重写QSqlQueryModel实现QTableView显示图片 0
QLocalServer基于本地套接字socket的服务端server 0
Qt使用动态库的方法 QLibrary库的典型用法 0
QT实现视频播放器界面开发 0
QTableview实现鼠标放上面显示不同颜色 0
Qt的QTableView自定义委托详解 0
QTableView利用自定义委托实现日期显示下拉菜单文字颜色等 0
Qt利用QApplication::sendEvent和QMouseEvent模拟鼠标点击事件 0
Qt获取父进程路径和父进程ID代码 0
QStyledItemDelegate和QItemDelegate区别在于绘制和向视图提供编辑器的方式 0
Qt实现全局快捷键功能利用QxtGlobalShortcut库 0
利用QSS去掉QListWidget选中时的虚线框 0
如何自己使用 QEventLoop解决窗口一闪而过的问题 0
Qt 为什么没有提供跨平台的 sleep 函数? 0
相关主题
打印机USB驱动开发之实现打印服务器 0
Qt利用QLabel组件来显示图片 0
TableView自定义代理QStyledItemDelegate实现ComboBox 0
Qt利用QGraphicsView类实现图片放大缩小平移显示 0
Qt实现非阻塞延迟方法sleep 0
海康相机SDK的C++对应的接口 0
Qt实现webdav客户端功能支持https协议的webdav客户端 0
CHKDSK解决 移动硬盘只能看见盘符其它信息都看不见另外双击也打不开 0
gogs一直报errror:dial tcp xxx.xxx.xxx.xxx 宿主机的ip 0
索鸟快传2.1.2发布 0
索鸟快传2.1.1发布 0
Qt操作windows注册表的方法 bat从注册表中将键值删除 0
重写QSqlQueryModel实现QTableView显示图片 0
QLocalServer基于本地套接字socket的服务端server 0
Qt使用动态库的方法 QLibrary库的典型用法 0
QT实现视频播放器界面开发 0
QTableview实现鼠标放上面显示不同颜色 0
Qt的QTableView自定义委托详解 0
QTableView利用自定义委托实现日期显示下拉菜单文字颜色等 0
Qt利用QApplication::sendEvent和QMouseEvent模拟鼠标点击事件 0