Qt5中表格處理大數據量

在Qt中若是是普通項目,GUI處理展示的數據量不大,通常用QTableWidget,QTreeWidget這樣的控件就知足了,可是若是數據量行數達到了幾萬行,那麼Widget的展現性能就誤差了。編程

Qt中提供了一種Model/View的編程方式來處理數據,也就是展現層和數據層分離,這樣就解耦了。一旦Model的狀態改變,它會自動渲染到View控件。這樣的機制使得GUI能夠展示大量的數據也不會卡頓。ide

爲了處理數據的靈活性,咱們用QStandardItemModel來作QTableView的Model層實現。由於以Table的形式展示,因此如下代碼實現了,點擊表頭按列排序,點擊行顯式行的上下文菜單的功能。由於QTableView的默認函數

排序是按字符序列排序,因此得對QStandardItem進行子類化,並重載operator< 函數才能達到某些列用數值大小來排序。性能

 

由於是簡單的Demo例子,QTableView是採用拖拽空間的方式拖到一個Widget裏面的,該Wdiget類爲ModelViewTable:ui

複製代碼

1 // ModelViewTable.h
  2 #pragma once
  3 
  4 #include <QtWidgets/QWidget>
  5 #include "ui_ModelViewTable.h"
  6 
  7 class QStandardItemModel;
  8 class QMenu;
  9 
 10 class ModelViewTable : public QWidget
 11 {
 12     Q_OBJECT
 13 
 14 public:
 15     ModelViewTable(QWidget *parent = Q_NULLPTR);
 16     void generateDataSet();
 17     void addRowRecord(int row);
 18 
 19     void setColumnItem(int row, int column, QString ip);
 20 
 21 public slots:
 22     void slotShowContextMenu(const QPoint& point);
 23 private:
 24     Ui::ModelViewTableClass ui;
 25     QStandardItemModel * m_model;
 26     QMenu* m_contextMenu;
 27 };
 28 
 29 // ModelViewTable.cpp
 30 #include "ModelViewTable.h"
 31 
 32 #include <QStandardItemModel>
 33 #include <QStandardItem>
 34 #include <QString>
 35 #include <QMenu>
 36 #include <QAction>
 37 
 38 #include "CustomStandardItem.h"
 39 
 40 ModelViewTable::ModelViewTable(QWidget *parent)
 41     : QWidget(parent)
 42 {
 43     ui.setupUi(this);
 44 
 45     //////////////////////////設置表頭/////////////////////
 46     m_model = new QStandardItemModel(this);
 47     m_model->setColumnCount(3);
 48     m_model->setHeaderData(0, Qt::Horizontal, QStringLiteral("終端IP"));
 49     m_model->setHeaderData(1, Qt::Horizontal, QStringLiteral("CPU使用率"));
 50     m_model->setHeaderData(2, Qt::Horizontal, QStringLiteral("內存使用率"));
 51     
 52     ui.tableView->resizeColumnsToContents(); // 自適應列寬
 53     ui.tableView->setSortingEnabled(true); // 能夠按列來排序
 54     ui.tableView->setModel(m_model);
 55     ui.tableView->horizontalHeader()->setDefaultAlignment(Qt::AlignHCenter);
 56     ui.tableView->horizontalHeader()->setFont(QFont("Times",10,QFont::Bold));
 57    
 58     ui.tableView->setSelectionBehavior(QAbstractItemView::SelectRows); //整行選中
 59     ui.tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);// 表格單元格爲只讀
 60     ui.tableView->setContextMenuPolicy(Qt::CustomContextMenu); // 能夠自定義右鍵菜單
 61 
 62     m_contextMenu = new QMenu(this);
 63     QAction *processAct = new QAction(QStringLiteral("進程列表信息"),m_contextMenu);
 64     QAction *windowAppsAct = new QAction(QStringLiteral("窗口應用列表信息"),m_contextMenu);
 65     m_contextMenu->addAction(processAct);
 66     m_contextMenu->addAction(windowAppsAct);
 67 
 68     connect(ui.tableView, SIGNAL(customContextMenuRequested(const QPoint&)),
 69         this, SLOT(slotShowContextMenu(const QPoint&)));
 70    
 71 
 72 }
 73 
 74 void ModelViewTable::generateDataSet()
 75 {
 76     for (int i = 0; i < 3000; ++i)
 77     {
 78         addRowRecord(i);
 79     }
 80 }
 81 
 82 void ModelViewTable::addRowRecord(int row)
 83 {
 84     // 每行3列
 85     QString ip = QString("%1.%2.%3.%4").arg(192).arg(168).arg(1).arg(row);
 86     setColumnItem(row, 0, ip);
 87 
 88     QString cpu = QString("%1").arg((row * 10) % 100);
 89     setColumnItem(row, 1, cpu);
 90 
 91     QString mem = QString("%1").arg((row * 12)  % 100);
 92     setColumnItem(row, 2, mem);
 93     
 94 }
 95 
 96 void ModelViewTable::slotShowContextMenu(const QPoint& point)
 97 {
 98     QModelIndex index = ui.tableView->indexAt(point);
 99     if (index.isValid())
100     {
101         m_contextMenu->exec(QCursor::pos());
102     }
103 }
104 
105 void ModelViewTable::setColumnItem(int row, int column, QString ip)
106 {
107     m_model->setItem(row, column, new CustomStandardItem(ip));
108     m_model->item(row, column)->setTextAlignment(Qt::AlignCenter);
109 }

複製代碼

 

由於須要實現自定義的數值排序,因此要繼承QStandardItem,並覆蓋其中的相關函數:this

複製代碼

1 //   CustomStandardItem.h
 2 #pragma once
 3 
 4 #include <QStandardItem>
 5 #include <QString>
 6 
 7 //  自定義數值排序
 8 class CustomStandardItem : public QStandardItem
 9 {
10    // Q_OBJECT
11 
12 public:
13     CustomStandardItem();
14     CustomStandardItem(const CustomStandardItem& other);
15     CustomStandardItem(const QString &text);
16     CustomStandardItem & operator =(const CustomStandardItem& other);
17     ~CustomStandardItem();
18 
19 public:
20     virtual bool operator<(const QStandardItem& other) const override;
21 
22 };
23 
24 //CustomStandardItem.cpp
25 #include "CustomStandardItem.h"
26 
27 #include <QVariant>
28 
29 CustomStandardItem::CustomStandardItem()
30 {
31 }
32 
33 CustomStandardItem::CustomStandardItem(const CustomStandardItem& other)
34     :QStandardItem(other)
35 {
36 
37 }
38 
39 CustomStandardItem::CustomStandardItem(const QString &text)
40     :QStandardItem(text)
41 {
42 
43 }
44 
45 CustomStandardItem::~CustomStandardItem()
46 {
47 }
48 
49 CustomStandardItem & CustomStandardItem::operator=(const CustomStandardItem& other)
50 {
51     QStandardItem::operator=(other);
52     return *this;
53 }
54 
55 bool CustomStandardItem::operator<(const QStandardItem& other) const
56 {
57     const QVariant left = data(Qt::DisplayRole), right = other.data(Qt::DisplayRole);
58     //   第1到2列,所有采用浮點數的大小排序
59     if (column() == other.column() && other.column() >= 1 && other.column() <= 2)
60     {
61         return left.toDouble() < right.toDouble();
62     }
63 
64     return QStandardItem::operator<(other);
65 }

複製代碼

 

以上代碼就徹底實現了Model/View 的Table編程。排序

相關文章
相關標籤/搜索