qtrich-text-editorqgraphicsitemqgraphicstextitemqtextcursor

How to continue text editing after formatting changes of QGraphicsTextItem?


I am trying to make changes (font changes) to a QGraphicsTextItem that is editable.
I am trying to change formatting of fragments of text, or the formatting applied at typing point (if I set text bold, the text I type after that action at cursor position would be bold).

Setting formatting for text fragments works - but I can't find a way to return the focus correctly to the item.
I can show the caret at the right position, but I can't type in the box unless I actually click in box (even though it seems hat I should be able to).

Simple sample (for some reason it crashes on closing program but I don't care about that since I am testing the text class, not the main program):

header: mytextitem.h

#include <QGraphicsTextItem>

class MyTextItem : public QGraphicsTextItem
{
Q_OBJECT
public:
    MyTextItem();
    ~MyTextItem() {}
public slots:
    void setItemBold(const int b);
};

mytextitem.cpp

#include "mytextitem.h"
#include <QTextCursor>

MyTextItem::MyTextItem()
{
    setPlainText("ABCD");
    setFont(QFont("Arial", 20));
    setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsFocusable);
    setTextInteractionFlags(Qt::TextEditorInteraction);
}
void MyTextItem::setItemBold(const int b)
{
    int _weight = (b != 0) ? QFont::Bold : QFont::Normal;
    QTextCursor _cursor = textCursor();
    //int p = _cursor.position();     // this won't help
    QTextCharFormat _format = _cursor.charFormat();
    _format.setFontWeight(_weight);
    _cursor.setCharFormat(_format);
    //_cursor.setPosition(p, QTextCursor::KeepAnchor);  // makes no difference on allowing me to type, but I can make the cursor move
    //_cursor.movePosition(QTextCursor::NoMove, QTextCursor::KeepAnchor, 0); // makes no difference but I just thought some action might
    setTextCursor(_cursor);
    setFocus(Qt::MouseFocusReason);
    // grabKeyboard();  // does nothing
}

main.cpp

#include <QApplication>
#include <QGraphicsView>
#include <QGridLayout>
#include <QtWidgets>
#include <QCheckBox>
#include "mytextitem.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QGraphicsScene scene(-20, -20, 150, 100);
    QGraphicsView view(&scene);
    QWidget widget;
    QGridLayout layout(&widget);
    layout.addWidget(&view, 0, 0);
    QCheckBox bold("Bold");
    layout.addWidget(&bold, 0, 1);
    MyTextItem* item = new MyTextItem();
    scene.addItem(item);
    QObject::connect(&bold, SIGNAL(stateChanged(int)), item, SLOT(setItemBold(int)));
    view.ensureVisible(scene.sceneRect());
    widget.show();
    return a.exec();
}

Editing the item is possible only if clicking in the box.

Assuming that I am already in the box (editing), and I push the "Bold" checkbox, I expect to be able to continue editing - type in the box - but even though I try to

nothing seems to return me to the box so I continue typing (with the new font setting).

How can I get the QTextCursor or anything else to allow me to keep editing the text ?


Solution

  • You need to focus on QGraphicsView after format change. You can't focus on QGraphicsTextItem because it isn't QWidget.