c++qtqwidgetqtextedittextchanged

How to emit QTextTexid::textChanged signal only in certain cases selectively?


Can you trigger the textChanged signal only for certain cases? for example triggering it for inserted text, inserted space characters but not backspace?

I am running checks for typed characters inside a QTextEdit every time the text changes and based on the results highlighting text inside a read-only QTextEdit in the background used as an always-on placeholder text for the user to look at while typing. If the user makes a mistake the character gets highlighted red and reset to it's initial background color after the mistake is fixed. The problem arises when the backspace key is pressed, as it is registered as a mistake and as a result the previous character also gets highlighted red.

 void Widget::onTextChanged()
 {
     QChar c;

     QString txt_contents = txtedit_->toPlainText();

     if(txt_contents.isEmpty()){
         c = '\0';

         //reset text display
         txtdisplay_->clear();
         txtdisplay_->append(*label_text_);
     }
     else
         c = txtedit_->toPlainText().back();
  
     if(!texteditq_->isEmpty()){
         if(c == texteditq_->head()){
             //refresh text display
             correct_++;
             txtdisplay_->clear();
             txtdisplay_->append(*label_text_);

             //remove character that was used for the successful check from the
             //queue
             texteditq_->dequeue();
         }else{
             //set backgroud color to red for errors
             fmt_->setBackground(Qt::red);

             if(!txtedit_->toPlainText().isEmpty()){
                 //move cursor to the end of the editor, where the error is and save
                 //the position the error occurs at
                 c_edit_->movePosition(QTextCursor::End);
                 quint32 error_pos = c_edit_->position();

                 //move the cursor in the display for the background text and
                 //use the KeepAnchor move mode to highlight the misspelled char
                 c_display_->setPosition(error_pos-1,QTextCursor::MoveAnchor);
                 c_display_->setPosition(error_pos,QTextCursor::KeepAnchor);

                 //apply formating to that character
                 c_display_->setCharFormat(*fmt_);
             }
         }
     }
 }

Solution

  • As per OP's request, I am posting a solution that is a class called CustomTextEdit which is subclassing QTextEdit. It is hooking to keyPressEvent() and checking the key that was pressed. If it was other than Backspace then the custom signal keyPressed() will get emitted.

    class CustomTextEdit : public QTextEdit {
      Q_OBJECT
     public:
      explicit CustomTextEdit(QWidget *parent = nullptr) : QTextEdit(parent) {}
    
     signals:
      void keyPressed();
    
     protected:
      void keyPressEvent(QKeyEvent *e) override {
        if (e->key() != Qt::Key_Backspace) {
          emit keyPressed();
        }
    
        QTextEdit::keyPressEvent(e);
      }
    };