首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过QTextCursor修改QTextEdit后Qt程序崩溃

通过QTextCursor修改QTextEdit后Qt程序崩溃
EN

Stack Overflow用户
提问于 2012-05-09 11:03:35
回答 1查看 1.4K关注 0票数 0

我想在按下菜单按钮时缩进QPlainTextEdit的文本。当按钮被按下时,我询问是否有选择,如果没有,我只缩进当前行,如果有,我想缩进选择中的所有行。现在,代码只适用于单行,但是当缩进选定内容时,这行的最后一部分就消失了。例如,如果我有行:"Artificial Intelligence stands no chance against Natural Stupidity.",缩进之后就是:" Artificial Intelligence stands no chance against Natural Stupidi,之后如果我开始在该行中写入,当文本到达现在的句子末尾时,文本开始消失。此外,如果我点击或将光标放在句子后面消失的部分之后,程序就会崩溃。

代码:

代码语言:javascript
复制
void MainWindow::on_action_Indent_triggered()
{
    Document* doc = dynamic_cast<Document*>(ui->tabsManager->currentWidget());
    QTextCursor cursor = doc->textArea->textCursor();
    cursor.beginEditBlock();

    // If ther is no text selected...
    if (cursor.selection().isEmpty()) {
        cursor.movePosition(QTextCursor::StartOfLine);
        cursor.insertText(this->tabLength);
    } else { // If the selection is not empty...
        cursor.beginEditBlock();

        // Save selection start and end
        int start = cursor.selectionStart();
        int end = cursor.selectionEnd();
        cursor.clearSelection();

        // Set end to the end of line of the selected line
        cursor.setPosition(end);
        cursor.movePosition(QTextCursor::EndOfLine);
        end = cursor.position();

        // Set cursor to the start of the first selected line
        cursor.setPosition(start);
        cursor.movePosition(QTextCursor::StartOfLine);
        start = cursor.position();

        // While still in the selection, add "    " to the start of each line
        do {
            cursor.movePosition(QTextCursor::StartOfLine);
            cursor.insertText(this->tabLength);
            end += this->tabLength.count();
            cursor.movePosition(QTextCursor::EndOfLine);
        } while (cursor.position() < end && cursor.movePosition(QTextCursor::Down));

        // Select the changed areatabLenght
        cursor.clearSelection();
        cursor.setPosition(start);
        while (cursor.position() < end)
            cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
    }
    // Set the cursor in the GUI
    doc->textArea->setTextCursor(cursor);
    cursor.endEditBlock();
}

Document是一个QTextPlainEdit,而Document是一个Class。这个->tabLength是一个值为“”的QString

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-05-29 08:41:49

问题很简单:调用beginEditBlock()的次数比调用endEditBlock()的次数多。在} else {之后立即删除beginEditBlock()调用。我可以重现这个问题,匹配的[begin|end]EditBlock()调用确实解决了这个问题。

下面是一个自包含的示例。

代码语言:javascript
复制
# indenttest.pro
CONFIG += qt gui
SOURCES += indenttest.cpp
代码语言:javascript
复制
// indenttest.cpp
#include <cmath>
#include <QWidget>
#include <QVBoxLayout>
#include <QPlainTextEdit>
#include <QPushButton>
#include <QTextCursor>
#include <QTextDocumentFragment>
#include <QApplication>

//

class QPlainTextEdit;
class MainWindow : public QWidget
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);

public slots:
    void on_indent();

private:
    const QString tabLength;
    QPlainTextEdit * textArea;
};

//

MainWindow::MainWindow(QWidget *parent) :
    QWidget(parent),
    tabLength("    ")
{
    QVBoxLayout * layout = new QVBoxLayout(this);
    QPushButton * btn = new QPushButton("Indent", this);
    layout->addWidget(btn);
    textArea = new QPlainTextEdit(this);
    textArea->setPlainText("foo\nbar\nbaz\nbat");
    layout->addWidget(textArea);
    connect(btn, SIGNAL(clicked()), SLOT(on_indent()));

}

void MainWindow::on_indent()
{
    QTextCursor cursor = textArea->textCursor();
    cursor.beginEditBlock();

    // If ther is no text selected...
    if (cursor.selection().isEmpty()) {
        cursor.movePosition(QTextCursor::StartOfLine);
        cursor.insertText(this->tabLength);
    } else { // If the selection is not empty...
        //cursor.beginEditBlock();

        // Save selection start and end
        int start = cursor.selectionStart();
        int end = cursor.selectionEnd();
        //cursor.clearSelection();

        // Set end to the end of line of the selected line
        cursor.setPosition(end);
        cursor.movePosition(QTextCursor::EndOfLine);
        end = cursor.position();

        // Set cursor to the start of the first selected line
        cursor.setPosition(start);
        cursor.movePosition(QTextCursor::StartOfLine);
        start = cursor.position();

        // While still in the selection, add "    " to the start of each line
        do {
            cursor.movePosition(QTextCursor::StartOfLine);
            cursor.insertText(this->tabLength);
            end += this->tabLength.count();
            cursor.movePosition(QTextCursor::EndOfLine);
        } while (cursor.position() < end && cursor.movePosition(QTextCursor::Down));

        // Select the changed areatabLenght
        cursor.clearSelection();
        cursor.setPosition(start);
        while (cursor.position() < end)
            cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
    }
    // Set the cursor in the GUI
    textArea->setTextCursor(cursor);
    cursor.endEditBlock();
}

int main(int argc, char** argv)
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

#include "indenttest.moc"
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10509305

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档