1

アイテムを選択して(矢印キーを使用して)PopupCompletionモードを使用してリターンを押すと、lineEditは空になるはずですが(リターンを押すとlineEditをクリアします)、lineEditは空になりません。(もう一度「Enter」を押すと、lineEdit が空になります)。returnを押すとlineEditがクリアされると思いますが、returnを押すとQCompleterに選択した項目をlineEditに挿入するように指示されるため、何も起こらないようです。

ただし、矢印で選択する代わりにアイテムをクリックすると、すべて正常に機能します。

インターネットで解決策を見つけようとしましたが、同じ問題を抱えている人が 1 人だけ見つかりました: http://lists.trolltech.com/qt-interest/2006-10/thread00985-0.html。残念ながら答えはありません。私の問題を理解するのに役立つので、彼の質問を読んでください。

QCompleter が選択した項目を挿入した後に LineEdit をきれいにするにはどうすればよいですか? (活性化された信号をキャッチしても役に立ちません)

4

1 に答える 1

11

ここでの問題は、実際にはコンプリータにポップアップが含まれていることです。これは実際には別の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);

このオプションはより手間がかかりますが、何をしているのかがより明確になります。さらに、必要に応じて、この方法で追加のカスタマイズを実行できます。

于 2012-08-10T16:48:55.090 に答える