• 视图代理(转帖)


      代理就是一个中间人的意思,也就是model和view之间的一个中间件,它协调两者之间的数据处理,以保证数据在显示层和model层的一致性。

                        在qt中实现自己的一个代理,一般继承自QItemDelegate类,当然也可以是QAbstractItemDelegate。

                        在做代理的时候,我们首先要明确一些问题,我们的编辑控件是什么,设置它的值,修改怎么影响model,编辑控件的样式什么样,大小位置是否考虑。在qt中这些需要实现自己代理的方面都以虚函数的形式给出,在实现自己代理的时候,重新实现这些虚函数就行,而调用是自动的,这就是利用C++多态,实现了开闭。

                        下面给出一个例子

                        

    1. #ifndef SPINBOXDELEGATE_H  
    2. #define SPINBOXDELEGATE_H  
    3. #include <QItemDelegate>  
    4. #include <QModelIndex>  
    5. #include <QObject>  
    6. #include <QSize>  
    7. #include <QSpinBox>  
    8.   
    9. #define logger()  qDebug() << __FILE__ << __LINE__ << __func__  
    10.   
    11. class SpinBoxDelegate : public QItemDelegate  
    12. {  
    13.     Q_OBJECT  
    14.   
    15. public:  
    16.     SpinBoxDelegate(QObject *parent = 0);  
    17.     /** 
    18.       * @brief createEditor 进入可编辑的状态时,产生的编辑控件 
    19.       * @param parent 这个控件的上层控件 
    20.       * @param option 一些控件样式选择 
    21.       * @param index 所在的索引位置 
    22.       * @return 编辑控件的指针 
    23.       */  
    24.     QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,  
    25.                           const QModelIndex &index) const;  
    26.     /** 
    27.       * @brief setEditorData 进入和推出编辑模式调用,修改view的值 
    28.       * @param editor 与改变想对应的editor指针 
    29.       * @param index model中的那个索引改变了值 
    30.       */  
    31.     void setEditorData(QWidget *editor, const QModelIndex &index) const;  
    32.     /** 
    33.       * @brief setModelData 退出编辑模式,修改model 
    34.       * @param editor 那个editor改变了 
    35.       * @param model 想对应的model 
    36.       * @param index 对应的索引 
    37.       */  
    38.     void setModelData(QWidget *editor, QAbstractItemModel *model,  
    39.                       const QModelIndex &index) const;  
    40.     /** 
    41.       * @brief updateEditorGeometry 更新位置 
    42.       * @param editor 
    43.       * @param option 
    44.       * @param index 
    45.       */  
    46.     void updateEditorGeometry(QWidget *editor,  
    47.                               const QStyleOptionViewItem &option, const QModelIndex &index) const;  
    48. };  
    49. /** 
    50.    这些虚函数是自动调用的,我们重新实现这些虚函数来达到控制的效果,可以重新实现的虚函数还有好几个,但是意义都是一样的 
    51.  
    52.    */  
    53.   
    54.   
    55. #endif // SPINBOXDELEGATE_H  
    56. #include "spinBoxDelegate.h"  
    57.   
    58. #include <QtGui>  
    59. #include <QDebug>  
    60.   
    61.   
    62. SpinBoxDelegate::SpinBoxDelegate(QObject *parent)  
    63.     : QItemDelegate(parent)  
    64. {  
    65. }  
    66.   
    67. QWidget *SpinBoxDelegate::createEditor(QWidget *parent,  
    68.                                        const QStyleOptionViewItem &/* option */,  
    69.                                        const QModelIndex &/* index */) const  
    70. {  
    71.     logger();  
    72.   
    73.     QSpinBox *editor = new QSpinBox(parent);//产生一个QSpinBox控件  
    74.     editor->setMinimum(0);  
    75.     editor->setMaximum(100);  
    76.   
    77.     return editor;  
    78. }  
    79.   
    80. void SpinBoxDelegate::setEditorData(QWidget *editor,  
    81.                                     const QModelIndex &index) const  
    82. {  
    83.     logger();  
    84.     int value = index.model()->data(index, Qt::EditRole).toInt();//根据index获得model的值  
    85.   
    86.     QSpinBox *spinBox = static_cast<QSpinBox*>(editor);  
    87.     spinBox->setValue(value);  
    88. }  
    89.   
    90. void SpinBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,  
    91.                                    const QModelIndex &index) const  
    92. {  
    93.     logger();  
    94.     QSpinBox *spinBox = static_cast<QSpinBox*>(editor);  
    95.     spinBox->interpretText();  
    96.     int value = spinBox->value();  
    97.   
    98.     model->setData(index, value, Qt::EditRole);  
    99. }  
    100.   
    101. void SpinBoxDelegate::updateEditorGeometry(QWidget *editor,  
    102.                                            const QStyleOptionViewItem &option, const QModelIndex &/* index */) const  
    103. {  
    104.     logger();  
    105.     editor->setGeometry(option.rect);  
    106. }  
    107. #include <QApplication>  
    108. #include <QHeaderView>  
    109. #include <QItemSelectionModel>  
    110. #include <QStandardItemModel>  
    111. #include <QTableView>  
    112.   
    113. #include "spinBoxDelegate.h"  
    114.   
    115. int main(int argc, char *argv[])  
    116. {  
    117.     QApplication app(argc, argv);  
    118.   
    119.     QStandardItemModel model(4, 2);  
    120.     QTableView tableView;  
    121.     tableView.setModel(&model);  
    122.   
    123.     SpinBoxDelegate delegate;  
    124.     tableView.setItemDelegate(&delegate);  
    125.   
    126.     tableView.horizontalHeader()->setStretchLastSection(true);  
    127.     tableView.verticalHeader()->setStretchLastSection(true);  
    128.   
    129.     for (int row = 0; row < 4; ++row) {  
    130.         for (int column = 0; column < 2; ++column) {  
    131.             QModelIndex index = model.index(row, column, QModelIndex());  
    132.             model.setData(index, QVariant((row+1) * (column+1)));  
    133.         }  
    134.     }  
    135.   
    136.     tableView.setWindowTitle(QObject::tr("Spin Box Delegate"));  
    137.     tableView.show();  
    138.     return app.exec();  
    139. }  


              可以根据打印的logger知道这些虚函数是怎么调用的,加深对整个框架运行机制的理解

  • 相关阅读:
    unity, 调节图片导入尺寸
    photoshop, 钢笔上色
    maxscript, 批量导出物体
    unity, readOnly varible
    通过Maven找java source源码方法
    Nginx技巧:灵活的server_name,Nginx配置一个服务器多个站点 和 一个站点多个二级域名
    设置局域网共享文件不需要用户名密码
    SELECT INTO 和 INSERT INTO SELECT 两种表复制语句
    利用nginx泛域名解析配置二级域名和多域名
    三分钟了解Activity工作流
  • 原文地址:https://www.cnblogs.com/alleyonline/p/4903333.html
Copyright © 2020-2023  润新知