Узнайте удаленный текст QPlainTextEdit

void QTextDocument::contentsChange(int position, int charsRemoved, int charsAdded) [signal]

Этот сигнал испускается всякий раз, когда изменяется содержание документа; например, когда текст вставляется или удаляется, или когда применяется форматирование.

Пользователь может щелкнуть вырезать / нажать клавишу удаления / возврата или любым другим способом и удалит текст.
Проблема в том, что этот сигнал испускается после удаления текста. Так что я не знаю, какой текст был удален. Теперь позиция и charsRemoved бесполезны.

Я хочу узнать удаленный текст QPlainTextEdit. Есть ли способ добиться этого?

1

Решение

Я вижу 2 возможных решения:

  1. Сохраняйте содержимое документа после каждого изменения содержимого, поэтому при каждом следующем изменении вы будете иметь доступ к предыдущему содержимому и сможете извлечь значение, используя позиция а также charsRemoved.

    Плюсы: Это изолированный механизм и не будет мешать другим сигналам или слотам.

    Минусы: Это подразумевает значительную память и загрузку процессора (каждое изменение текста приводит к полному копированию строки).

  2. (лучше на мой взгляд) В реализации функции слота используйте undo() а также redo() методы QPlainTextEdit восстановить предыдущее содержимое на время запроса charsRemoved. Обратите внимание, что зовет undo() а также redo() не буду вызвать contentsChange() сигнал (я только что проверил), так что это так просто.

    Плюсы: Не вызывает дополнительной памяти. Не уверен насчет загрузки процессора, но я думаю, что в этом случае тоже лучше.

    Минусы: Это будет работать только с Отменить повторить механизм включен (что по умолчанию), и это также может повлиять на любой код отмены / повтора, который вы используете или переопределяете (обычно это не так).

Чтобы быть понятным, пример кода, снятый для решения 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
}
1

Другие решения

Трюк с вызовом undo а также redo предложенный Googie это хорошо, чтобы сделать его еще более эффективным, можно использовать 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() << ")";
}
}
1

По вопросам рекламы [email protected]