为啥slot函数调用成功也不能插入文本

Posted

技术标签:

【中文标题】为啥slot函数调用成功也不能插入文本【英文标题】:Why the slot function cannot insert text even if it's successfully called为什么slot函数调用成功也不能插入文本 【发布时间】:2019-12-05 15:53:19 【问题描述】:

我正在使用 QScintilla 在 Qt 中编写代码编辑器。

我想在输入前括号时自动补全后括号。所以我将cursorPositionChanged(int, int) 信号连接到complete_braces() 插槽并且连接正常。但是insert()语句即使调用了slot函数也不起作用。

这适用于运行 Qt 5.13.0(MinGW 7.3.0 32 位)、Qt Creator 4.9.2、QScintilla 2.11.2 的 Windows 10 PC。 信号和槽的连接正常,因为qDebug()语句输出正确。 当我将工具栏按钮触发器连接到插槽功能并按下按钮时。后支架放置正确。 insert(QString) 函数在我在普通函数中调用时可以正常工作。

标题:

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

    Q_OBJECT
...

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

代码:

/* 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.
    

...

我希望正确调用 slot 函数中的 insert(QString) 函数,但它没有。

如何使插入语句生效,或者是否有其他方法可以自动完成括号?

【问题讨论】:

【参考方案1】:

似乎QsciScintilla 不允许在连接到textChanged 信号的插槽中添加文本,一个可能的解决方案是稍后使用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);
        );

另一方面,建议您使用新的连接语法:

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

【讨论】:

它有效,谢谢!但是,当我使用新的连接语法时,会出现"QObject::connect: signal not found in CodeEditor" 的错误,但旧的连接语法运行良好。我不知道为什么会这样。

以上是关于为啥slot函数调用成功也不能插入文本的主要内容,如果未能解决你的问题,请参考以下文章

C语言中函数为啥可以嵌套定义 ?

PHP为啥不能调用MySQL

为啥我不能从内部调用一个类的 start 函数?

QThread 与 QObject的关系(QObject可以用于多线程,可以发送信号调用存在于其他线程的slot函数,但GUI类不可重入)

为啥不能在 PHP 中从抽象类中调用抽象函数?

QT出现重复调用SLOT函数