Results 1 to 3 of 3

Thread: QGraphicsTextItem and text cursor position via QPoint

  1. #1
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    4,380
    Thanks
    19
    Thanked 1,005 Times in 913 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60
    Wiki edits
    5

    Default QGraphicsTextItem and text cursor position via QPoint

    Hi,

    I have a customized QGraphicsTextItem. By default the item is not editable. If one would like to change the content he has to double click the item:
    Qt Code:
    1. void MyWordItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent */*event*/)
    2. {
    3. setTextInteractionFlags(Qt::TextEditorInteraction);
    4. }
    To copy to clipboard, switch view to plain text mode 
    Now every time the blinking cursor is at the position 0, but I want the text cursor to be near the mouse double click position. (Like the result if one click the mouse button a third time.) Looking through QTextCursor, QTextDocument for a function like setTextCursorPos(QPoint) faild (I would like to use event->pos()). Even in the sources I don't figure out how the trolls do it in the mouse press reimp...

    Passing the event to QGraphicsTextItem::mouseDoubleClickEvent(event); or QGraphicsTextItem::mousePressEvent(event); ends in a total selection of the content.


    Any suggestions?
    Thanks

  2. The following user says thank you to Lykurg for this useful post:

    mhennings (6th December 2012)

  3. #2
    Join Date
    Dec 2012
    Posts
    7
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QGraphicsTextItem and text cursor position via QPoint

    I know this thread is older than Saint Nicholas, but I had the exact same problem today and I found a solution that at least works for Qt 4.7.4.

    Setup:

    A customized QGraphicsTextItem class named TextItem.

    In the constructor, it gets these settings:

    Qt Code:
    1. setFlags(ItemIsSelectable | ItemIsMovable | ItemIsFocusable);
    2. setTextInteractionFlags(Qt::NoTextInteraction);
    To copy to clipboard, switch view to plain text mode 

    This public function turns text editor mode on or off:

    Qt Code:
    1. void SetTextInteraction(bool on, bool selectAll = false)
    2. {
    3. if(on && textInteractionFlags() == Qt::NoTextInteraction)
    4. {
    5. // switch on editor mode:
    6. setTextInteractionFlags(Qt::TextEditorInteraction);
    7. // manually do what a mouse click would do else:
    8. setFocus(Qt::MouseFocusReason); // this gives the item keyboard focus
    9. setSelected(true); // this ensures that itemChange() gets called when we click out of the item
    10. if(selectAll) // option to select the whole text (e.g. after creation of the TextItem)
    11. {
    12. QTextCursor c = textCursor();
    13. c.select(QTextCursor::Document);
    14. setTextCursor(c);
    15. }
    16. }
    17. else if(!on && textInteractionFlags() == Qt::TextEditorInteraction)
    18. {
    19. // turn off editor mode:
    20. setTextInteractionFlags(Qt::NoTextInteraction);
    21. // deselect text (else it keeps gray shade):
    22. QTextCursor c = this->textCursor();
    23. c.clearSelection();
    24. this->setTextCursor(c);
    25. clearFocus();
    26. }
    27. }
    To copy to clipboard, switch view to plain text mode 

    Now we want to turn on the editor mode on mouseDoubleClick:

    Qt Code:
    1. void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *evt)
    2. {
    3. qDebug("mouseDoubleClickEvent '%s'", this->toPlainText().toStdString().c_str());
    4. if(textInteractionFlags() == Qt::TextEditorInteraction)
    5. {
    6. // if editor mode is already on: pass double click events on to the editor:
    7. QGraphicsTextItem::mouseDoubleClickEvent(evt);
    8. return;
    9. }
    10.  
    11. // if editor mode is off:
    12. // 1. turn editor mode on and set selected and focused:
    13. SetTextInteraction(true);
    14.  
    15. // 2. send a single click to this QGraphicsTextItem (this will set the cursor to the mouse position):
    16. // create a new mouse event with the same parameters as evt
    17. QGraphicsSceneMouseEvent *click = new QGraphicsSceneMouseEvent(QEvent::GraphicsSceneMousePress);
    18. click->setButton(evt->button());
    19. click->setPos(evt->pos());
    20. QGraphicsTextItem::mousePressEvent(click);
    21. delete click; // don't forget to delete the event
    22. }
    To copy to clipboard, switch view to plain text mode 

    To leave the editor mode, it is sufficient to wait for the deselection event:

    Qt Code:
    1. QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
    2. {
    3. if(change == QGraphicsItem::ItemSelectedChange) qDebug("itemChange '%s', selected=%s", this->toPlainText().toStdString().c_str(), value.toString().toStdString().c_str());
    4. if(change == QGraphicsItem::ItemSelectedChange
    5. && textInteractionFlags() != Qt::NoTextInteraction
    6. && !value.toBool())
    7. {
    8. // item received SelectedChange event AND is in editor mode AND is about to be deselected:
    9. SetTextInteraction(false); // leave editor mode
    10. }
    11. return QGraphicsTextItem::itemChange(change, value);
    12. }
    To copy to clipboard, switch view to plain text mode 

    That's all.

    I left the qDebug() outputs in the code for your convenience. :-)

    Since SetTextInteraction() is public, you can call it after creating a TextItem, so the user can start typing directly (you need to make sure that the view and the scene have the keyboard focus).
    Last edited by mhennings; 6th December 2012 at 15:48. Reason: itemChange: corrected comment

  4. #3
    Join Date
    Jul 2012
    Posts
    4
    Thanks
    1
    Qt products
    Qt4

    Default Re: QGraphicsTextItem and text cursor position via QPoint

    Thanks for this!

    Here is a near-verbatim refactor to Python that runs:
    (Replace YOUR_CLASS with your class)

    Qt Code:
    1. .
    2. def setTextInteraction(self, state, selectAll=False):
    3. if state and self.textInteractionFlags() == QtCore.Qt.NoTextInteraction:
    4. # switch on editor mode:
    5. self.setTextInteractionFlags(QtCore.Qt.TextEditorInteraction)
    6.  
    7. # manually do what a mouse click would do else:
    8. self.setFocus(QtCore.Qt.MouseFocusReason) # give the item keyboard focus
    9. self.setSelected(True) # ensure itemChange() gets called when we click out of the item
    10. if selectAll: # option to select the whole text (e.g. after creation of the TextItem)
    11. c = self.textCursor()
    12. c.select(QtGui.QTextCursor.Document)
    13. self.setTextCursor(c)
    14.  
    15. elif not state and self.textInteractionFlags() == QtCore.Qt.TextEditorInteraction:
    16. # turn off editor mode:
    17. self.setTextInteractionFlags(QtCore.Qt.NoTextInteraction)
    18.  
    19. # deselect text (else it keeps gray shade):
    20. c = self.textCursor()
    21. c.clearSelection()
    22. self.setTextCursor(c)
    23. self.clearFocus()
    24.  
    25. def mouseDoubleClickEvent(self, event):
    26. log.warn("mouseDoubleClickEvent '%s'", self.toPlainText())
    27.  
    28. if self.textInteractionFlags() == QtCore.Qt.TextEditorInteraction:
    29. # if editor mode is already on: pass double click events on to the editor:
    30. super(YOUR_CLASS, self).mouseDoubleClickEvent(event)
    31. return
    32.  
    33. # if editor mode is off:
    34. # 1. turn editor mode on and set selected and focused:
    35. self.setTextInteraction(True)
    36.  
    37. # 2. send a single click to this QGraphicsTextItem (will set the cursor to the mouse pos)
    38. # create a mouse event with the same parameters as event
    39. click = QtGui.QGraphicsSceneMouseEvent(QtCore.QEvent.GraphicsSceneMousePress)
    40. click.setButton(event.button())
    41. click.setPos(event.pos())
    42. self.mousePressEvent(click)
    43.  
    44. def itemChange(self, change, value):
    45. if change == QtGui.QGraphicsItem.ItemSelectedChange:
    46. log.warn("itemChange '%s', selected=%s", self.toPlainText(), value)
    47.  
    48. if change == QtGui.QGraphicsItem.ItemSelectedChange \
    49. and self.textInteractionFlags() != QtCore.Qt.NoTextInteraction \
    50. and not value:
    51.  
    52. # item received SelectedChange event AND is in editor mode AND is about to be deselected
    53. self.setTextInteraction(False) # leave editor mode
    54.  
    55. return super(YOUR_CLASS, self).itemChange(change, value)
    To copy to clipboard, switch view to plain text mode 

Similar Threads

  1. Rich text in QGraphicsTextItem
    By maverick_pol in forum Qt Programming
    Replies: 3
    Last Post: 29th September 2008, 20:08
  2. Replies: 9
    Last Post: 22nd February 2008, 16:22
  3. [Solved] Selecting text with mouse in a QGraphicsTextItem
    By pherthyl in forum Qt Programming
    Replies: 2
    Last Post: 11th August 2007, 19:10
  4. Editable text in QGraphicsView
    By wysota in forum Qt Programming
    Replies: 8
    Last Post: 24th February 2007, 15:30

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.