void QTextDocument::contentsChange(int position, int charsRemoved, int charsAdded) [signal]
当文档的内容改变时发出这个信号;例如,当插入或删除文本时,或者当应用格式化时。
用户可以点击剪切/删除/退格或任何其他方式,将删除文本。问题是文本被删除后发出的信号。所以我不知道哪条短信被删了。现在position和charsRemoved都没有用了
我想找出QPlainTextEdit中删除的文本。有什么办法可以做到这一点吗?
调用Googie建议的undo
和redo
的技巧很好,为了使其更有效,可以使用QTextCursor
来提取文本,而不是调用toPlainText
:
void TextEdit::slotCheckRange(int pos, int removed, int added){
if(removed > 0){
undo();
QTextCursor c(textCursor());
c.setPosition(pos);
c.setPosition(pos + removed, QTextCursor::KeepAnchor);
qDebug() << "Removed: " << removed << " (" << c.selectedText() << ")";
redo();
}
if(added > 0){
QTextCursor c(textCursor());
c.setPosition(pos);
c.setPosition(pos + added, QTextCursor::KeepAnchor);
qDebug() << "Added: " << added << " (" << c.selectedText() << ")";
}
}
我看到两个可能的解决方案:
-
在每次内容更改后存储文档的内容,因此在每次下一次更改中,您将能够访问以前的内容,并且您将能够使用position和charsRemoved提取值。
优点:隔离机制,不会干扰任何其他信号或插槽
缺点:这意味着大量的内存和CPU占用(每次文本更改都会导致完整的字符串复制)。
-
(我认为更好的一个)在插槽函数实现中,使用
QPlainTextEdit
的undo()
和redo()
方法来恢复查询charsRemoved时的先前内容。请注意,调用undo()
和redo()
不会触发contentsChange()
信号(我刚刚测试了它),所以它就这么简单。优点:不会造成额外的内存占用。不确定CPU占用,但我认为在这种情况下也更好。
缺点:这将只工作与撤销/重做机制启用(这是默认的),它也可能影响任何撤销/重做代码,你使用或覆盖(通常不是这样)。
为清楚起见,为解决方案2截取的示例代码:
void MainWindow::textChanged(int pos, int rem, int add)
{
ui->plainTextEdit->undo();
qDebug() << ui->plainTextEdit->document()->toPlainText().mid(pos, rem); // <- text removed
ui->plainTextEdit->redo();
qDebug() << ui->plainTextEdit->document()->toPlainText().mid(pos, add); // <- text added
}