Qt模型model、视图view、代理

       例子为qt5应用及实例第8章

  MVC是一种与用户界面相关的设计模式。通过使用此模型,可以有效地分离数据和用户界面。MVC设计模式包含三要素:表示数据的模型(Model)、表示用户界面的视图(View)和定义了用户在界面上的操作控制(Controller)。
  Qt的设计了一种与MVC类似的设计模式:使用模型/视图结构完成数据和界面的分离,即InterView框架。Qt的InterView框架把视图和控制部件结合在一起,使得框架更为简洁。Qt引入了代理(delegate)更灵活的处理用户的输入,能够自定义数据条目(item)的显示和编辑方式。
  Qt的模型/视图结构分为三个部分:模型、视图、代理。模型与数据源通信并为其他部件提供接口;视图从模型中获得用来引用数据条目的条目索引;在视图中,代理负责绘制数据条目。编辑条目时,代理和模型直接通信;各个部件之间使用信号和槽的方式进行通信。

 

一、案例:文件浏览器

#include <QApplication>
#include <QAbstractItemModel>
#include <QAbstractItemView>
#include <QItemSelectionModel>

#include <QDirModel>
#include <QTreeView>
#include <QListView>
#include <QTableView>
#include <QSplitter>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    // QDirModel类继承自QAbstractItemModel类,为访问本地文件系统提供数据模型,它提供了与文件操作相关的函数
    QDirModel model;

    // 新建三种不同的View对象,以便文件对象可以以三种不同方式显示
    QTreeView tree;
    QListView list;
    QTableView table;

    tree.setModel(&model);
    list.setModel(&model);
    table.setModel(&model);

    // 设置treeView对象的选择方式为多选
    //tree.setSelectionMode(QAbstractItemView::MultiSelection);
    //list.setSelectionModel(tree.selectionModel());
    //table.setSelectionModel(tree.selectionModel());

    QObject::connect(&tree, SIGNAL(doubleClicked(QModelIndex)), &list, SLOT(setRootIndex(QModelIndex)));
    QObject::connect(&tree, SIGNAL(doubleClicked(QModelIndex)), &table, SLOT(setRootIndex(QModelIndex)));

    QSplitter *splitter = new QSplitter;//QSplitter继承自QWidget
    splitter->addWidget(&tree);
    splitter->addWidget(&list);
    splitter->addWidget(&table);
    splitter->setWindowTitle(QObject::tr("InterView"));
    splitter->resize(1500, 600);
    splitter->show();

    return a.exec();
}

 

二、自定义模型Model

1、ModelEx.h

 1 #include <QAbstractTableModel>
 2 #include <QVector>
 3 #include <QMap>
 4 #include <QList>
 5 
 6 class ModelEx : public QAbstractTableModel
 7 {
 8     Q_OBJECT
 9 public:
10     ModelEx(QObject *parent = 0);
11 
12     // 重定义QAbstractTableModel的虚函数
13     virtual int rowCount(const QModelIndex &parent) const;
14     virtual int columnCount(const QModelIndex &parent) const;
15     QVariant data(const QModelIndex &index, int role) const;
16     QVariant headerData(int section, Qt::Orientation orientation, int role) const;
17 
18 private:
19     QVector<short> army;
20     QVector<short> weaponType;
21 
22     QMap<short, QString> armyMap;
23     QMap<short, QString> weaponTypeMap;
24 
25     QStringList weapon;
26     QStringList header;
27 
28     // 完成表格数据的初始化填充
29     void populateModel();
30 };

2、ModelEx.cpp

 1 #include "ModelEx.h"
 2 
 3 ModelEx::ModelEx(QObject *parent) : QAbstractTableModel(parent)
 4 {
 5     armyMap[1] = tr("空军");
 6     armyMap[2] = tr("陆军");
 7     armyMap[3] = tr("海军");
 8     armyMap[4] = tr("海军陆战队");
 9 
10     weaponTypeMap[1] = tr("轰炸机");
11     weaponTypeMap[2] = tr("战斗机");
12     weaponTypeMap[3] = tr("航空母舰");
13     weaponTypeMap[4] = tr("驱逐舰");
14     weaponTypeMap[5] = tr("直升机");
15     weaponTypeMap[6] = tr("坦克");
16     weaponTypeMap[7] = tr("两栖攻击舰");
17     weaponTypeMap[8] = tr("两栖战车");
18 
19     populateModel();
20 }
21 
22 int ModelEx::rowCount(const QModelIndex &parent) const
23 {
24     // 返回行数
25     return army.size();
26 }
27 
28 int ModelEx::columnCount(const QModelIndex &parent) const
29 {
30     // 返回列数
31     return 3;
32 }
33 
34 // 返回指定索引的数据,即将数字映射为文字
35 QVariant ModelEx::data(const QModelIndex &index, int role) const
36 {
37     if (!index.isValid())
38     {
39         return QVariant();
40     }
41 
42     if (role == Qt::DisplayRole)
43     {
44         switch(index.column())
45         {
46         case 0:
47             return armyMap[army[index.row()]];
48             break;
49         case 1:
50             return weaponTypeMap[weaponType[index.row()]];
51             break;
52         case 2:
53             return weapon[index.row()];
54         default:
55             return QVariant();
56         }
57     }
58 
59     return QVariant();
60 }
61 
62 // 设置表头数据
63 QVariant ModelEx::headerData(int section, Qt::Orientation orientation, int role) const
64 {
65     if (role == Qt::DisplayRole && orientation == Qt::Horizontal)
66     {
67         return header[section];
68     }
69 
70     return QAbstractTableModel::headerData(section, orientation, role);
71 }
72 
73 void ModelEx::populateModel()
74 {
75     header << tr("军种") << tr("种类") << tr("武器");
76     army << 1 << 2 << 3 << 4 << 2 << 4 << 3 << 1;
77     weaponType << 1 << 3 << 5 << 7 << 4 << 8 << 6 << 2;
78     weapon << tr("B-2") << tr("尼米兹级") << tr("阿帕奇") << tr("黄蜂级")
79            << tr("阿利伯克级") << tr("AAAV") << tr("M1A1") << tr("F-22");
80 }

3、main,cpp

#include <QApplication>
#include "ModelEx.h"
#include <QTableView>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    ModelEx modelEx;
    QTableView view;
    view.setModel(&modelEx);
    view.setWindowTitle(QObject::tr("weapon"));
    view.resize(600, 600);
    view.show();

    return a.exec();
}

      

 

三、自定义视图View

四、自定义代理

posted @ 2018-09-09 22:08  雪落梅藏  阅读(1504)  评论(0编辑  收藏  举报