Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

keyPressEvent - how to override?



  • The keyPressEvent is virtual. I want to override it for my QTextEdit. How do I do it?
    I created
    mytextedit.h

    class MyTextEdit : public QTextEdit
    {
        public:
        MyTextEdit();
    
        protected:
        virtual void keyPressEvent( QKeyEvent *  e);
    };
    

    mytextedit.cpp

    void MyTextEdit::keyPressEvent( QKeyEvent * e)
    {
       QMessageBox msgBox;
    
        if(e->key()==Qt::Key_Enter)
        {
            msgBox.setText("OK");
            msgBox.exec();
        }
    
        QTextEdit::keyPressEvent(e);
    }
    

    Now what? How do I connect it to my QTextEdit on the MainForm?


  • Lifetime Qt Champion

    @jenya7 said in keyPressEvent - how to override?:

    How do I connect it to my QTextEdit on the MainForm?

    What do you want to connect and why?



  • @Christian-Ehrlicher said in keyPressEvent - how to override?:

    @jenya7 said in keyPressEvent - how to override?:

    How do I connect it to my QTextEdit on the MainForm?

    What do you want to connect and why?

    I have a text box. When I type in it I want to check what character I type. If it was an Enter - I will take the line and send it serially.


  • Lifetime Qt Champion

    @jenya7 said in keyPressEvent - how to override?:

    I will take the line and send it serially.

    simply emit a signal then, and do whatever you want in your slot: https://doc.qt.io/qt-5/signalsandslots.html



  • @Christian-Ehrlicher said in keyPressEvent - how to override?:

    @jenya7 said in keyPressEvent - how to override?:

    I will take the line and send it serially.

    simply emit a signal then, and do whatever you want in your slot: https://doc.qt.io/qt-5/signalsandslots.html
    What slot? I need to check every typed character? how a slot is related to it?
    We have an event especially designed for this purpose - keyPressEvent.



  • Instead of overriding the keyPressEvent function you can override the eventFilter function.
    bool eventFilter(QObject *obj, QEvent *ev) ;

    and implement as below

    bool eventFilter(QObject *obj, QEvent *event)
    {
    if (obj == MytextEdit)
    {
    if (event->type() == QEvent::KeyPress)
    {
    QKeyEvent keyEvent = static_cast<QKeyEvent>(event);
    qDebug() << keyEvent->key();
    return true;
    }
    else {

          return eventFilter(obj, event);
      }
    

    }

    Now after this you can go to your main form and create the object of Mytextedit and install event filter for the textedit object ...



  • @Ashok-Kumar
    Thank you. How do I install the event filter for the textedit object?



  • @jenya7 you can create textedit object and do

    textedit->installEventFilter(this);



  • @Ashok-Kumar said in keyPressEvent - how to override?:

    @jenya7 you can create textedit object and do

    textedit->installEventFilter(this);

    In mainwindow.cpp I do

    bool eventFilter(QObject *obj, QEvent *event)
    {
        if (obj == textEditTerminalTx) 
        {
            if (event->type() == QEvent::KeyPress) 
            {
                QKeyEvent keyEvent = static_cast<QKeyEvent>(event);
                //qDebug() << keyEvent->key();
                return true;
            } 
            else 
            {
                return false;
            }
        } 
        else 
        {
            // pass the event on to the parent class
            return eventFilter(obj, event);
        }
    }
    

    On this line obj == textEditTerminalTx I get - error: use of undeclared identifier 'textEditTerminalTx'
    On this line QKeyEvent keyEvent = static_cast<QKeyEvent>(event); - I get error: no matching conversion for static_cast from 'QEvent *' to 'QKeyEvent'



  • @jenya7 instead of doing casting like u did above QKeyEvent keyEvent = static_cast<QKeyEvent>(event);

    instead u can do like this

    QKeyEvent keyEvent=(QKeyEvent*)(event);
    It will work



  • @Ashok-Kumar said in keyPressEvent - how to override?:

    @jenya7 instead of doing casting like u did above QKeyEvent keyEvent = static_cast<QKeyEvent>(event);

    instead u can do like this

    QKeyEvent keyEvent=(QKeyEvent*)(event);
    It will work

    This way I get - error: no viable conversion from 'QKeyEvent *' to 'QKeyEvent'

    Ah I see - QKeyEvent keyEvent = (QKeyEvent)(event); - the site editor removes a pointer star.

    And why the object not visible in the scope - if (obj == textEditTerminalTx) ?
    I tried if (obj == ui->textEditTerminalTx) but ui also not visible.

    Say in functions with MainWindow:: ui is visible like
    void MainWindow::on_ButtonCompileScript_clicked()
    {
    QString text = ui->textEditScriptIn->toPlainText();
    }

    OK.

    In mainwindow.h I added

    public:
        bool eventFilter(QObject *obj, QEvent *event);
    

    In mainwindow.cpp

    MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        ui->textEditTerminalTx->installEventFilter(this);
    }
    
    bool MainWindow::eventFilter(QObject *obj, QEvent *event)
    {
        QMessageBox mb;
        if (obj == ui->textEditTerminalTx)
        {
            if (event->type() == QEvent::KeyPress)
            {
                QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
                if (keyEvent->key() == Qt::Key_Enter)
                {
                    mb.setText("Enter");
                    mb.exec();
                }
                return true;
            }
            else
                return false;
        }
        else
        {
            // pass the event on to the parent class
            return eventFilter(obj, event);
        }
    }
    

    But when I type - no char is typed in the widget and no reaction on Enter key.



  • @jenya7 If u r getting no viable conversion from QKeyEvent* to QKeyEvent. include <QKeyEvent> headerfile in the mainwindow class



  • @Ashok-Kumar said in keyPressEvent - how to override?:

    @jenya7 If u r getting no viable conversion from QKeyEvent* to QKeyEvent. include <QKeyEvent> headerfile in the mainwindow class

    I do get the event. To test it I added

    if (event->type() == QEvent::KeyPress)
            {
                QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
                if (keyEvent->key() == Qt::Key_Return)
                {
                    mb.setText("Enter");
                    mb.exec();
                }
                else
                {
                    term_str += static_cast<char> (keyEvent->key());
                    ui->textEditTerminalTx->setText(term_str);
                }
                return true;
            }
            else
                return false;
    

    When I type I get chars in the widget but it types also backspase and delete keys instead of action. And on Key_Return I see the message box.



  • @jenya7
    if u want only chars in the QTextedit then u can use try this

    if(keyevent->key()>=Qt::Key_0 && keyevent->key()<=Qt::Key_9)

    if u want only digits in the QTextedit then u can use try this

    if(keyevent->key()>=Qt::Key_A && keyevent->key()<=Qt::Key_Z)...

    If u create the QMessageBox object in the constructor then it will be shown in the beginning itself



  • @Ashok-Kumar said in keyPressEvent - how to override?:

    @jenya7
    if u want only chars in the QTextedit then u can use try this

    if(keyevent->key()>=Qt::Key_0 && keyevent->key()<=Qt::Key_9)

    if u want only digits in the QTextedit then u can use try this

    if(keyevent->key()>=Qt::Key_A && keyevent->key()<=Qt::Key_Z)...

    If u create the QMessageBox object in the constructor then it will be shown in the beginning itself

    to get every possible key I did so

    if (keyEvent->key() != Qt::Key_Backspace && keyEvent->key() != Qt::Key_Delete)
     {
                term_str += static_cast<char> (keyEvent->key());
               ui->textEditTerminalTx->setText(term_str);
     }
    

    but the keys Backspace and Delete don't act as suppose to be - no action - it suppose to delete chars.
    Also it gets chars only in upper case ignoring CapsLock selection.

    This way it works

    bool MainWindow::eventFilter(QObject *obj, QEvent *event)
    {
        QMessageBox mb;
        if (obj == ui->textEditTerminalTx)
        {
            if (event->type() == QEvent::KeyPress)
            {
                QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
                if (keyEvent->key() == Qt::Key_Return)
                {
    
                    mb.setText("Enter");
                    mb.exec();
                }
                else
                {
                    //term_str += static_cast<char> (keyEvent->key());
                    return false;
                }
            }
            else
                return false;
        }
        else
            // pass the event on to the parent class
            return MainWindow::eventFilter(obj, event);
    }
    


  • @jenya7 What exactly is your problem. Which keys do you need to use in textedit . can u elaborate it .



  • @Ashok-Kumar said in keyPressEvent - how to override?:

    @jenya7 What exactly is your problem. Which keys do you need to use in textedit . can u elaborate it .

    The last function's version solves the problem - I get all the chars and keys Backspase and Delete work.
    Now - on Enter key - I'd like to take the line before the Enter key and send it. Looking how to get the line before the Enter key. Trivial things so difficult in Qt... :)



  • @jenya7 If u want the text before the enter key then you have to emit signal with parameter as string and write a particular slot for that and there u can get that text...

    signal:
    void textBeforeEnter(QString);

    slot :
    void getText(QString);

    connect(this,SIGNAL(textBeforeEnter(QString)),this,SLOT(getText(QString)));
    emit textBeforeEnter(textedit.text);

    void getText(QString text)
    {
    qDebug()<<"The text in textedit before pressing enter key is "<<text<<endl;
    }


Log in to reply