2012-04-17 30 views
4

CODE:QTableWidgetが移入され初めて、すべてが正常ですが、私はそれを再作成するとき、それはかなり遅いです

populateTable() 
{ 
    tableWidget->clearContents(); 
    tableWidget->setRowCount(stringList.size()); 

    for(int i = 0; i < stringList.size(); ++i) 
    { 
    tableWidget->setItem(i, 0, new QTableWidgetItem(stringList.at(i))); 
    } 
} 

問題:

初めてpopulateTable( )が実行されても、すべて正常です。しかし、次の結果として、以前より大幅に遅くなります。

議論:

は慎重にテストの後、私は問題である)(clearContentsを疑います。単純に

tableWidget->clearContents(); 

からコードを変更するため、次

tableWidget->setRowCount(0); 

修正問題が、今では別の問題になります。行数を '0'に設定すると、割り当てられたヒープQTableWidgetItemsが削除されないように見えますが、アイテムの所有権が残っているように見えるので、メモリリークが発生します。 (または少なくとも私はそう考えています...)

QTableWidgetのQtのドキュメントはかなり漠然としているので、clearContents()が実際に何をしているのか正確には分かりません。ドキュメントでは、「ビューからヘッダーにないすべてのアイテムを削除します」というメッセージが表示されるので、テーブルの内容は隠すだけですか?それは削除されますか?私は確信していません。私の理論では、clearContents()はアイテムのみを隠すだけで、テーブルを作成しようとすると、実際には各アイテムが削除されて削除され、テーブルに設定する新しいアイテムが割り当てられます。

QtableWidgetに関するQtのドキュメントによれば、QTableWidgetを実装する適切な方法は、ヒープにQTableWidgetItemを割り当て、setItem()を使ってテーブルセルに設定することです。私は要約すると

...奇妙なことを見つける:

移入し、これらの問題のすべてを持つことなく、Qtのテーブルを再移植するための別の方法はありますか?もしそうでなければ、これらの問題を解決する方法はありますか?

答えて

5

「QTableWidget上のQtのドキュメントはQTableWidgetを移入するための適切な方法は、私が見つけた、私は上記のコードで提示と同じように)その後、ヒープ上QTableWidgetItemを割り当てるSetItem関数(とテーブルセルの上にそれを設定することであることを示唆しています奇妙な... "

documentation for QTableWidget::setItemは、ウィジェットがアイテムの所有権を持っていると明示的に言っていると考えています。

"行カウントを '0'に設定すると、QTableWidgetItemsが割り当てられたヒープが削除されないように見えるので、アイテムの所有権が残っているように見えるので、メモリリークが発生します(少なくとも、 ..) "

QTableWidgetItemの独自のサブクラスを作成し、そのデストラクタにコードを入れて、ブレークポイントを設定して確実に知ることができるようにすることができます。あるいは、Qtソースは読みやすいです。

http://qt.gitorious.org/qt/qt/blobs/4.8/src/gui/itemviews/qtablewidget.cpp#line370

http://qt.gitorious.org/qt/qt/blobs/4.8/src/gui/itemviews/qtablewidget.cpp#line100

しかし、これは再び行に、このモデルの行数を設定します

documentation for QTableWidget::setRowCount

と一致している: setRowCountは確かQTableWidgetItemsを削除しない removeRowsを呼び出します。これがrowCount()より小さい場合、不要な行のデータは破棄されます。

clearContents()とsetRowCount(0)の違いはほとんどありません。あなたは、この現象を実証する、どんな大きなプログラムにも巻き込まれていない小さな再現可能な例を作りましたか?

+1

はい、私は必要なだけで何も使用していないスタンドアロンを作成しました。 QTableWidgetを4列と100行で完全に埋めるテストプログラムを作成しました。 QElapsedTimerを使用して、処理を完了するのにかかる時間を測定しました。 まず、clearContents()を使用して、再投入しようとするとかなり遅くなることがわかりました。次に、私はsetRowCount(0)を使用して、テーブルを再投入するのにかかる時間も、約15msの差異を設定するのにかかる時間に等しいことを発見しました。 あなたが提供したリンクが参考になる場合は、clearContents()の定義につなげることができますか? –

+0

ああ、clearContents()の定義については気にせず、見つけました。 –

2

私は、QTableWidgetの再作成だけでなく、変更を加えることで一般的な速度が遅いことに気付きました。

たとえば、setCheckState()を使用して、約1000個のセルにチェックボックスを表示するセルがあります。初めてチェック/チェックを外すことによって、彼らは高速です。 2回目には15秒かかりますが、これはまったく受け入れられません。私はblockSignals(true/false)を試したが、何も働かなかった。

の信号をブロックするのは、テーブルではなく、テーブルをブロックすることです。モデルはCPUを食べるものです。

auto table = ui.tableWidget; 
auto rows = table->rowCount(); 
auto cols = table->columnCount(); 

table->model()->blockSignals(true); 

for (auto row = 0; row < rows; row++) 
    for (auto col = 0; col < cols; col++) 
     if (auto cb = table->item(row, col)) 
      cb->setCheckState(Qt::CheckState::Checked); 

table->model()->blockSignals(false); 
table->model()->layoutChanged();//Required, or else you won't see your changes immediately. 
関連する問題

 関連する問題