Results 1 to 9 of 9

Thread: How do I set a QTextEdit to a specific line by line number?

  1. #1
    Join Date
    Mar 2011
    Posts
    22
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Windows

    Question How do I set a QTextEdit to a specific line by line number?

    Hello.
    In my application I'm writing in Qt, I am trying to implement a "Go to Line" dialog which will set the central widget (a QTextEdit) to a specific line that the user enters, using a line number.

    However, I have searched the docs for such a function will allow one to easily do this, and have not found one. Is this because it does not exist? Or maybe I missed it?

    I also need to display the line numbers in the QTextEdit like many text editors do (i.e. displaying the line numbers on the left side of each line), but have also failed to find such existing functionality.

    Any suggestions??

    Thanks.

    EDIT:

    Here is what I have so far:

    Qt Code:
    1. void C_MainWindow::goToLineAction() {
    2.  
    3. bool ok;
    4. int line_number = QInputDialog::getInt(this, tr("Go to Line"),
    5. tr("Enter a line number to go to: "), 1, 1, central_widget_TextDocument->blockCount(), 1, &ok);
    6. if (ok) {
    7. }
    8.  
    9. }
    To copy to clipboard, switch view to plain text mode 

    This creates the "Go to Line" dialog with the default value being the first line's number (1) and the minimal value also being 1, and the maximal value being the number of "blocks" (which I understand is really lines, I believe) that the text editor's document currently has. But it does not (yet) actually go to the line in the QTextEdit, since I don't know how to do that yet (hence this thread).
    Last edited by Coolname007; 27th December 2012 at 22:39.

  2. #2
    Join Date
    Jul 2012
    Location
    Switzerland
    Posts
    32
    Thanks
    7
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: How do I set a QTextEdit to a specific line by line number?

    Well I would try to set the QTextCursor to this position, something like:

    Qt Code:
    1. QTextCursor txtCursor = edit->textCursor();
    2. //position where you want it
    3. txtCursor.setPosition(...);
    4. edit->setTextCursor(txtCursor);
    To copy to clipboard, switch view to plain text mode 

  3. #3
    Join Date
    Mar 2011
    Posts
    22
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: How do I set a QTextEdit to a specific line by line number?

    Quote Originally Posted by airglide View Post
    Well I would try to set the QTextCursor to this position, something like:

    Qt Code:
    1. QTextCursor txtCursor = edit->textCursor();
    2. //position where you want it
    3. txtCursor.setPosition(...);
    4. edit->setTextCursor(txtCursor);
    To copy to clipboard, switch view to plain text mode 
    Well, how would I convert a line number to an absolute position inside of a document (which is what that setPosition() function requires)?

    Also, assuming I could get that to work, I don't think a text cursor principle would work on a QTextEdit which has had its setReadOnly(true) function called (since setting it to read-only mode means you can no longer use the cursor in it), which is what I do for "Standard Mode" in my application...


    Added after 52 minutes:


    Hmm...
    I have tried the following code to see if it might work, but it did not perform as expected. In the "Go to Line" dialog, I entered line 14 for a document that contains 14 lines, but instead of selecting line 14, it selected line 1, proving it does not work.

    Qt Code:
    1. void C_MainWindow::goToLineAction() {
    2.  
    3. bool ok;
    4. int line_number = QInputDialog::getInt(this, tr("Go to Line"),
    5. tr("Enter a line number to go to: "), 1, 1, central_widget_TextDocument->blockCount(), 1, &ok);
    6. if (ok) {
    7. QTextCursor text_cursor(central_widget_TextDocument->findBlockByLineNumber(line_number));
    8. text_cursor.select(QTextCursor::BlockUnderCursor);
    9. central_widget_TextEdit->setTextCursor(text_cursor);
    10. }
    11.  
    12. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by Coolname007; 28th December 2012 at 04:28.

  4. #4
    Join Date
    Dec 2012
    Posts
    90
    Thanks
    5
    Thanked 20 Times in 18 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: How do I set a QTextEdit to a specific line by line number?

    I have tried the following code to see if it might work, but it did not perform as expected. In the "Go to Line" dialog, I entered line 14 for a document that contains 14 lines, but instead of selecting line 14, it selected line 1, proving it does not work.
    Use findBlockByLineNumber (line_number -1), since findBlockByNumber works on zero-based line numbers.
    After that you can set position of the cursor (rather than selecting whole block):
    Qt Code:
    1. QTextBlock text_block = central_widget_TextDocument->findBlockByLineNumber(line_number-1);
    2.  
    3. QTextCursor text_cursor = central_widget_TextEdit->textCursor ();
    4. text_cursor.setPosition (text_block.position ());
    5. central_widget_TextEdit->setFocus ();
    6. central_widget_TextEdit->setTextCursor (text_cursor);
    To copy to clipboard, switch view to plain text mode 

    BUT, I don't think i fully understand concept of a block. Can it contain multiple lines?
    Can anyone clarify on that?
    If this is the case, this method will not work. Then you can simply have a list of the absolute positions of strings inside your text edit and set up cursor accordingly to this list.


    To display line numbers you can subclass text edit and do custom painting in paint event using drawText and QFontMetrics (first thing that comes to mind).
    What is unclear for me is how you get what lines are displayed.

  5. #5
    Join Date
    Mar 2011
    Posts
    22
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: How do I set a QTextEdit to a specific line by line number?

    Quote Originally Posted by lanz View Post
    Use findBlockByLineNumber (line_number -1), since findBlockByNumber works on zero-based line numbers.
    Hey, thanks for that. I wasn't aware that the findBlockByNumber() function uses 0-based line numbers, and it doesn't mention it in the docs.
    I just assumed it used 1-based numbers.
    I tried modifying the code in my last post to use line_number - 1 instead of just line_number, and that appears to have fixed it. It now selects
    the right line that I enter in. However, I have noticed something a bit strange in its behavior: Instead of just selecting the line that I entered, it also appears to select a
    one-character-width space before the line as well (even if the line before is empty). And if I enter in a line number corresponding to a line that does not follow an empty line,
    it does not select any of the characters of the previous line, but appears to select a one-character-width space after the previous line's characters. I do not know why this is.
    I suspect it has something to do with Qt's concept of a "block".

    After that you can set position of the cursor (rather than selecting whole block):
    Thanks, but I'd rather keep selecting the whole block, reason being when the text edit is in read-only mode (which is true in my application when the text editor mode is in "Standard mode", meaning you can only edit the document with the GUI controls,
    and can not directly modify the document), it does not show the cursor, and you can only select the text.
    Qt Code:
    1. QTextBlock text_block = central_widget_TextDocument->findBlockByLineNumber(line_number-1);
    2.  
    3. QTextCursor text_cursor = central_widget_TextEdit->textCursor ();
    4. text_cursor.setPosition (text_block.position ());
    5. central_widget_TextEdit->setFocus ();
    6. central_widget_TextEdit->setTextCursor (text_cursor);
    To copy to clipboard, switch view to plain text mode 
    Thanks for the example code. I didn't even think of looking at the QTextBlock class for a function to get the position.
    However, since "text_block.position()" refers to a position corresponding to that of the first character of the block in the document, wouldn't that position be different in terms of cursor positions (since the cursor is always in between characters, and not on the same space)? Maybe it should be "text_block.position() - 1"?
    BUT, I don't think i fully understand concept of a block. Can it contain multiple lines?
    Can anyone clarify on that?
    Good question. I'm wondering the same thing myself, especially after the results I just got.
    I will wait for an answer...

    If this is the case, this method will not work. Then you can simply have a list of the absolute positions of strings inside your text edit and set up cursor accordingly to this list.


    To display line numbers you can subclass text edit and do custom painting in paint event using drawText and QFontMetrics (first thing that comes to mind).
    What is unclear for me is how you get what lines are displayed.
    Keep in mind, I'm still relatively new to Qt, and don't quite understand how to do "custom painting in paint event".
    I would appreciate it if you could give some example code demonstrating this.

    Thanks.


    Added after 47 minutes:


    Ok, I guess not (about the cursor position thing)...
    I just tried the following code, and the cursor (in "Hand-Editing" mode) shows up on the right position on the right line when I enter a line to go to.
    But, as before, the selection problem still exists.

    Qt Code:
    1. void C_MainWindow::goToLineAction() {
    2.  
    3. bool ok;
    4. int line_number = QInputDialog::getInt(this, tr("Go to Line"),
    5. tr("Enter a line number to go to: "), 1, 1, central_widget_TextDocument->blockCount(), 1, &ok);
    6. if (ok) {
    7. /*
    8.   QTextCursor text_cursor(central_widget_TextDocument->findBlockByLineNumber(line_number - 1));
    9.   text_cursor.select(QTextCursor::BlockUnderCursor);
    10.   central_widget_TextEdit->setTextCursor(text_cursor);
    11.   */
    12. QTextBlock text_block = central_widget_TextDocument->findBlockByLineNumber(line_number - 1);
    13. QTextCursor text_cursor = central_widget_TextEdit->textCursor ();
    14. text_cursor.setPosition (text_block.position());
    15. central_widget_TextEdit->setFocus();
    16. text_cursor.select(QTextCursor::BlockUnderCursor);
    17. central_widget_TextEdit->setTextCursor (text_cursor);
    18. }
    19.  
    20. }
    To copy to clipboard, switch view to plain text mode 

    EDIT:

    Nevemind about the selection problem. FIXED!

    Qt Code:
    1. void C_MainWindow::goToLineAction() {
    2.  
    3. bool ok;
    4. int line_number = QInputDialog::getInt(this, tr("Go to Line"),
    5. tr("Enter a line number to go to: "), 1, 1, central_widget_TextDocument->blockCount(), 1, &ok);
    6. if (ok) {
    7. QTextCursor text_cursor(central_widget_TextDocument->findBlockByLineNumber(line_number - 1));
    8. text_cursor.select(QTextCursor::LineUnderCursor);
    9. central_widget_TextEdit->setTextCursor(text_cursor);
    10.  
    11. /*
    12.   QTextBlock text_block = central_widget_TextDocument->findBlockByLineNumber(line_number - 1);
    13.   QTextCursor text_cursor = central_widget_TextEdit->textCursor ();
    14.   text_cursor.setPosition (text_block.position());
    15.   central_widget_TextEdit->setFocus();
    16.   text_cursor.select(QTextCursor::LineUnderCursor);
    17.   central_widget_TextEdit->setTextCursor(text_cursor);
    18.   */
    19. }
    20.  
    21. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by Coolname007; 28th December 2012 at 18:54. Reason: Solved selection problem

  6. #6
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: How do I set a QTextEdit to a specific line by line number?

    Quote Originally Posted by Coolname007 View Post
    Hey, thanks for that. I wasn't aware that the findBlockByNumber() function uses 0-based line numbers, and it doesn't mention it in the docs.
    I just assumed it used 1-based numbers.
    Why? EVERYTHING in c/c++ is 0-based.
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

  7. #7
    Join Date
    Mar 2011
    Posts
    22
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: How do I set a QTextEdit to a specific line by line number?

    Quote Originally Posted by amleto View Post
    Why? EVERYTHING in c/c++ is 0-based.
    Not everything. Size functions and size parameters in functions always use 1-based numbers.
    Granted, findBlockByLineNumber() is a find function, and find functions in the C++ standard library use 0-based numbers to represent positions.
    But, line numbers and indexes are two separate things. Since line numbers are often displayed (and always in the 1-based format), I just assumed
    that a function which takes a line number as a parameter would count the line number in a 1-based way, and not a 0-based way.
    Last edited by Coolname007; 31st December 2012 at 18:53.

  8. #8
    Join Date
    Dec 2012
    Posts
    90
    Thanks
    5
    Thanked 20 Times in 18 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: How do I set a QTextEdit to a specific line by line number?

    Quote Originally Posted by Coolname007 View Post
    Keep in mind, I'm still relatively new to Qt, and don't quite understand how to do "custom painting in paint event".
    I would appreciate it if you could give some example code demonstrating this.
    There's very good example:
    http://doc.qt.digia.com/qt/widgets-codeeditor.html

  9. The following user says thank you to lanz for this useful post:

    Coolname007 (1st February 2013)

  10. #9
    Join Date
    Mar 2011
    Posts
    22
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: How do I set a QTextEdit to a specific line by line number?

    Quote Originally Posted by lanz View Post
    Awesome. That example looks exactly like what I'm looking for.
    I haven't had time yet to look over it in any depth, but I'm certain I'll find the information that I need in there.

    Thanks a ton. I really appreciate it.

Similar Threads

  1. Read a specific line from a file
    By rleojoseph in forum Qt Programming
    Replies: 11
    Last Post: 21st March 2011, 11:58
  2. Replies: 1
    Last Post: 22nd July 2010, 17:12
  3. QTextDocument line number
    By bunjee in forum Qt Programming
    Replies: 14
    Last Post: 10th June 2008, 13:49
  4. Line Number - QTextEdit...???
    By deepusrp in forum Qt Programming
    Replies: 2
    Last Post: 15th May 2007, 16:34
  5. How to get column number in a line
    By showhand in forum Qt Programming
    Replies: 1
    Last Post: 30th August 2006, 09:42

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.