PDA

View Full Version : Interactive text formatting in QGraphicsTextItem



olelukoie
18th October 2009, 09:33
I've got a problem with interactive text formatting inside a QGraphicsTextItem (more correctly inside my own QGraphicsTextItem-derived class).

I have created the same toolbar as in diagramscene example with five controls - two combos and three buttons - and implemented my own text formatting methods using QTextCursor to apply new formatting to selected text fragments only.

The problem is that when I click on the toolbar on font or font size combo the item on the scene looses focus (and thus looses text selection) and formatting doesn't applies to the text. At the same time simple buttons (bold, italic etc) work OK. It seems that I've missed some option that prevents item from loosing its focus when the mouse pointer leaves the scene or something like this.

Can anybody help me to solve this? Thanks in advance.

PS. I've looked at textedit demo and found that it connects combos' activated() signals to custom slots. It this a solution to this problem? Is there a more advanced example (than the buggy diagramscene) on how to interactively format text inside QGraphicsTextItem?

wysota
18th October 2009, 16:27
Try setting focus policy of those troublesome widgets to NoFocus.

olelukoie
19th October 2009, 06:01
Try setting focus policy of those troublesome widgets to NoFocus.
You mean combo boxes? I've already tried this and found that then I loose the "editable" ability for them (combo box still allows me to select its current value with a mouse but keyboard input doesn't work). It's not critical for font selection but very important for font size combo box.

wysota
19th October 2009, 07:41
I don't know how you would expect it to work then... You either have focus in one item or the other, not in both at once... What you can do is to remember the previously focused item so that you know what to apply the formatting on.

olelukoie
23rd October 2009, 08:23
I don't know how you would expect it to work then... You either have focus in one item or the other, not in both at once...
I have created a couple of screenshots that demonstrate the behavior I need. The first one is an MS Visio diagram and the second one is an OOo Draw diagram.

As you can see on these shots the text cursor (caret) is in font size combo box and it is possible to edit its value with keyboard while the shape on the "scene" remains visually active, selected and seems doesn't loose focus so the text selection is not cleared and displayed using "active" colors.

wysota
23rd October 2009, 08:49
"Visually active" means "selected". Selection and focus are two different things. Multiple things can be selected but only one can have keyboard focus.

olelukoie
23rd October 2009, 12:41
"Visually active" means "selected". Selection and focus are two different things. Multiple things can be selected but only one can have keyboard focus.
Mmm, well, I see... Do you mean that an item can be selected and not have focus at the same time? What should I do to achieve this? How to keep an item selected when focus leaves the scene? By default QGraphicsTextItem becomes inactive when I select combo box on the toolbar. Diagramscene demo doesn't show this ability. Furthermore, in this demo the text item exits text editing mode when it looses focus thus loosing the text selection. I've tried to override focus in and focus out event handlers of the item but it didn't help. Should I reimplement some scene events (currently I only reimplement some items' and view's events and use the standard scene)? Can you point me to the working example?

wysota
23rd October 2009, 13:15
Mmm, well, I see... Do you mean that an item can be selected and not have focus at the same time? What should I do to achieve this?
Nothing. Selection and focus are two separate mechanisms controled by two different flags.


By default QGraphicsTextItem becomes inactive when I select combo box on the toolbar.
Because it loses focus and was never selected. If you select it, it will stay that way until you deselect it.


Diagramscene demo doesn't show this ability. Furthermore, in this demo the text item exits text editing mode when it looses focus thus loosing the text selection.
Was it ever selected?

olelukoie
23rd October 2009, 18:05
Was it ever selected?
Surely yes. Run diagramscene demo, create text item, enter some text, select some portion of this text and click inside the font size combo box. Text selection would be cleared (lost). My question is how to keep it so that formatting changes apply to selected text fragment only and not to the whole text of the item.

olelukoie
27th October 2009, 06:40
So can anybody help me or point to a working example?

wysota
27th October 2009, 09:56
We still haven't seen a minimal compilable example reproducing the problem :)

olelukoie
27th October 2009, 13:35
We still haven't seen a minimal compilable example reproducing the problem :)

"a minimal compilable example reproducing the problem" is a standard diagramscene example that comes with Qt4. I have already described the steps you can follow to see the problem with this example. See my previous reply.

Of course if you insist I can upload my own testing project but it's not 'minimal' by any means and besides is just a testing project so it doesn't have any good readable class hierarhy nor comments neither was created from the best programming practices POV. And it have a russian only UI and is not localizable for english support ;) . Do you wanna see it?

PS. I wanted to add links to several bugs in Qt's bugzilla that are important for me and relate to this project and found that the UI of bugzilla is completely changed and old bug report numbers do not fit it anymore. So I give you the old numbers I have: 138596, 206294, 221584. For example one of these bugs reported that QGraphicsTextItem could not align text by center or by right border and this ability is critical for the project I planned to work on. So if these bugs are still valid (not fixed, as they were marked several days ago) than it's completely useless to continue my studying of GV framework as I won't be able to create what I need.

wysota
27th October 2009, 14:36
"a minimal compilable example reproducing the problem" is a standard diagramscene example that comes with Qt4.
Not really. It works just fine :) You can see that the example works on the level of items, not its content.


I have already described the steps you can follow to see the problem with this example.
So be so kind and craft that compilable example reproducing the problem if you want me to devote my private time to help you.


Of course if you insist I can upload my own testing project but it's not 'minimal'
That won't do us (and you especially) any good. The point of a minimal compilable example is that you remove everything that might have influence on the outcome even if you don't think it should have any influence. Another point of a minimal compilable example is for you to think again about your problem. In most cases this is enough to solve a problem.


And it have a russian only UI and is not localizable for english support ;)
This is not a problem for me in particular.

Do you wanna see it?

Not really. I want to understand why don't you just store the selection and then apply your formatting on that selection. You're still confusing focus and selection... Only ONE item can have focus at the same time. If you want it to go to the editable combobox for changing the font size, the text item WILL lose it. The bright side is YOU DON'T NEED IT.

See QTextCursor::selectionStart() and QTextCursor::selectionEnd(). These have nothing to do with the focus. Also see QTextEdit::setExtraSelections() - if you want something similar for your item, just implement it.

olelukoie
27th October 2009, 17:15
Not really. I want to understand why don't you just store the selection and then apply your formatting on that selection. You're still confusing focus and selection... Only ONE item can have focus at the same time. If you want it to go to the editable combobox for changing the font size, the text item WILL lose it. The bright side is YOU DON'T NEED IT.

Seems like we don't understand each other. What I need is visual keeping the text selection inside QGraphicsTextItem while the focus is in the combobox on the toolbar. And this selection should be displayed in "active" colors. That's all I need. Remembering selected text in a string or remembering its starting and ending positions can be used internally but visual representation is absolutely necessary anyway. The user should see the selected text as selected while he changes font size or family. I can not get this behavior by reimplementing formatting slots using QTextCursor. As I've already mentioned in my first post here this approach works with simple buttons but doesn't work with combos that steal focus. Using NoFocus for the combos solves the problem with text selection visual representation but disables manual value change - combos become non-editable and it's not appropriate.

And my question was very simple: what should I implement/reimplemet/override or what option(s) I should use to get the desired visual effect of keeping text selection in a QGraphicsTextItem?

And if you still want to see some code, than this setFont method would be fully enough to format only selected text in diagramscene example, but it won't work for font family and size:

//! [4]
void DiagramScene::setFont(const QFont &font)
{
myFont = font;

if (isItemChange(DiagramTextItem::Type)) {
QGraphicsTextItem *item =
qgraphicsitem_cast<DiagramTextItem *>(selectedItems().first());
//At this point the selection can change so the first selected item might not be a DiagramTextItem
if (item)
{
QTextCursor cursor = item->textCursor();
QTextCharFormat fmt = cursor.charFormat(); // may be unnecessary assignment

fmt.setFont(font);

cursor.setCharFormat(fmt);
item->setTextCursor(cursor);
}
}
}
//! [4]

wysota
27th October 2009, 21:46
What I need is visual keeping the text selection inside QGraphicsTextItem while the focus is in the combobox on the toolbar.
I already told you how to do that - see ExtraSelection.


Remembering selected text in a string or remembering its starting and ending positions can be used internally but visual representation is absolutely necessary anyway.
So why don't you just draw it? You have all the data you need. It's either that or making sure the item doesn't lose focus (by making sure none of formatting tools can steal it from the item). You may also use a hybrid approach - let other tools steal the focus but once you're done with the tool, bring the focus back to the item and restore the selection.

olelukoie
28th October 2009, 08:15
I already told you how to do that - see ExtraSelection.
Wait, ExtraSelection is a "structure" in QTextEdit. According to the docs QGraphicsTextItem is not derivative of this class and there is no any mention about ExtraSelection members in its full members list. Is it the bug in the docs? Or you suggest me to implement this functionality by myself?

Another approach to solve the problem could be replacing QGraphicsTextItem with QTextEdit item using QGraphicsWidget. Are there any tutorials or working examples of using QTextEdit on the GV scene?

wysota
28th October 2009, 09:17
Wait, ExtraSelection is a "structure" in QTextEdit. According to the docs QGraphicsTextItem is not derivative of this class and there is no any mention about ExtraSelection members in its full members list. Is it the bug in the docs? Or you suggest me to implement this functionality by myself?

Yes, sometimes you actually have to implement something and not only use existing features.


Another approach to solve the problem could be replacing QGraphicsTextItem with QTextEdit item using QGraphicsWidget.
You could but then you'll get scrollbars and all that stuff you don't really need.

Are there any tutorials or working examples of using QTextEdit on the GV scene?

It doesn't differ in any way from using it outside a graphics scene.

olelukoie
28th October 2009, 15:06
You could but then you'll get scrollbars and all that stuff you don't really need.
As I can see the bug QTBUG-312 (http://bugreports.qt.nokia.com/browse/QTBUG-312) (old number is 138596) is not yet fixed so it seems like I do not have choice and have to use QTextEdit instead of QGraphicsTextItem. And scrollbars are not a problem if Qt::ScrollBarAlwaysOff works as intended.

Anyway thank you, I'll begin experimenting with QTextEdit...

BTW Do you have any information on plans on improving GV functionality in future Qt releases? Are there plans on extending QGraphicsTextItem and fixing its bugs (I have mentioned some of them earlier)?

wysota
29th October 2009, 09:49
And scrollbars are not a problem if Qt::ScrollBarAlwaysOff works as intended.
Unless there is more text that can fit into the widget in which case you will simply not see the rest.


BTW Do you have any information on plans on improving GV functionality in future Qt releases? Are there plans on extending QGraphicsTextItem and fixing its bugs (I have mentioned some of them earlier)?

Don't count on those bugs being fixed any time soon. As for graphics view, it's one of the most actively developed frameworks in Qt.