元のリンク: QRowTable テーブル コントロール (4) - 効率の最適化 - データ ソースの最適化
1. 幸せな瞬間
あるプログラマーがガールフレンドの家に初めて行ったとき、彼女の母親は真顔でこう尋ねました。「私の娘と結婚したいのですが、貯金はいくらありますか?」
プログラマーは頭を下げました:500!
彼女の母親はそれをさらに軽蔑しました。たったの500元で、トイレを買うのに十分ではありませんでした。
プログラマーは慌てて「これは人民元ではありません!」と言いました。
母親:米ドルでもトイレ買うには足りないよ!
プログラマー: それは実際にはビットコインです!
彼女の母親:わあ、義理の息子、大きなロブスターを買ってあげるよ
2. 問題分析
私はテーブル コントロールの機能についてすでに 3 つの記事を書きました。つまり、QRowTable テーブル コントロール - 行全体のホバー、行全体のチェック、指定した列の並べ替えなどをサポートしています。QRowTableテーブル コントロール (2) - 赤が上、緑が下です。QRowTable テーブル コントロール (3) - 効率の最適化 - QStandardItem の合理的な使用、これら 3 つの記事は主にコア機能の一般的な実装に関するものですが、データ量が大きい場合、パフォーマンスの問題が発生します。
問題があるのですから、当然解決しなければなりません。この記事では、大量のデータを扱う方法について説明します。
まず、上記の実装方法がなぜ時間がかかるのかを分析しましょう。まず、コードの量はそれほど多くありません。コード内のいくつかのブレークポイントにランダムにヒットすると、次のコードで費やされる時間がわかります。 QStandardItem 構造体のループ構造 これは比較的長く、for ループが数万回ループする場合に特に顕著です。
問題を見つけた後は、QStandardItem を構築するプロセスをより少ない呼び出しで呼び出す方法を見つけたいだけですが、もちろん、Qt はデータ ソース (モデル) を書き換えるという優れた解決策も提供します。
3. データソースを書き換える
Qt には、よく使用する QStandardItemModel、QTableView、QStyledItemDelegate などの古典的な MVC パターンが含まれており、効率的なテーブル コントロールを実装したい場合、これら 3 つのクラスを書き換えるだけで、基本的に必要な機能を完成させることができます。
もちろん、Qt はデータ キャッシュ レイヤー QSortFilterProxyModel のレイヤーも提供します。このクラスは、並べ替え機能やあいまい検索機能をより適切に実装するのに役立ちます。
この記事ではデータソースの書き換えについてのみ説明し、他の 2 つのクラスの書き換えについては前の記事で説明する必要があるため、ここではあまり説明しません。
データ ソースの書き換えメソッドを見てみましょう。ここでは、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 にデータを設定する際、最もパフォーマンスが低下するのはデータのコピーの処理ですが、これが問題にならないかどうかをよく検討してください。
上記のコードの TradeOrderInfoList インターフェイスは、テーブル データを格納するのに便利な独自に定義したコンテナ インターフェイスであり、ビューが描画されるときにここからデータが取得されます。
2. データインターフェースを書き換える
データの準備が完了しました。次のステップは、データをエレガントに取得して描画する方法です。ここでは、データの取得方法と描画方法に焦点を当てます。これは QStyledItemDelegate クラスの問題です。興味のある方は、自分で研究することができます。
モデルのモデレーターのドキュメントを注意深く見ると、データ インターフェイス関数があり、そのステートメントは次のようになっていることがわかります。
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
私たちのタスクは、このインターフェイスを書き換えて、指定されたインデックスの指定されたタイプのデータを返すことです。
- インデックス: 行番号と列番号を含むテーブルセルのインデックス
- 役割: テーブル データ型。各セルには一連のキーと値のペアが含まれており、前景色、背景色、フォント、位置、ハイライト色、背景ブラシなどのさまざまなデータをセルに保存するのに便利です。
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 インターフェイスを使用して更新することを忘れないでください。
データ ソースが書き換えられた後、パフォーマンスが良好かどうかを確認してみましょう。
4. 比較
この記事は、ほとんどの製品要件を満たすことができるテーブル関数を実現するための最後の記事となります。
将来的には、よりフレンドリーなインタラクションの最適化が行われる可能性がありますので、ご期待ください。
以下は、従来の表形式データ ソースと書き換えられた表形式データ ソースの長所と短所を比較した表です。
項目を比較する | 伝統的な方法 | モデルを書き換える |
---|---|---|
難易度 | 単純 | 複雑な |
コードの中で | 少し | 多くの |
パフォーマンス | 違い | 良い |
おすすめ | 2 つ星 | 五つ星 |
5. 関連記事
-
Qt はテーブル コントロールを実装しています - マルチレベルの列ヘッダー、マルチレベルの行ヘッダー、セルの結合、フォント設定などをサポートします。
-
Qt の高度な模倣 Excel テーブル コンポーネント - 列の固定、行の固定、コンテンツの適応、セルの結合をサポート
-
プロパティ ブラウザ コントロール QtTreePropertyBrowser はダイナミック ライブラリ (デザイナー プラグイン) にコンパイルされます。
-
QRowTable テーブル コントロール - 行全体のホバー、行全体のチェック、指定した列の並べ替えなどをサポートします。
一見の価値のある優れた記事:
重要です – 再版声明
-
当サイトの記事は特別な指示はなく、すべてオリジナルであり著作権で保護されています。転載する場合はリンクを使用し、原文の出典を明記してください。同時に原作者を書きます:朝十夜八またはTwowords
-
転載する場合は原文のまま転載してください 転載する際に本記事を改変する場合は事前にご連絡ください 転載の際、転載者に利益をもたらすような改変を行うことを禁止します