Qt: как переместить курсор TextEdit в определенный столбец и строку

#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);
 

Есть также преимущество в производительности, если это уместно.