PDA

View Full Version : Painting selection grips for a QGraphicsRectItem



blooglet
1st April 2011, 16:50
I want to paint selection grips on a QGraphicsRectItem. Currently, I do this by overriding the paint event.

http://i.imgur.com/s1y2u.png


void GraphicNode::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
drawShape(painter);

if (this->isSelected())
drawSelectionGrips(painter);

if (this->associatedNode)
drawLabel(painter);
}

void GraphicNode::drawSelectionGrips(QPainter *painter) {
painter->setPen(Qt::SolidLine);
painter->setPen(Qt::black);
painter->setBrush(Qt::black);

painter->drawRect(this->boundingRect().x(), this->boundingRect().y(), GRIPSIZE, GRIPSIZE);

int topRightX = this->boundingRect().x() + this->boundingRect().width() - GRIPSIZE - SHADOWSIZE;
painter->drawRect(topRightX, this->boundingRect().y(), GRIPSIZE, GRIPSIZE);

int bottomLeftY = this->boundingRect().y() + this->boundingRect().height() - GRIPSIZE - SHADOWSIZE;
painter->drawRect(this->boundingRect().x(), bottomLeftY, GRIPSIZE, GRIPSIZE);

int bottomRightX = this->boundingRect().x() + this->boundingRect().width() - SHADOWSIZE;
int bottomRightY = this->boundingRect().y() + this->boundingRect().height() - SHADOWSIZE;
painter->drawRect(bottomRightX - GRIPSIZE, bottomRightY - GRIPSIZE, GRIPSIZE, GRIPSIZE);

painter->setPen(Qt::DotLine);
painter->setBrush(Qt::transparent);
painter->drawRect(this->boundingRect().x(), this->boundingRect().y(), this->boundingRect().width() - SHADOWSIZE, this->boundingRect().height() - SHADOWSIZE);
}

I want the cursor to change when the user hovers over the selection grips, so I was thinking I'd convert them into four QGraphicsRectItems and use setCursor to modify the cursor.

In the constructor:

this->topLeftGrip = new QGraphicsRectItem();
this->topLeftGrip->setCursor(Qt::SizeFDiagCursor);
this->topLeftGrip->setPen(QPen(Qt::black));
this->topLeftGrip->setBrush(QBrush(Qt::black));
this->topRightGrip = new QGraphicsRectItem();
this->topRightGrip->setCursor(Qt::SizeBDiagCursor);
this->topRightGrip->setPen(QPen(Qt::black));
this->topRightGrip->setBrush(QBrush(Qt::black));
this->bottomLeftGrip = new QGraphicsRectItem();
this->bottomLeftGrip->setCursor(Qt::SizeFDiagCursor);
this->bottomLeftGrip->setPen(QPen(Qt::black));
this->bottomLeftGrip->setBrush(QBrush(Qt::black));
this->bottomRightGrip = new QGraphicsRectItem();
this->bottomRightGrip->setCursor(Qt::SizeBDiagCursor);
this->bottomRightGrip->setPen(QPen(Qt::black));
this->bottomRightGrip->setBrush(QBrush(Qt::black));

In the selection drawing function:

this->topLeftGrip->setRect(this->boundingRect().x(), this->boundingRect().y(), GRIPSIZE, GRIPSIZE);
this->topLeftGrip->setVisible(true);

int topRightX = this->boundingRect().x() + this->boundingRect().width();
this->topRightGrip->setRect(topRightX, this->boundingRect().y(), GRIPSIZE, GRIPSIZE);
this->topRightGrip->setVisible(true);

int bottomLeftY = this->boundingRect().y() + this->boundingRect().height() - GRIPSIZE - SHADOWSIZE;
this->bottomLeftGrip->setRect(this->boundingRect().x(), bottomLeftY, GRIPSIZE, GRIPSIZE);
this->bottomLeftGrip->setVisible(true);

int bottomRightX = this->boundingRect().x() + this->boundingRect().width() - SHADOWSIZE;
int bottomRightY = this->boundingRect().y() + this->boundingRect().height() - SHADOWSIZE;
this->bottomRightGrip->setRect(bottomRightX - GRIPSIZE, bottomRightY - GRIPSIZE, GRIPSIZE, GRIPSIZE);
this->bottomRightGrip->setVisible(true);

I don't see any selection grips when I use the QGraphicsRectItem approach. Did I forget something important? Is there a better way to draw the selection grips? (Keep in mind that my object also uses drop shadow, so I may not be able to use Qt's built-in selection features.)

JohannesMunk
1st April 2011, 19:58
Why don't you change the mouse cursor of your item in its hoverMoveEvent when the cursor is over one of the grips?

In order to recieve mouseMoveEvents without a pressed button you will need to activate mousetracking (http://doc.qt.nokia.com/latest/qwidget.html#mouseTracking-prop)on the view and setAcceptHoverEvents(true) on the item.

HIH

Johannes