#c #qt #qtextedit
#c #qt #qtextedit
Вопрос:
Я могу получить текущую позицию в строке и столбце с помощью QTextCursor::blockNumber() и QTextCursor::positionInBlock(). Мой вопрос в том, как переместить курсор в определенную позицию с помощью строки и столбца. Нравится
setPosition(x,y) // The current cursor would move to row x and col y.
Возможно ли это сделать?
Ответ №1:
Я думаю, что лучший способ — через QTextCursor
.
Например, если ваш QTextEdit
вызывается textEdit
:
QTextCursor textCursor = ui->textEdit->textCursor();
textCursor.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, x);
textCursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, y);
ui->textEdit->setTextCursor(textCursor);
Где x
и y
— требуемая позиция.
Комментарии:
1. сначала вы должны переместить его в начало.
2. Зависит от приложения. Я не знаю начального состояния. Но да, это может быть необходимо.
3. по крайней мере, для последовательных вызовов.
4. Это отлично работает, потому что вам не нужно создавать циклы добавлять
.movePosition(QTextCursor::Start)
Ответ №2:
Простое решение:
Просто переместите курсор туда:
textEdit.moveCursor(QTextCursor::Start); //set to start
for( <... y-times ...> )
{
textEdit.moveCursor(QTextCursor::Down); //move down
}
for( < ... x-times ...>)
{
textEdit.moveCursor(QTextCursor::Right); //move right
}
moveCursor также является способом перехода, если вам нужно «выбрать» текст для его изменения. Аналогичный подход без циклов также находится в конце.
Немного больше объяснений и, возможно, лучшее решение:
Теоретически в тексте нет «строк», как показано в графических интерфейсах, но endline-character
( n
или rn
в зависимости от операционной системы и фреймворка) — это всего лишь еще один символ. Итак, для курсора в основном все — это всего лишь один «текст» без строк.
Для решения этой проблемы существуют функции-оболочки, но я перейду к ним позже. Сначала вы не можете получить к ним прямой доступ через QTextEdit
интерфейс, но вам нужно напрямую управлять курсором.
QTextCursor curs = textEdit.textCursor(); //copies current cursor
//... cursor operations
textEdit.setTextCursor(curs);
Теперь для «операций»:
Если вы знаете, в какую позицию вы хотите перейти в строке, которую вы имеете setPosition()
здесь. Эта «позиция» относится не к вертикальным линиям, а ко всему тексту.
Вот как выглядит многострочная строка внутри:
"Hello, World!nAnotherLine"
Это показало бы
Hello, World!
AnotherLine
setPosition()
требуется позиция внутренней строки.
Чтобы перейти к другой строке, вам нужно будет вычислить позицию, найдя первую n
в тексте и добавив свое смещение по x. Если вам нужна 3-я строка, найдите первые 2 n
и т. Д.
К счастью, есть также функция setVerticalMovement
, которая, похоже, переносит это и, возможно, это то, что вы хотите сделать. Он перемещает курсор по вертикали.
Итак, вы могли бы сделать:
curs.setPosition(x); //beginning at first line
curs.setVerticalMovement(y); //move down to the line you want.
После этого вызовите setTextCursor
, как показано выше, с помощью курсора.
Примечание:
Однако порядок важен. setPosition
задает позицию во всем тексте. Таким setPosition(5)
образом, хотя, возможно, в 3-й строке он не будет установлен на 5-й символ в строке, в которой вы находитесь, но для всего текста. Итак, сначала переместите x-cordinate, а затем y.
Однако вам нужно знать о длине строк.
some longer line
short
another longer line
Если вы теперь укажете строку 2 и столбец 7, это будет «вне границ». Я не уверен, как verticalMovement
здесь себя ведет. Я предполагаю, что курсор будет находиться в конце строки.
Когда вы используете QTextCursor
класс напрямую, вы также можете использовать операции перемещения без циклов, потому что у них есть дополнительный параметр для повторения операций.
curs.movePosition(QTextCursor::Start);
curs.movePosition(QTextCursor::Down,<modeMode>,y); //go down y-times
curs.movePosition(QTextCursor::Right,<moveMode>,x); //go right x-times
Комментарии:
1. @Tarod спасибо. учитывая длину вопроса, это может быть слишком много, хотя: D
Ответ №3:
Если макет документа использует 1 блок на строку (например, это a QPlainTextEdit
или документ содержит текст с очень простым форматированием), то вы можете установить позицию напрямую:
void setCursorLineAndColumn (QTextCursor amp;cursor, int line, int col,
QTextCursor::MoveMode mode)
{
QTextBlock b = cursor.document()->findBlockByLineNumber(line);
cursor.setPosition(b.position() col, mode);
// you could make it a one-liner if you really want to, i guess.
}
Основное преимущество перед методами Down Right заключается в том, что намного проще выбирать текст между двумя местоположениями:
QTextCursor cursor = textEdit->textCursor();
setCursorLineAndColumn(cursor, startLine, startCol, QTextCursor::MoveAnchor);
setCursorLineAndColumn(cursor, endLine, endCol, QTextCursor::KeepAnchor);
textEdit->setTextCursor(cursor);
Есть также преимущество в производительности, если это уместно.