【问题标题】:Qt: how to move textEdit cursor to specific col and rowQt:如何将 textEdit 光标移动到特定的列和行
【发布时间】:2016-10-17 08:01:41
【问题描述】:

我可以通过 QTextCursor::blockNumber()QTextCursor::positionInBlock()。我的问题是如何将光标移动到带有行和列的特定位置。喜欢

setPosition(x,y) // The current cursor would move to row x and col y.

有可能吗?

【问题讨论】:

    标签: c++ qt qtextedit


    【解决方案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);
    

    其中xy 是必需的位置。

    【讨论】:

    • 你应该先把它移到开头。
    • 取决于应用程序。我不知道初始状态。但是,是的,这可能是必要的。
    • 至少可以连续调用。
    • 这很好用,因为您不必制作循环 + 添加 .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 也是首选方式。最后也是一种没有循环的类似方法。

    更多解释,也许更好的解决方案:

    理论上,文本没有 GUI 中显示的“行”,但 endline-character\n\r\n 取决于操作系统和框架)只是另一个字符。因此,对于光标而言,几乎所有内容都只是一个没有线条的“文本”。

    有一些包装函数可以处理这个问题,但我稍后会介绍它们。首先,您不能通过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 行,但 not 会将其设置为您所在行的第 5 个字符,但属于整个文本。所以先移动 x 坐标,然后移动 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
    

    【讨论】:

    • @Tarod 谢谢。考虑到问题的长度,这可能有点太多了:D
    【解决方案3】:

    如果文档布局每行使用 1 个块(例如,它是 QPlainTextEdit 或文档包含非常基本格式的文本),那么您可以直接设置位置:

    void setCursorLineAndColumn (QTextCursor &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);
    

    如果相关,还有性能优势。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-08-24
      • 1970-01-01
      • 1970-01-01
      • 2012-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多