首页 文章

从QCompleter中选择项目后无法清除QLineEdit

提问于
浏览
1

当你选择一个项目时使用PopupCompletion模式(使用箭头键)并按回车键 - lineEdit应该变为空(我按下返回时清除lineEdit),但lineEdit不会变为空 . (如果再次按'Enter',它将清空lineEdit) . 所以我认为按下return会清除lineEdit,但是按下return也会告诉QCompleter将所选项插入到lineEdit中,所以似乎没有任何反应 .

但是,如果你单击用箭头选择它的项目 - 一切正常 .

我试图在互联网上找到解决方案,但我发现只有一个人有同样的问题:http://lists.trolltech.com/qt-interest/2006-10/thread00985-0.html . 可悲的是没有答案 . 请阅读他的问题,因为它有助于理解我的问题 .

在QCompleter插入所选项目后如何清理LineEdit? (捕捉激活的信号没有帮助)

1 回答

  • 10

    这里的问题是,完成者实际上包含一个弹出窗口,它实际上是一个单独的 QAbstractItemView 小部件(参见QCompleter::popup()文档) . 因此,当您在QCompleter上按'Enter'时,键事件实际上会转到弹出窗口,而不是行编辑 .

    有两种不同的方法可以解决您的问题:

    选项1

    连接完成者's activated signal to the line edit'的清除插槽,但是将其作为 QueuedConnection

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

    使用直接连接不起作用的原因是因为您基本上依赖于从信号调用槽的顺序 . 使用 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);
    

    这个选项更有用,但是你做的更清楚 . 此外,如果您愿意,可以通过这种方式执行其他自定义 .

相关问题