ここでの問題は、実際にはコンプリータにポップアップが含まれていることです。これは実際には別のQAbstractItemView
ウィジェットです ( QCompleter::popup()のドキュメントを参照してください)。そのため、QCompleter で「Enter」を押すと、キー イベントは実際には行編集ではなくポップアップに移動します。
問題を解決するには、次の 2 つの方法があります。
オプション1
コンプリーターのアクティブ化された信号を行編集のクリア スロットに接続しますが、次のように実行しますQueuedConnection
。
QObject::connect(completer, SIGNAL(activated(const QString&)),
lineEdit, SLOT(clear()),
Qt::QueuedConnection);
直接接続の使用が機能しない理由は、スロットがシグナルから呼び出される順序に本質的に依存しているためです。a を使用するQueuedConnection
と、これを回避できます。コードのメンテナンスの観点から、私はこのソリューションをあまり好みません。なぜなら、コードを見るだけでは意図が明確ではないからです。
オプション 2
ポップアップの周りにイベント フィルターを記述して、'Enter' キーを除外し、行の編集を明示的にクリアします。イベント フィルターは次のようになります。
class EventFilter : public QObject
{
Q_OBJECT
public:
EventFilter(QLineEdit* lineEdit, QObject* parent = NULL)
:QObject(parent)
,mLineEdit(lineEdit)
{ }
virtual ~EventFilter()
{ }
bool eventFilter(QObject* watched, QEvent* event)
{
QAbstractItemView* view = qobject_cast<QAbstractItemView*>(watched);
if (event->type() == QEvent::KeyPress)
{
QKeyEvent* keyEvent = dynamic_cast<QKeyEvent*>(event);
if (keyEvent->key() == Qt::Key_Return ||
keyEvent->key() == Qt::Key_Enter)
{
mLineEdit->clear();
view->hide();
return true;
}
}
return false;
}
private:
QLineEdit* mLineEdit;
};
次に、コンプリーターのポップアップにイベント フィルターをインストールします。
EventFilter* filter = new EventFilter(lineEdit);
completer->popup()->installEventFilter(filter);
このオプションはより手間がかかりますが、何をしているのかがより明確になります。さらに、必要に応じて、この方法で追加のカスタマイズを実行できます。