QT MVC模式

    QT项视图类主要有三种: QListView,QTreeView,QTableView,对应的基础Model为 QAbstractItemModel(QStandardItemModelo为QAbstractItemModel实现), 对于QListView和QTableView则分别提供了QStringListModel,QAbstractTableModel实现. 

   一直不太喜欢用MVC模型,对于很简单的视图,使用MVC反而显得有点复杂,大材小用了. QT中对于QListView,QTreeView,QTableView这三个视图提供了其简便实现类QListWidget,QTreeWidget,QTableWidget. 如果处理比较复杂且数据量比较大的视图,MVC就显现出其优越性了,下面看例子:

 

   history table view

 

一. QTableWidget实现

Cpp代码   收藏代码
  1. QTableWidget tableWidget;  
  2. tableWidget.setAlternatingRowColors(true);  
  3. tableWidget.setWindowTitle("历史曲线");  
  4.   
  5. // 设置水平/垂直方向标签  
  6. tableWidget.setColumnCount(2);  
  7. tableWidget.setRowCount(2);  
  8. tableWidget.setHorizontalHeaderLabels(QStringList()<<"0分钟"<<"5分钟");  
  9. tableWidget.setVerticalHeaderLabels(QStringList()<<"0小时"<<"1小时");  
  10.   
  11. // 填充数据  
  12. for(int i=0;i<2;i++) // 行  
  13. {  
  14.     for(int j=0;j<2;j++) // 列  
  15.     {  
  16.         QTableWidgetItem *item=new QTableWidgetItem;  
  17.         item->setText(QString::number(datas[i*2+j]));  
  18.   
  19.         tableWidget.setItem(i,j,item);  
  20.     }  
  21. }  
  22.   
  23. tableWidget.show();  

   QTableWidget构建表格,需要手动一个一个添加数据,视图与数据层深度耦合

 

二. QListView+QStandardItemModel实现

Cpp代码   收藏代码
  1. // 标准model实现  
  2. QStandardItemModel hisModel(2,2); // 定义2行2列模型  
  3. hisModel.setHorizontalHeaderLabels(QStringList()<<"0分钟"<<"5分钟");  
  4. hisModel.setVerticalHeaderLabels(QStringList()<<"0小时"<<"1小时");  
  5. for(int i=0;i<2;i++) // 行  
  6. {  
  7.     for(int j=0;j<2;j++) // 列  
  8.     {  
  9.         QStandardItem *item=new QStandardItem;  
  10.         item->setText(QString::number(datas[i*2+j]));  
  11.   
  12.         hisModel.setItem(i,j,item); // model设置数据  
  13.     }  
  14. }  
  15.   
  16. QTableView tableView;  
  17. tableView.setModel(&hisModel); // 只需要设置model就行了,将数据渲染工作交给model  
  18. tableView.setAlternatingRowColors(true);  
  19. tableView.setWindowTitle("历史曲线");  
  20. tableView.show();  

   将数据渲染逻辑交给model, view层只需调用setModel()即可显示数据,

 

三.  QListView+QAbstractTableModel实现

       对于上述代码,当数据修改后,不能即时在view上显现出来,代码比较固化. 下面通过实现QAbstractTableModel来实现:

project List   

 

main.cpp

Cpp代码   收藏代码
  1. int main(int argc, char *argv[])  
  2. {  
  3.     QApplication app(argc, argv);  
  4.     QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GBK"));  
  5.     QTextCodec::setCodecForTr(QTextCodec::codecForName("GBK"));  
  6.   
  7.     QList<double> datas;  
  8.     datas<<89.2<<98.3<<45.8<<65.9;  
  9.   
  10.     HistoryModel hisModel;  
  11.     hisModel.setHisDatas(datas); // 当数据改变后,只需要重新调用setHisDatas()就可以更改视图  
  12.   
  13.     QTableView tableView;  
  14.     tableView.setModel(&hisModel);  
  15.     tableView.setAlternatingRowColors(true);  
  16.     tableView.setWindowTitle("历史曲线");  
  17.     tableView.show();  
  18.       
  19.     return app.exec();  
  20. }     

historymodel.h

Cpp代码   收藏代码
  1. /** 
  2.  * 派生QAbstractTableModel 
  3.  */   
  4. class HistoryModel:public QAbstractTableModel  
  5. {  
  6.     Q_OBJECT  
  7.   
  8. public:  
  9.     HistoryModel(QObject *parent=0);  
  10.     ~HistoryModel();  
  11.   
  12.     // 重载,返回行数目  
  13.     int rowCount(const QModelIndex &parent) const;  
  14.     // 重载,返回列数目  
  15.     int columnCount(const QModelIndex &parent) const;  
  16.     // 重载,设置每一单元格数据  
  17.     QVariant data(const QModelIndex &index, int role) const;  
  18.     // 重载,设置表头数据  
  19.     QVariant headerData(int section, Qt::Orientation orientation,int role) const;  
  20.     // 重载,设置单元格属性  
  21.     Qt::ItemFlags flags(const QModelIndex &index) const;  
  22.   
  23.     // 设置模型数据源  
  24.     void setHisDatas(const QList<double> hisdatas);  
  25.   
  26. private:  
  27.     QStringList horizontalList;  
  28.     QStringList verticalList;  
  29.     QList<double> hisdatas;  
  30. };  

 

historymodel.cpp

Cpp代码   收藏代码
  1. #include "historymodel.h"  
  2.   
  3. HistoryModel::HistoryModel(QObject *parent):QAbstractTableModel(parent)  
  4. {  
  5.     horizontalList<<"0分钟"<<"5分钟";  
  6.     verticalList<<"0小时"<<"1小时";  
  7. }  
  8.   
  9. HistoryModel::~HistoryModel()  
  10. {  
  11.   
  12. }  
  13.   
  14. void HistoryModel::setHisDatas(const QList<double> hisdatas)  
  15. {  
  16.     this->hisdatas=hisdatas;  
  17.   
  18.     // 调用reset()告诉任何一个使用这个模型的视图,它们所有的数据都无效了,这样就会强制它们为可见的项刷新数据  
  19.     reset();  
  20. }  
  21.   
  22. int HistoryModel::rowCount(const QModelIndex &parent) const  
  23. {  
  24.     return verticalList.size();  
  25. }  
  26.   
  27.   
  28. int HistoryModel::columnCount(const QModelIndex &parent) const  
  29. {  
  30.     return horizontalList.size();  
  31. }  
  32.   
  33. QVariant HistoryModel::headerData(int section, Qt::Orientation orientation, int role) const  
  34. {  
  35.     if(role==Qt::DisplayRole)  
  36.     {  
  37.         if(orientation==Qt::Horizontal) // 水平表头  
  38.         {  
  39.             return horizontalList[section];  
  40.         }  
  41.   
  42.         return verticalList[section]; // 垂直表头  
  43.     }  
  44.   
  45.     return QVariant();  
  46. }  
  47.   
  48. Qt::ItemFlags HistoryModel::flags(const QModelIndex &index) const  
  49. {  
  50.     Qt::ItemFlags flag=QAbstractItemModel::flags(index);  
  51.       
  52.     // flag|=Qt::ItemIsEditable // 设置单元格可编辑,此处注释,单元格无法被编辑  
  53.     return flag;  
  54. }  
  55.   
  56. QVariant HistoryModel::data(const QModelIndex &index, int role) const  
  57. {  
  58.     if(!index.isValid())  
  59.         return QVariant();  
  60.   
  61.     if(role==Qt::TextAlignmentRole)  
  62.     {  
  63.         return int(Qt::AlignHCenter|Qt::AlignVCenter); // 设置单元格对齐方式  
  64.     }else if(role==Qt::DisplayRole)  
  65.     {  
  66.         int offset=index.row()*horizontalList.size()+index.column(); // 设置单元格数据  
  67.         return hisdatas[offset];  
  68.     }  
  69.   
  70.     return QVariant();  
  71. }  

   通过子类化QAbstractTableModel,重新实现模型内虚方法,设置项的显示方式,项数据. 

 

 疑问: 如何设置第一个表头数据,见下面效果:

 Set Table Header

 

    ©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页