QT笔记:代理(Delegate)小结

本文介绍如何在Qt中通过两种方式实现自定义代理类,包括从QAbstractItemDelegate类和QItemDelegate类继承的方法。重点讲解了paint()、sizeHint()函数的实现细节以及SpinBoxDelegate的具体代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

用户实现代理类时,可以从两个类中继承

第一种:从QAbstractItemDelegate类中继承,至少需要实现两个函数,paint()和sizeHint()

void MyDelegate::paint(QPainter*painter,const QStyleOptionViewItem&option, constQModelIndex&index)const
{
    if (index.column() == 需代理的列) {
        int content = index.model()->data(index, Qt::DisplayRole).toInt(); // 取到模型中原来的内容
        // ... 修改取到的值,代码略                QStyleOptionViewItem myOption = option;
        myOption.displayAlignment = Qt::AlignRight | Qt::AlignVCenter; // 处理文本的对齐方式 (不重要)

        drawDisplay(painter, myOption, myOption.rect, 修改后的值); // 写回处理后的值
        drawFocus(painter, myOption, myOption.rect); // 如果当前项具有焦点,它就绘制一个焦点矩形(不重要)
    } else{
        QItemDelegate::paint(painter, option, index);
    }
}

QSize MyDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{    
    if (条件) {
        return Qsize(int width, int height); // 用户定义
    } else {
        return QStyledItemDelegate::sizeHint(option, index);
    }
}

 

第二种:从QItemDelegate类继承,一般使用这种方式,减少代码量

.h文件

#ifndef DELEGATE_H
#define DELEGATE_H

#include <QItemDelegate>
#include <QModelIndex>
#include <QObject>
#include <QSize>
#include <QSpinBox>

class SpinBoxDelegate : public QItemDelegate
{
    Q_OBJECT

public:
    SpinBoxDelegate(QObject *parent = 0);

    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;

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

    void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;
};
#endif


.cpp文件

SpinBoxDelegate::SpinBoxDelegate(QObject *parent)
    : QItemDelegate(parent)
{
}

QWidget *SpinBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &/* option */,
    const QModelIndex &/* index */) const
{
    QSpinBox *editor = new QSpinBox(parent);
    editor->setMinimum(0);
    editor->setMaximum(100);

    return editor;
}

void SpinBoxDelegate::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 SpinBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
                                   const QModelIndex &index) const
{
    QSpinBox *spinBox = static_cast<QSpinBox*>(editor);
    spinBox->interpretText();
    int value = spinBox->value();

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

void SpinBoxDelegate::updateEditorGeometry(QWidget *editor,
    const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
{
    editor->setGeometry(option.rect); // option.rect属性中保存了条目的位置,这里将控件设置在刚好占住条目的位置
}


 

 

 

 

 

 

Qt动态代理是一种在Qt框架下通过信号与槽机制实现的一种设计模式,主要用于解耦组件之间的直接依赖关系。它允许一个对象(代理)代表另一个对象(目标),并且可以拦截、修改甚至阻止某些操作。 ### Qt 动态代理的核心思想 1. **信号与槽**:这是Qt特有的通信机制,也是实现代理的基础。当某个事件触发时,发送者会发出信号,并由接收者的相应槽函数处理。 2. **解耦合**:动态代理可以帮助我们将实际业务逻辑从界面或其他模块中分离出来,使得系统更易于维护和测试。 3. **增强功能**:除了简单地转发请求外,还可以加入日志记录、权限检查等额外的功能而无需改变原服务端代码。 4. **灵活性高**:因为所有连接都是运行时建立而非硬编码进程序里头去的所以非常灵活适配性强。 --- #### 实现步骤 - 定义好需要被代理的服务提供方(`Server`)以及它的公共接口; - 创建一个中间层即我们的`Proxy`类继承自QObject并实现上述提到的那个共同遵守的标准协议然后注册对应的方法映射表最后关联真实的后台处理器动作即可完成整个流程构建工作了! 例如: ```cpp class MyService : public QObject { Q_OBJECT public slots: void doSomething() { /* 真正的操作 */ } }; class Proxy : public QObject{ Q_OBJECT private: MyService *m_service; public: explicit Proxy(QObject* parent = nullptr) : QObject(parent), m_service(new MyService(this)){} signals: // 转发给客户端的消息 void notify(); public slots: void requestAction(){ qDebug("Before calling..."); emit notify(); // 可选的通知 if(m_service){ m_service->doSomething(); } qDebug("After called."); } }; ``` 在这个例子当中我们创建了一个简单的服务和对应的代理实例化之后就能正常运作起来了同时保留扩展的可能性比如添加更多的验证规则之类的都很容易做到不影响既有结构稳定性前提条件下做出改进优化调整策略等等都是非常便利的事情呢~ ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值