Qt: как сделать так, чтобы излучался только один из QCompleter :: activ () или QLineEdit :: returnPressed ()? - PullRequest
3 голосов
/ 26 декабря 2010

У меня есть QLineEdit с QCompleter.Я хочу, чтобы слот myslot () вызывался, когда испускался любой из сигналов QCompleter :: activ (const QString) или QLineEdit :: returnPressed ().

Кроме того, я хочу, чтобы этот слот вызывался сразу после завершениясделано, если пользователь использовал QCompleter для ввода данных (т.е. я не хочу, чтобы пользователь нажимал Enter, если он уже нажал на QCompleter).

Это прекрасно работает, если пользователь не используетзавершитель, или использует мышь, чтобы нажать на завершитель.Однако, если он использует клавишу ввода во всплывающем окне QCompleter, оба сигнала испускаются, и myslot () вызывается дважды.

Как сделать так, чтобы он вызывался только один раз, независимо от ситуации

Ответы [ 3 ]

1 голос
/ 29 декабря 2010

Я рекомендую создать класс-оболочку для QCompleter, в котором вы переопределите eventFilter () . Класс-обертка может либо выдавать сигнал только для щелчка мыши, либо он может принимать событие возврата назад. Четкую документацию можно найти в руководстве по Qt. Электронная копия находится здесь: http://doc.qt.io/archives/4.6/qobject.html#eventFilter

Есть и другие пути, но этот довольно прямой.

0 голосов
/ 02 января 2011

Я решил это; это не особенно чисто, но это работает. Вот мой обработчик для обоих сигналов. Если сигнал поступает от QCompleter, для вызывающего абонента устанавливается значение COMPLETER, в противном случае для него устанавливается значение ENTER_PRESSED.

void myClass::handler(char caller)
{
  if ((caller == COMPLETER && lineedit->text().length() != 0) || (caller == ENTER_PRESSED))
  {
    // do stuff here
    lineedit->clear();
  }
}

Очистив телефон доверия после того, как он выполняет ту работу, которая ему необходима, он может затем игнорировать второй сигнал (тот, что получен от завершителя), поскольку для QCompleter нет смысла завершать пустую строку.

Кроме того, мне нужно это поведение (т. Е. Не просто игнорировать сигнал, если helpline-> text (). Length () равно 0), потому что в моем приложении пользователь может просто нажать клавишу ввода с пустым строка.

0 голосов
/ 29 декабря 2010

Вы можете попытаться убедиться, что вы подключены только к одному сигналу. Если завершитель виден, то подключитесь к его сигналу и отключите от линии редактирования. Когда завершитель завершится, вернитесь к строке редактирования. Вот пример файла, который работает так, как вы хотите.

#include <QAbstractItemView>
#include <QApplication>
#include <QCompleter>
#include <QDebug>
#include <QLineEdit>

class MyLineEdit : public QLineEdit
{
Q_OBJECT
public:
    MyLineEdit() : m_completer( new QCompleter( QStringList( "foo" ) ) )
    {
        setCompleter( m_completer );
        m_completer->popup()->installEventFilter( this );
        connectReturnPressed();
    }

    virtual bool eventFilter( QObject* watched, QEvent* e )
    {
        if ( e->type() == QEvent::Show )
        {
            connectCompleterActivated();
        }
        else if ( e->type() == QEvent::Hide )
        {
            connectReturnPressed();
        }

        return QLineEdit::eventFilter( watched, e );
    }

private slots:
    void myslot() { qDebug() << "myslot"; }

private:
    void connectReturnPressed()
    {
        disconnect( m_completer, SIGNAL( activated( const QString& ) )
                  , this, SLOT( myslot() ) );
        connect( this, SIGNAL( returnPressed() )
                     , SLOT( myslot() ) );
    }
    void connectCompleterActivated()
    {
        disconnect( this, SIGNAL( returnPressed() )
                  , this, SLOT( myslot() ) );
        connect( m_completer, SIGNAL( activated( const QString& ) )
               , SLOT( myslot() ) );
    }

    QCompleter*const m_completer;
};

#include "main.moc"

int main( int argc, char** argv )
{
    QApplication qapp( argc, argv );

    MyLineEdit*const edit = new MyLineEdit;
    edit->show();

    return qapp.exec();
}
...