ひとことで
大量のアイテムが候補になると、QListView
の表示が遅くなるので、QCompleter::setPopup(QAbstractItemView*)
で QTableView
をポップアップに利用する。
QCompleter を使った素直なサンプルでの性能問題
素直に、QCompleter で 20000 件程度の候補から選択させると、
キー入力で絞り込んだ数が多い時に、QListView の表示がもたついてしまう。
特に最初の1文字だと表示待ち時間が長い。
# include <QApplication>
# include <QLineEdit>
# include <QCompleter>
int main(int argc, char **argv) {
QApplication app(argc, argv);
QLineEdit *edit = new QLineEdit;
// サジェストに利用する候補文字列を生成
QList<QString> candidates;
for (int i = 0; i < 5000; ++i) {
candidates << QString("hoge%1").arg(i, 5, 10, QChar('0'))
<< QString("huga%1").arg(i, 5, 10, QChar('0'))
<< QString("foga%1").arg(i, 5, 10, QChar('0'))
<< QString("fuga%1").arg(i, 5, 10, QChar('0'));
}
// サジェストを提供する QCompleter を生成する
QCompleter *comp = new QCompleter(candidates, edit)
edit->setCompleter(comp);
edit->show();
app.exec();
}
対応策 QListView の代わりに、QTableView を使う
QCompleter::setPopup(QAbstractItemView*)
を使うと、候補のポップアップ表示に使うウィジットを設定できる。
setPopup()
で、QTableView
をポップアップに設定すると、表示が早くなる。
ただし、単に new QTableView
したままのビューでは、ヘッダが表示されてしまうので、行ヘッダや列ヘッダを非表示にして、行の高さを調整する。
QTableView *popup = new QTableView();
// 列ヘッダを非表示にする。
popup->horizontalHeader()->hide();
// 候補の右側に余計なスペースが表示されないようにストレッチモードを変更
popup->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); // Qt4 だと setResizeMode()
// 行ヘッダを非表示にする
popup->verticalHeader()->hide();
// 候補1行の高さを調整
popup->verticalHeader()->setDefaultSectionSize(20);
// 候補のポップアップに QTableView を使う
comp->setPopup(popup);
実行結果の比較
デフォルトのポップアップ
まず、デフォルトのポップアップ表示で表示した場合は、以下のようになる。
画像ではわからないが、この表示に数秒を要する。
ポップアップに QTableView (調整なし)を使用した結果
次に、QCompleter::setPopup()
でQTableView を指定した場合の表示は、以下のようになる。
図. QTableView(調整なし) ポップアップで表示した場合の候補表示
ポップアップに QTableView (調整ずみ)を使用した結果
最後に、QCompleter::setPopup()
で ヘッダのサイズなどを調整した QTableView を指定した場合の表示は、以下のようになる。
グリッドの線が表示されてしまっているが、さらに調整すれば消せるはず。