Fail to clear QLineEdit after selecting item from QCompleter

瘦欲@ 提交于 2019-12-04 20:11:35

The issue here is that the completer actually contains a pop-up, which is actually a separate QAbstractItemView widget (refer to the QCompleter::popup() documentation). As such, when you press 'Enter' on the QCompleter, the key event actually goes to the pop-up and not the line edit.

There are two different ways to resolve your issue:

Option 1

Connect the completer's activated signal to the line edit's clear slot, but do it as a QueuedConnection:

QObject::connect(completer, SIGNAL(activated(const QString&)),
                 lineEdit, SLOT(clear()),
                 Qt::QueuedConnection);

The reason why using a direct connection doesn't work is because your are essentially dependent on the order in which slots get called from a signal. Using a QueuedConnection gets around this. From a code maintenance standpoint, I don't really prefer this solution because it isn't clear what your intention is just by looking at the code.

Option 2

Write an event filter around the pop-up to filter out the 'Enter' key to clear the line edit explicitly. Your event filter would end up looking something like this:

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;
};

You would then install the event filter on the completer's pop-up:

EventFilter* filter = new EventFilter(lineEdit);
completer->popup()->installEventFilter(filter);

This option is more work, but it's clearer as to what you are doing. Moreover, you can perform additional customization this way, if you prefer.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!