qt中delegate的使用

Qt中使用delegate来自定义控件的显示方法。与传统的MVC模式不同,在此之前,先了解一下何为MVC模式。

 MVC架构是"Model-View-Controller"的缩写,中文翻译为"模式-视图-控制器"。MVC应用程序总是由这三个部分组成。Event(事件)导致Controller改变Model或View,或者同时改变两者。只要Controller改变了Models的数据或者属性,所有依赖的View都会自动更新。类似的,只要Controller改变了View,View会从潜在的Model中获取数据来刷新自己。

 

 

Qt使用的是model/view 模式, MVC模式不同,model/view结构没有用于与用户交互的完全独立的组件。一般来讲, view负责把数据展示给用户,也处理用户的输入。为了获得更多的灵性性,交互通过delegagte执行。它既提供输入功能又负责渲染view中的每个数据项。 
使用Delegate
的原因  Qt中当用到QTreeView和QTableView等用于显示item的视图时,你要编辑一个item用到的编辑工具可能是除了默认文字编辑lineEdit以外的工具,例如button,spinBox,甚至Slider,ProgressBar,也有可能是自定义的widget。所以Qt提供了一个委托类,用来处理View中的数据展示方式。

 

现在来看一下使用步骤。

1. 新建一个类 ,继承于QStyledItemDelegate

2. 重写以下函数

virtual QSize  sizeHint(const QStyleOptionViewItem & option,

       const QModelIndex & index) const;

 

   // 决定如何绘图

   virtual void  paint(QPainter * painter,

       const QStyleOptionViewItem & option,

       const QModelIndex & index) const;

 

3.对于原位编辑,采取以下步骤:

/* 原位编辑 */

 

    // 1步:创建一个widget作为编辑器

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

        const QModelIndex &index) const;

 

    // 2步:调用编辑器的显示位置

    void updateEditorGeometry(QWidget *editor,

        const QStyleOptionViewItem &option, const QModelIndex &index) const;

 

    // 3步:初始化显示数据

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

 

    // -------------------------

 

    // 4步:用户完成编辑、编辑器被关闭时,提供数据到model

    void setModelData(QWidget *editor, QAbstractItemModel *model,

       const QModelIndex &index) const;

 

4.最后,在要使用的控件调用如下函数

   ui.treeWidget->setItemDelegate(new Mydelegate(ui.treeWidget));

//以树控件为例

 

源代码示例

头文件 mydelegate.h

#pragma once

 

#include <QStyledItemDelegate>

#include <QString>

#include<QPainter>

class Mydelegate : public QStyledItemDelegate

{

    Q_OBJECT

 

public:

    Mydelegate(QObject *parent);

    ~Mydelegate();

 

private:

    /* 自定义单元格显示  */

 

    // 决定该单元格的推荐大小

    virtual QSize  sizeHint(const QStyleOptionViewItem & option,

        const QModelIndex & index) const;

 

    // 决定如何绘图

    virtual void  paint(QPainter * painter,

        const QStyleOptionViewItem & option,

        const QModelIndex & index) const;

 

 

private:

    /* 原位编辑 */

 

    // 1步:创建一个widget作为编辑器

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

        const QModelIndex &index) const;

 

    // 2步:调用编辑器的显示位置

    void updateEditorGeometry(QWidget *editor,

        const QStyleOptionViewItem &option, const QModelIndex &index) const;

 

    // 3步:初始化显示数据

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

 

    // -------------------------

 

    // 4步:用户完成编辑、编辑器被关闭时,提供数据到model

    void setModelData(QWidget *editor, QAbstractItemModel *model,

        const QModelIndex &index) const;

 

private:

    QString m_defaultText;

 

 

};

 

Cpp文件:mydelegate.cpp

 

#include "Mydelegate.h"

#include "GBK.h"

#include <QLineEdit>

Mydelegate::Mydelegate(QObject *parent)

    : QStyledItemDelegate(parent)

{

    m_defaultText = GBK::ToUnicode("双击添加...");

}

 

 

Mydelegate::~Mydelegate()

{

}

 

void Mydelegate::paint(QPainter * painter,

    const QStyleOptionViewItem & option,

    const QModelIndex & index) const

{

    // QStyledItemDelegate::paint(painter,option, index);

 

    QRect rect = option.rect; // 目标矩形

    rect.adjust(2, 2, -2, -2); // 缩小一圈,留出空白间隔

 

                               // 状态显示: 若该项被选中,背景高亮显示

    bool selected = false;

    if (option.state & QStyle::State_Selected)

    {

        selected = true;

        painter->setPen(Qt::NoPen);

 

        painter->setBrush(Qt::SolidPattern);

        painter->setBrush(QColor(0x53, 0x86,0x8b));

        painter->drawRoundedRect(rect, 2, 2);

    }

 

    int rowid = index.data(Qt::UserRole).toInt();

    if (rowid < 0)

    {

        // 空条目

        painter->setBrush(Qt::NoBrush);

        painter->setPen(Qt::DotLine);

        painter->drawRect(rect);

 

        QRect dst = rect;

        dst.adjust(2, 2, -2, -2);

        if (selected)

            painter->setPen(QColor(0xCC, 0xCC,0xCC));

        else

            painter->setPen(QColor(0x99, 0x99,0x99));

        painter->drawText(dst, Qt::AlignLeft | Qt::AlignVCenter, m_defaultText);

    }

    else

    {

        // 有意义的条目

        QString text = index.data(Qt::DisplayRole).toString();

        QRect dst = rect;

 

        if (selected)

            painter->setPen(QColor(0xFF, 0xFF,0xFF));

        else

            painter->setPen(QColor(0x00, 0x00,0x00));

        painter->drawText(dst, Qt::AlignLeft | Qt::AlignVCenter, text);

    }

 

}

 

// 决定该单元格的推荐大小

QSize Mydelegate::sizeHint(const QStyleOptionViewItem & option,

    const QModelIndex & index) const

{

    // returnQStyledItemDelegate::sizeHint(option, index);

 

    QSize  size = QStyledItemDelegate::sizeHint(option, index);

    size.setHeight(32);

    return size;

}

 

// 1步:创建一个widget作为编辑器

QWidget* Mydelegate::createEditor(QWidget *parent,

    const QStyleOptionViewItem &option,

    const QModelIndex &index) const

{

    // qDebug() <<"createEditor";

    QLineEdit* editor = new QLineEdit(parent); //创建一个文本框作为编辑器

    return editor;

}

 

// 2步:调用编辑器的显示位置

void Mydelegate::updateEditorGeometry(QWidget *editor,

    const QStyleOptionViewItem &option,

    const QModelIndex &index) const

{

    // qDebug() <<"updateEditorGeometry";

    QRect rect = option.rect.adjusted(2, 2, -2, -2);

    editor->setGeometry(rect);

 

}

 

 

// 3步:初始化显示数据

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

{

    // qDebug() <<"setEditorData";

 

    QString text = index.data(Qt::DisplayRole).toString();

    QLineEdit* ed = (QLineEdit*)editor;

    ed->setText(text);

}

 

 

// 第四步:用户完成编辑,编辑器被关闭时,提供数据到model

void Mydelegate::setModelData(QWidget *editor,

    QAbstractItemModel *model,

    const QModelIndex &index) const

{

    // qDebug() <<"setModelData";

 

    QLineEdit* lineEdit = (QLineEdit*)editor;

    QString value = lineEdit->text();

    if (value.length() > 0)

    {

        model->setData(index, value, Qt::DisplayRole);

    }

 

    // 修改数据,触发QListWidget的信号:QListWidget::itemChanged

}

 

  • 4
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
A:在Qt使用model和delegate可以实现高效的数据显示和修改。以下是使用模型和委托的步骤: 1. 创建一个继承自QAbstractItemModel类的自定义模型。 2. 实现以下方法: a. rowCount()和columnCount():分别返回数据项的行数和列数。 b. data():返回指定索引的数据项。 c. setData():设置指定索引的数据项的值。 d. flags():返回指定索引的数据项的标志,如是否可编辑、是否可选等。 e. index()和parent():返回指定行和列的索引和父索引。 f. headerData():返回表头数据。 3. 创建一个继承自QStyledItemDelegate类的自定义委托。 4. 实现以下方法: a. paint():绘制表格项。 b. createEditor():创建编辑器。 c. setEditorData():将数据传输到编辑器。 d. setModelData():从编辑器获取数据。 e. updateEditorGeometry():设置编辑器位置和大小。 5. 在需要使用表格视图的地方,创建一个QTableView对象,并设置model和delegate。 6. 将数据加载到模型,可以使用setRowCount()、setColumnCount()、setData()等方法。 7. 对表格项进行修改时,调用setData()方法,该方法调用模型的setData()方法,最终数据被保存在模型。 8. 在需要更新视图时,可以使用update()方法进行刷新。 注意事项: 1. model和delegate的生命周期需要保持一致,否则会导致内存泄漏。 2. 在使用自定义委托时,需要在model设置制定列的editable属性为true,否则无法触发编辑行为。 3. 在使用自定义委托时,需要考虑数据类型和格式,以便正确地显示和修改数据。 4. 在使用自定义委托时,需要考虑委托的样式和交互方式,以便提高用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值