Qt Program Crashes aftes QTextEdit 通过 QTextCursor 进行修改
Qt Program Crashes aftes QTextEdit is modified via QTextCursor
我想缩进QPlainTextEdit的文本,按下菜单按钮。按下按钮时,我问是否有选择,如果没有,我只是缩进当前行,如果有,我想缩进选择中的所有行。现在代码适用于单行,但是当缩进所选内容时,就像该行的最后一部分消失一样。例如,如果我有行: "Artificial Intelligence stands no chance against Natural Stupidity."
,缩进后它只是:" Artificial Intelligence stands no chance against Natural Stupidi
,之后如果我开始在该行中书写,则文本在到达现在的句子末尾时开始消失。此外,如果我单击或将光标放在句子消失部分之后的那行中,程序就会崩溃。
代码:
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();
}
文档是一个类,textArea 是一个 QTextPlainEdit。 this->tabLength 是一个值为 " " 的 QString
问题很简单:你打电话给beginEditBlock()
的次数比你打电话endEditBlock()
的次数多。} else {
后立即删除beginEditBlock()
呼叫。我可以重现这个问题,匹配[begin|end]EditBlock()
调用确实可以解决它。
下面是一个自包含的示例。
# indenttest.pro
CONFIG += qt gui
SOURCES += indenttest.cpp
// 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("foonbarnbaznbat");
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"
相关文章:
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 独立读取-修改-写入顺序
- 当系统的卷被修改时,如何修改WASAPI环回捕获卷
- 修改函数中的指针(将另一个指针作为参数传递)
- 为什么我可以通过引用修改常量返回
- 对于结构,表达式必须是可修改的ivalue
- QML:修改在不同QML文件(而非main.QML)中定义的子对象的属性
- 为什么不能修改对象中的值?另外,我如何改进此链表?
- 修改创建帐户程序
- 我应该如何修改此代码以使用给定字符串中的字母打印菱形图案
- 如何从子成员函数修改父公共成员变量
- 修改 VS Code 中的默认C++代码段
- 为什么在我的函数类型后使用引用运算符 (&) 允许我修改它返回的值?
- 如何使用递归打印修改后的星号三角形图案
- 已修改的LinkedList未在文本文件本身中更新
- C++RapidXml-使用first_node()遍历以修改XML文件中节点的值
- 为什么可以修改数组 b?
- 将 C++ 类与 Rcpp 一起使用,从 C 或 R 修改它
- 停止 QTextCursor::insertText() 修改 QTextDocument 滚动条范围
- Qt Program Crashes aftes QTextEdit 通过 QTextCursor 进行修改