Thalia
Thalia

Reputation: 14615

Editing text - how can I change cursor position?

I have a TextItem inheriting QGraphicsTextItem. I am trying to get it to work based on specific requirements (center of transformations being center of bounding rectangle).

Since using QGraphicsTextItem::paint() gives me a little trouble (see this question) and also because I will need special wrapping possibly, it would be ideal to draw text in paint.

 #include <QApplication>
#include <QPainter>
#include <QGraphicsItem>
#include <QGraphicsView>

class TextItem: public QGraphicsTextItem
{
public:
    TextItem()
    {
        QFont f;
        f.setPointSize(50);
        f.setBold(true);
        f.setFamily("Helvetica");
        setFont(f);
        setHtml("Caf&#x00e9; Frap&#x00e9;");
        setFlags(QGraphicsItem::ItemIsMovable    |
                 QGraphicsItem::ItemIsFocusable  |
                 QGraphicsItem::ItemIsSelectable);
        setTextInteractionFlags(Qt::NoTextInteraction);
    }

    void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
    {
        qreal w = QGraphicsTextItem::boundingRect().width();
        qreal h = QGraphicsTextItem::boundingRect().height();
        QRectF r = QRectF(-w/2, -h/2, w, h);
        painter->setPen(QPen(m_penColor));
        painter->setFont(this->font());
        painter->setBrush(Qt::NoBrush);

        painter->drawText(r, this->toPlainText(), this->document()->defaultTextOption());
    }

    QRectF boundingRect() const
    {
        qreal w = QGraphicsTextItem::boundingRect().width();
        qreal h = QGraphicsTextItem::boundingRect().height();
        QRectF r = QRectF(-w/2, -h/2, w, h);
        return r;
    }

protected:
    virtual void focusOutEvent (QFocusEvent * event)
    {
        Q_UNUSED(event);
        setTextInteractionFlags(Qt::NoTextInteraction);
    }
    virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent * event)
    {
        Q_UNUSED(event);
        setTextInteractionFlags(Qt::TextEditorInteraction); 
        setFocus();
    }
};

int main(int argc, char *argv[])
{
    QApplication  a(argc, argv);
    TextItem* t = new TextItem();
    QGraphicsView view(new QGraphicsScene(-200, -150, 400, 300) );
    view.scene()->addItem(t);
    view.show();
    return a.exec();
}

This works in drawing text with desired options, but I am unable to edit properly - the text cursor is always at the beginning of the text block.

How can I move text cursor ? Is it possible to attach it to the paint ?

Upvotes: 0

Views: 2384

Answers (1)

Robert
Robert

Reputation: 807

You first need to enable editing for the item like this:

setTextInteractionFlags(Qt::TextEditable);

You can then get the text cursor using the textCursor() function from QGraphicsTextItem and set it to any position u want, e.g.:

auto cursor = textCursor();
cursor.movePosition(QTextCursor::End);
setTextCursor(cursor);

Update:

To edit based on the position of a double-click, you can reimplement the mouseDoubleClickEvent of QGraphicsTextItem like this:

void TextItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event)
{
    if (textInteractionFlags() == Qt::NoTextInteraction)
    {
        setTextInteractionFlags(Qt::TextEditable);
        setFocus();
    }

// ensure that when enabling the edit mode, the cursor is in an appropriate position (close to where the double-click happened)
    auto p = document()->documentLayout()->hitTest(event->pos(), Qt::FuzzyHit);
    auto cursor = textCursor();
    cursor.setPosition(p);
    setTextCursor(cursor);

    QGraphicsTextItem::mouseDoubleClickEvent(event);
}

Upvotes: 2

Related Questions