最近「NavyJS & NavyCreator」というモバイルWebフレームワークとそれ専用の開発環境(簡易IDE)を作ってます。 そのNavyCreatorはC++/Qtを使って実装していて、Qt便利ですごくありがたいなーと思ってます。
QCompleter
NavyCreatorでコンボボックス(ファイル名とかクラス名とかのリスト)にインクルメンタルサーチを実装したいなーと思って、Qtのリファレンスを見てたらQCompleterっていうすごく便利なのを見つけて喜んでました。けどQCompleterが対応してるのは前方一致のみ。オプションで変更できるだろうと思ったんですがそれも無さげ。という訳でQtのコードとか読みながら部分一致を行えるようにQCompleterを拡張できたのでメモとして記事を書いています。
NCompleter
QCompleterを継承したNCompleterで部分一致補完を行います
#ifndef N_COMPLETER_H #define N_COMPLETER_H #include <QCompleter> #include <QComboBox> #include <QStringListModel> class NCompleter : public QCompleter { Q_OBJECT public: explicit NCompleter(const QStringList &list, QObject *parent = 0); void setStringList(const QStringList &list); private: QStringList mList; QStringListModel *mModel; signals: private slots: void update(const QString &word); }; #endif // N_COMPLETER_H
#include "n_completer.h" NCompleter::NCompleter(const QStringList &list, QObject *parent) : QCompleter(parent) { mList = list; mModel = new QStringListModel(); mModel->setStringList(list); setModel(mModel); setCompletionMode(QCompleter::UnfilteredPopupCompletion); setModelSorting(QCompleter::CaseInsensitivelySortedModel); setCaseSensitivity(Qt::CaseInsensitive); } void NCompleter::setStringList(const QStringList &list) { mList = list; mModel->setStringList(list); } void NCompleter::update(const QString &word) { if (mList.indexOf(word) == -1) { QStringList filtered = mList.filter(word, caseSensitivity()); if (filtered.length() != 0) { mModel->setStringList(filtered); } } }
QLineEdit *e = new QLineEdit(this); NCompleter *c = new NCompleter(e); QStringList list; list << "book" << "this is book" << "cook"; c->setStringList(list); e->setCompleter(c); connect(e, SIGNAL(textChanged(QString)), c, SLOT(update(QString));
QtCreator上で日本語入力が安定しないのでコメントかけなくて辛い><