4

I am really stuck up with a task relating to Qt GraphicsView. Any help or suggestions will be highly appreciated. In my QGraphicsView application, I have a few editable QGraphicsTextItems that I have added to the scene. I need the following functionality:

  • Setting validator for float so that the user does not by mistake enter a character or new line in that text item.
  • Emitting a signal once the text is changed by the user.

Can anyone please suggest how I can implement this in my application? I have tried real hard but I am not able to find anything suitable. If there is any alternative or workaround, I'll be grateful to know.

Thanks!

Abhishek Bansal
  • 12,589
  • 4
  • 31
  • 46

1 Answers1

8

QGraphicsTextItem does not support this ability, as I'm sure you have discovered. So you have a few options:

  1. Reimplement focusOutEvent(QFocusEvent* event) and/or keyReleaseEvent(QKeyEvent* event) to detect when you validator needs to run. A QValidator can be created as a member of your text class, and queried either when focus is lost and/or a key is pressed (the enter key to signify completion, or on every letter). Then just create a custom signal for you when deem the editing to have finished or changed.
  2. Use a GraphicsProxyWidget to hold a 'real' QLineEdit for text entry, just set it up with a validator as you would if placing in a traditional GUI form. You will need to 'forward' the editingFinished() or textEdited(const QString& text) signal from the QLineEdit to your QGraphicsTextItem, so you don't have to provide external access to the widget.
  3. You could also use the internal QTextDocument of the QGraphicsTextItem, this is what actually holds and formats the text (access it with document()). However it doesn't support having a QValidator installed, so you would have to create a signal-slot loop whereby when the text is changed (signalled by contentsChanged()) it's received by the QGraphicsTextItem, validated, then either updated/cleared if it fails validation (which will update the QTextDocument, and trigger this process again) or ignored if it passes.

Neither is difficult to implement; the first requires more code but will give you more control over the visual appearance of the text box.

cmannett85
  • 21,725
  • 8
  • 76
  • 119
  • 2
    Could [QTextDocument::contentsChanged()](http://qt-project.org/doc/qt-5.0/qtgui/qtextdocument.html#contentsChanged) signal work? You can get the QTextDocument object with [QGraphicsTextItem::document()](http://qt-project.org/doc/qt-5.0/qtwidgets/qgraphicstextitem.html#document). I'm just guessing here. – thuga Jun 13 '13 at 08:24
  • @thuga Good idea, it's certainly no more complex than the other approaches. I've edited it in. – cmannett85 Jun 13 '13 at 09:09
  • Thanks guys! really helpful suggestions – Abhishek Bansal Jun 13 '13 at 17:40
  • Thank you, comrade, that's it! // Спасибо, товарищ! ^_^ – Felix Apr 02 '17 at 08:19
  • Thanks, I ran into the same problem... Question on option 1: What's the advantage of using QValidator at all? Why can't I make validation within `keyReleasedEvent`? – so.very.tired Oct 04 '17 at 17:51