QRowTable表格控制項(四)-效率優化之-優化數據源

来源:https://www.cnblogs.com/swarmbees/archive/2019/09/11/11490909.html
-Advertisement-
Play Games

[TOC] 原文鏈接: "QRowTable表格控制項(四) 效率優化之 優化數據源" 一、開心一刻 一程式員第一次上女朋友家她媽板著臉問 :你想娶我女兒,有多少存款? 程式員低了下頭:五百! 她媽更鄙視了:才五百塊,買個廁所都不夠! 程式員忙說:不是人民幣! 她媽:就算是美元,還是不夠買廁所! 程式 ...


目錄

原文鏈接:QRowTable表格控制項(四)-效率優化之-優化數據源

一、開心一刻

一程式員第一次上女朋友家她媽板著臉問 :你想娶我女兒,有多少存款?

程式員低了下頭:五百!

她媽更鄙視了:才五百塊,買個廁所都不夠!

程式員忙說:不是人民幣!

她媽:就算是美元,還是不夠買廁所!

程式員:其實是比特幣!

她媽:哇,賢婿,我給你買只大龍蝦去

二、問題分析

前邊已經寫了3篇關於表格控制項的功能,分別是QRowTable表格控制項-支持hover整行、checked整行、指定列排序等QRowTable表格控制項(二)-紅漲綠跌QRowTable表格控制項(三)-效率優化之-合理使用QStandardItem,這三篇文章主要是圍繞實現核心功能來講述的一般實現方式,當數據量多大時就會出現性能問題。

既然出現問題,當然是需要解決的。本篇文章就來講述怎麼處理大量數據的情況。

首先我們先來分析下上述幾種實現方式為什麼會比較消耗時間,首先代碼量也不大,在代碼里隨機打幾個斷點,我們就會發現,代碼在迴圈構造QStandardItem這個結構中耗費的時間比較久,並且當for迴圈出現上萬次迴圈時尤為明顯。

找到問題後,就是想辦法怎麼可以更少的調用構造QStandardItem這個流程,當然了Qt也給我們提供了很好的解決方案,那就是重寫數據源(Model)。

三、重寫數據源

Qt中包含有經典的MVC模式,比如我們經常使用的QStandardItemModel、QTableView和QStyledItemDelegate,當我們要實現一個高效的表格控制項時,重寫這3個類基本就可以完成我們所需要的功能。

當然了Qt還提供了了一層數據緩存層QSortFilterProxyModel,這個類可以幫助我們更好的實現排序、模糊搜索功能

本篇文章這裡只講解重寫數據源,關於其他兩個類的重寫前面文章中應該有所講述,這裡不再過多解釋。

下麵一起來看下數據源的重寫方式,我們這裡選擇繼承自QStandardItemModel這個類來實現我們的數據源,這裡是一個偷懶的方式,正常情況下是需要重寫QAbstractItemModel類,如果重寫QAbstractItemModel類的話,那麼就需要重寫更多的介面。

class QRowModel : public QStandardItemModel
{
    Q_OBJECT

public:
    explicit QRowModel(QObject * parent = 0);
    ~QRowModel();
public:
    //設置數據源
    void SetSourceData(const TradeOrderInfoList & data);
    ...

protected:
    virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
    virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
    virtual void sort(int column, Qt::SortOrder order /* = Qt::AscendingOrder */) override;

private:
    ...
    TradeOrderInfoList itemList;
    QColor m_CheckedColor = QColor("#4F4F4F");
    mutable std::map <int, int> m_AlignmentList;//列對其方式

    friend class QRowTable;
};

上次代碼是重寫Model類的頭文件,其中有一些不相干的代碼我選擇了隱藏,重寫Model最重要的就是需要我們自己去存儲數據,並且在Qt的調用機制調用獲取數據時給他返回即可。

關鍵點

  1. 重寫Model,自己存儲數據
  2. 重寫data介面,返回數據

1、自己存儲數據

自己存儲數據有一個好處,那就是我們在給Model設置數據時,最大的性能損耗就是數據拷貝的過程,仔細想想這個是不是都不是問題。

上述代碼中的TradeOrderInfoList這個介面提就是我們自己定義的一個容器介面,方便存儲我們的表格數據,當視圖繪製時,會從這裡拿數據。

2、重寫data介面

數據已經準備完畢,接下里就是View如何優雅的拿到數據並繪製了,這裡我們重點講述怎麼拿數據,如何繪製是QStyledItemDelegate這個類的事,感興趣的可以自己研究研究。

仔細查看Model的版主文檔們就會發現有一個data介面函數,他的聲明可能像下麵這樣

QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;

們的任務就是重寫這個介面,返回指定索引上的指定類型數據

  1. index:表格cell的索引,包含有行和列序號
  2. role:表格數據類型,每一個cell上都包含有一系列鍵值對,方便存儲單元格上的各種數據,比如說前景色、背景色、字體、位置、高亮色、背景畫刷等等。
QVariant QRowModel::data(const QModelIndex &index, int role) const
{
    if (Qt::DecorationRole == role)
    {
        int r = index.row();
        int c = index.column();
        if (r >= itemList.size())
        {
            return "";
        }
        const TradeOrderInfo & info = itemList.at(r);
        switch (c)
        {
        case 0:
            return QPixmap(stock_helper::getCurrencyIcon(info.market, info.symbol).c_str());
        default:
            "";
            break;
        }
    }
    else if (Qt::ForegroundRole == role)
    {
        int r = index.row();
        int c = index.column();
        if (r >= itemList.size())
        {
            return "";
        }
        const TradeOrderInfo & info = itemList.at(r);
        switch (c)
        {
        case 4://"方向"
            if (info.action.compare("SELL") == 0)
            {
                return QColor("#218DF2");
            }
            else
            {
                return QColor("#FF4A4A");
            }
        default:
            return QColor("#dddddd");
        }
    }
    else if (Qt::DisplayRole == role)
    {
        //自己從model中拿數據給view
        //"名稱"
        int r = index.row();
        int c = index.column();
        if (r >= itemList.size())
        {
            return "";
        }
        const TradeOrderInfo & info = itemList.at(r);
        switch (c)
        {
        case 0://"名稱" 
            return stock_helper::OrderDisplayName(&info);
        case 1://"代碼" 
            return stock_helper::OrderDisplaySymbol(&info, m_strAccount);
        case 2://"成交量" 數字居右
            return QString::number(info.totalQuantity);
        case 3://"成交均價" 數字居右
            return stock_helper::PriceDisplayName(info.symbol, info.market, info.secType, info.avgFillPrice);
        case 4://"方向"
            if (info.action.compare("SELL") == 0)
            {
                return QUI_LOAD_STRING(TTS_ORDER_DIR_SELL);
            }
            else
            {
                return QUI_LOAD_STRING(TTS_ORDER_DIR_BUY);
            }
        default:
            "";
            break;
        }
    }

    return QStandardItemModel::data(index, role);
}

別忘啦,當數據源發生變化的時候使用SetSourceData介面更新下。

數據源重寫好以後,再試試我們的性能是不是杠杠滴。

四、比較

本篇文章應該是實現表格功能的最後一篇文章了,可以滿足大多數的產品需求。

後續可能還會陸續出一些更友好的交互優化,敬請期待。

下麵是一個表格,包含了傳統的表格數據源和重寫後的表格數據源優劣比較。

比較項目 | 傳統方式 | 重寫Model --- | --- | --- 難易程度 | 簡單 | 複雜 代碼里 | 少 | 多 性能 | 差 | 好 推薦度 | 兩顆星 | 五顆星

五、相關文章

  1. Qt實現表格控制項-支持多級列表頭、多級行表頭、單元格合併、字體設置等

  2. Qt高仿Excel表格組件-支持凍結列、凍結行、內容自適應和合併單元格

  3. 屬性瀏覽器控制項QtTreePropertyBrowser編譯成動態庫(設計師插件)

  4. 超級實用的屬性瀏覽器控制項--QtTreePropertyBrowser

  5. Qt之表格控制項螞蟻線

  6. QRowTable表格控制項-支持hover整行、checked整行、指定列排序等

  7. QRowTable表格控制項(二)-紅漲綠跌

  8. QRowTable表格控制項(三)-效率優化之-合理使用QStandardItem


值得一看的優秀文章:

  1. 財聯社-產品展示
  2. 廣聯達-產品展示
  3. Qt定製控制項列表
  4. 牛逼哄哄的Qt庫





如果您覺得文章不錯,不妨給個打賞,寫作不易,感謝各位的支持。您的支持是我最大的動力,謝謝!!!














很重要--轉載聲明

  1. 本站文章無特別說明,皆為原創,版權所有,轉載時請用鏈接的方式,給出原文出處。同時寫上原作者:朝十晚八 or Twowords

  2. 如要轉載,請原文轉載,如在轉載時修改本文,請事先告知,謝絕在轉載時通過修改本文達到有利於轉載者的目的。



您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 原文再續,書接上一回 上回講到了,python IDLE的草稿本和作業本,並順便試了試python的輸入輸出,變數,運算的體驗,大家應該能感受到python的簡單了吧。 下麵我們繼續體驗python的強大,python之所以強大,是因為python有庫。(就如同人一樣學會了穿褲子也變得強大了) 課程 ...
  • 房天下 登錄 本次爬取的網址為: 一、分析請求 輸入用戶名和密碼,點擊登錄按鈕 請求的參數為: 就是輸入的用戶名, 是將密碼加密後的數據。我們只要找出密碼的加密方式就可以模擬登錄了。 二、密碼加密方式破解 這次我們以 作為關鍵字,進行搜索 找到加密位置之後,我們打上斷點,重新點擊登錄 找到密碼加密的 ...
  • 內容來自轉載整理 1.NumPy數值計算 NumPy是使用Python進行科學計算的基礎包,Numpy可以提供數組支持以及相應的高效處理函數,是Python數據分析的基礎,也是SciPy、Pandas等數據處理和科學計算庫最基本的函數功能庫,且其數據類型對Python數據分析十分有用。它包含: 一個 ...
  • 面試題 如何設計一個高併發系統? 面試官心理分析 說實話,如果面試官問你這個題目,那麼你必須要使出全身吃奶勁了。為啥?因為你沒看到現在很多公司招聘的 JD 里都是說啥,有高併發就經驗者優先。 如果你確實有真才實學,在互聯網公司里乾過高併發系統,那你確實拿 offer 基本如探囊取物,沒啥問題。面試官 ...
  • 前言 先列出java併發涉及的知識點,後面再慢慢補. java併發 1 常見概念 進程:程式執行的實體,操作系統資源調度資源分配的基本單元 線程:程式執行的最小單元,擁有獨立的堆棧和局部變數等屬性,可以共用進程的資源 同步是串列執行,阻塞 非同步是並行執行,非阻塞 併發:多個任務交替執行 並行:多個任 ...
  • 學習Python的第一天,也是我第一次寫博客的一天,不怎麼會寫博客,也不怎麼會Python,也不怎麼會寫總結.在學Python的第一天發現自己腦子不是很好用,在學習過程中出現很多錯誤,錯誤錦集如下,哈哈哈哈,要加油.以後要註意不要再犯下麵的錯誤了,不然以後在工作中很難獨立完成,也容易出現很多錯誤,這 ...
  • 之前多篇文章從mysql的底層結構分析、sql語句的分析器以及sql從優化底層分析, 還有工作中常用的sql優化小知識點。面試各大互聯網公司必問的mysql鎖和事務隔離級別,這篇文章給你打神助攻,一飛衝天。 鎖定義 鎖是電腦協調多個進程或線程併發訪問某一資源的機制。 在資料庫中,除了傳統的計算資源 ...
  • 一、instanceof運算符 instanceof是Java語言中的一個二元運算符,它的作用是判斷一個引用類型的變數所指向的對象是否是一個類(或介面、抽象類、父類)的實例,即它左邊的對象是否是它右邊的類的實例該運算符返回boolean類型的數據。 常見的用法為:result=object inst ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...