c++qttextqscintilla

Why the slot function cannot insert text even if it's successfully called


I'm writing a code editor in Qt with QScintilla.

I want to automatically complete the back brackets when I enter the front brackets. So that I connect the cursorPositionChanged(int, int) signal to complete_braces() slot and the connection works. But the insert() statement doesn't work even if the slot function is called.

Header:

/* codeeditor.h */
class CodeEditor : public QsciScintilla
{
    Q_OBJECT
...

public slots:
    void complete_brackets();
...
};

Code:

/* codeeditor.cpp */
CodeEditor::CodeEditor()
{
...
    // Slots
    connect(this, SIGNAL(textChanged()),
            this, SLOT(complete_brackets()));
...
}
...
void CodeEditor::complete_brackets()
{
    int line, index;
    getCursorPosition(&line, &index);
    if (text(line)[index] == '(')
    {
        qDebug() << "Get a bracket"; // This statement works.
        insert(QString(")")); // This statement doesn't work.
    }
}
...

I expected the insert(QString) function in the slot function to be called correctly, but it doesn't.

How can I do to make the insert statement effective or, is there any other method to auto complete the brackets?


Solution

  • It seems that QsciScintilla does not allow adding text in the slot connected to the textChanged signal, a possible solution is to add it a moment later using a QTimer::singleShot():

    void CodeEditor::complete_brackets(){
        int line, index;
        getCursorPosition(&line, &index);
        if (text(line)[index] == '(')
            QTimer::singleShot(0, [this, line, index](){
              insert(")");
              setCursorPosition(line, index+2);
            });
    }
    

    On the other hand it is recommended that you use the new connection syntax:

    connect(this, &QsciScintilla::textChanged, this, &CodeEditor::complete_brackets);