tags:

views:

429

answers:

3

Hello.

I have a console input in my Qt based application, it's a QLineEdit, all Ui is designed via QtDesigner. Is it any easy way way to handle up and down arrows in order to implement input history? The 'go to slot' only show returnProcessed signal, no way i can see to handle up and down arrows :(

+3  A: 

You can subclass QLineEdit and re-implement the virtual keyPressEvent method to handle your special keys.

void MyLineEdit::keyPressEvent(QKeyEvent *event)
{
    if(event->key() == Qt::Key_Up){
        // move back in history
    }
    else if(event->key() == Qt::Key_Down){
        // move forward in history
    }
    else{
        // default handler for event
        QLineEdit::keyPressEvent(event);
    }
}
Kyle Lutz
It's a good idea. But how to combine subclassing QLineEdit with QtDesigner-generated Ui?
Eye of Hell
See: http://doc.trolltech.com/4.6/designer-creating-custom-widgets.html
Kyle Lutz
So, in order to get up ad down arrows working i need to implement a whole QtDesigner plugin with tons of functions that defines how to use a "new" widget? :(
Eye of Hell
apart from using event filters (see my answer) you can define the same method to you window class and see if lineedit's up\down arrow key events would hit it; unhandled events are propagated up the parent widget chain until a widget accepts it with accept() or an event filter consumes it.
serge_gubenko
@Eye of Hell, in addition to plugins for designer, you can also add a QLineEdit to your form, right-click, and "Promote" it to a derived class. Works like a charm for cases like this.
Caleb Huitt - cjhuitt
@cjhuitt Thanks a lot, that's REALLY useful!
Eye of Hell
+3  A: 

you can install event filter and watch your line edit event in your window class. Below is an example:

declare event handler method on your window class:

class MainWindow : public QMainWindow {
    Q_OBJECT
...
protected:
    void changeEvent(QEvent *e);
...
};

window constructor

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ...
    ui->lineEdit->installEventFilter(this);
}

event handler implementation:

bool MainWindow::eventFilter(QObject* obj, QEvent *event)
{
    if (obj == ui->lineEdit)
    {
        if (event->type() == QEvent::KeyPress)
        {
            QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
            if (keyEvent->key() == Qt::Key_Up)
            {
                 qDebug() << "lineEdit -> Qt::Key_Up";
                 return true;
            }
            else if(keyEvent->key() == Qt::Key_Down)
            {
                qDebug() << "lineEdit -> Qt::Key_Down";
                return true;
            }
        }
        return false;
    }
    return QMainWindow::eventFilter(obj, event);
}

hope this helps, regards

serge_gubenko
One way to simplify further would be to add the event filter to the QLineEdit itself. Then you would not have to care about the obj argument, plus, you can apply it to several QLineEdits (given that you use obj when reacting to the event)
e8johan
Thanks, works like a charm :)
Eye of Hell
A: 

I had the same problem, but I find out in other forums that you need to setFocus, e.g.:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ...
    ui->lineEdit->installEventFilter(this);

    this->setFocus();
}

It works for me.

Reference: http://www.qtforum.org/article/28240/how-to-get-arrow-keys.html

Sinuhe Tellez Rivera