• Qt--自定义Delegate


    这是Model/View中的最后一篇了,Qt官方显然弱化了Controller在MVC中的作用,提供了一个简化版的Delegate;甚至在Model/View框架的使用中,提供了默认的委托,让这个控制器愈加淡出开发者的实现。

    实际上,Qt Model/View框架中的MVC概念是有误的,显而易见的就是Controller的作用,控制器应该只对交互进行控制,渲染方面的工作应该仅由View完成,但Delegate的接口中却包含了这一块。不过这都不是这篇文章的重点,我们只关注Delegate本身。

    1. 实现一个自定义Delegate

    这里我们也来实现一个自定义Delegate,怀着了解Delegate的目的,主要实现以下几个功能:

    1. 以不同颜色绘制View。
      
    2. 双击View方格区域弹出行编辑器,默认覆盖这个区域,显示字母。
      
    3. 输入行编辑器内的内容会被保存,下次点开显示。
      
    4. 鼠标停留,显示提示框。
      

    2. 继承QAbstractItemDelegate

    Qt提供了几个标准的委托:

    1. QItemDelegate:Qt**曾经**默认使用的委托。
      
    2. QStyledItemDelegate。:**现在**默认使用的委托,官方推荐我们使用这个。(自从Qt 4.4)
      

    为了熟悉委托借口,我们继承虚基类QAbstractItemDelegate来实现我们的自定义委托。

    3. 实现虚函数

    出去虚析构函数,QAbstractItemDelegate总共有9个虚函数,下面分别介绍。

    paint()函数用来重绘view。我们这里选择用随机颜色填充背景:

    void CustomeDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        if (!index.isValid() || option.state == QStyle::State_None || !index.isValid())
            return;
    
        painter->fillRect(option.rect, QColor(m_randomColor(m_generator)));
    }
    

    createEditor()destroyEditor()的用途非常明显,双击View的时候会弹出一个行编辑器:

    QWidget* CustomeDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        return new QLineEdit(parent);
    }
    
    void CustomeDelegate::destroyEditor(QWidget *editor, const QModelIndex &index) const
    {
        Q_ASSERT(dynamic_cast<QLineEdit*>(editor) != 0);
    
        delete dynamic_cast<QLineEdit*>(editor);
    }
    

    helpEvent()表示帮助事件,当发生QEvent::ToolTip或者QEvent::WhatsThis事件的时候,就会调用这个函数,我们这里根据事件不同显示不同内容的Tool Tip:

    bool CustomeDelegate::helpEvent(QHelpEvent *event, QAbstractItemView *view, const QStyleOptionViewItem &option, const QModelIndex &index)
    {
        if (event->type() == QEvent::ToolTip) {
            QToolTip::showText(QCursor::pos(), QString("CustomeDelegate Tooltip"), reinterpret_cast<QWidget*>(view), option.rect, 1000);
        } else if (event->type() == QEvent::WhatsThis) {
            QToolTip::showText(QCursor::pos(), QString("CustomeDelegate Whatsthis"), reinterpret_cast<QWidget*>(view), option.rect, 1000);
        }
        return true;
    }
    

    当Editor显示的时候,会调用setEditorData()这个函数来显示默认的文字:

    void CustomeDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
    {
        dynamic_cast<QLineEdit*>(editor)->setText(index.data(Qt::DisplayRole).toString());
    }
    

    setModelData()这个函数用来更新Model中的数据:

    void CustomeDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
    {
        model->setData(index, dynamic_cast<QLineEdit*>(editor)->text(), Qt::DisplayRole);
    }
    

    updateEditorGeometry()这个函数也会在Editor显示的时候被调用,双击不同方格时,我们用它来更新编辑器的位置和大小:

    void CustomeDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        dynamic_cast<QLineEdit*>(editor)->setFixedSize(option.rect.width(), option.rect.height());
        dynamic_cast<QLineEdit*>(editor)->move(option.rect.topLeft());
    }
    

    4. 运行结果

    result-img1 result-img2 result-img3

    完整代码见此处

  • 相关阅读:
    突然想谈谈——我的软件测试入门
    js+rem动态计算font-size的大小,适配各种手机设备!
    iOS 如何打测试包,直接给测试人员使用(绝对的新手入门)
    去掉无用的多余的空格(string1.前后空格,2.中间空格)
    iOS 自定义键盘ToolBar(与键盘的弹出、收起保持一致)
    iOS上线...踩坑
    iOS10 导航条,这个二狗子变了...踩坑
    ios程序发布测试打包
    获取毫秒级时间戳
    弹簧动画效果(系统自带方法)
  • 原文地址:https://www.cnblogs.com/lgxZJ/p/7617715.html
Copyright © 2020-2023  润新知