PDA

View Full Version : Custom QGraphicsRectItem with size grip



Bill
20th July 2009, 11:52
Hi all,
I know that this topic has been covered in a couple of threads, so sorry for repeating, but...

I'm trying to draw a size grip on my rectangles (class inherits from QGraphicsRectItem). I found this post: http://www.qtcentre.org/forum/f-newbie-4/t-qgraphicsitem-with-qsizegrip-6461-post33791.html and tried to do it in my reimplemented paint() method:


void MyRectangle::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
QCommonStyle q;
q.drawControl(QStyle::CE_SizeGrip, option, painter, widget);
QGraphicsRectItem::paint(painter, option, widget);
}

But the only result I get is a lot of artefacts on the screen and not a proper grip in the (I presume) bottom right corner.

Did any one succeed in implementing this? Would really appreciate your help.
TIA,
Regards,
Bill

wysota
20th July 2009, 13:47
First of all you can't just create a new style object, use the one that's already there. Second of all you need to setup the option object you pass to drawControl. What it expects is surely different from what paint() receives from QGraphicsView.

Bill
20th July 2009, 14:46
Hi,
Thanks for the reply. I'm still a bit puzzled. To use the drawControl() method I need an object of class QStyle. QStyleOptionGraphicsItem (as I understand from the manual) is rather a structure for settings used by QStyle; it doesn't have the needed method.
Could you please provide more detail?

Thank you very much,
Regards,
Bill

wysota
20th July 2009, 15:10
QApplication::style() will return you the current style. As for the options object, you need to fill it out correctly. Looking at QSizeGrip code may be helpful.

Bill
22nd July 2009, 17:18
Hi,
I'm still trying to draw the resize grip on my custom rectangles, without any luck. Please find attached the header file and source code of my class with an image of the effects of the implementation... Maybe you will spot an error.

I will appreciate any help.
Regards,
Bill

The MyRectangle.h file:

#ifndef __MYRECTANGLE_H__
#define __MYRECTANGLE_H__

#include <QGraphicsRectItem>

class QPen;
class QStyleOptionGraphicsItem;
class QStyleOptionSizeGrip;
class QPainter;

class MyRectangle : public QGraphicsRectItem
{
public:
MyRectangle(const QRectF &rect, QGraphicsItem *parent = 0);
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);

private:
QPen pen;
};

#endif

The MyRectangle.cpp file:

#include <QPen>
#include <QStyleOptionGraphicsItem>
#include <QStyleOptionSizeGrip>
#include <QPainter>
#include "myrectangle.h"

MyRectangle::MyRectangle(const QRectF &rect, QGraphicsItem *parent)
: QGraphicsRectItem(rect,parent)
{
setFlags(ItemIsMovable|ItemIsSelectable);
}

void MyRectangle::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
QStyleOptionSizeGrip opt;
opt.corner = Qt::BottomRightCorner;
opt.rect = boundingRect().toRect();
pen.setStyle(Qt::SolidLine);
pen.setColor(QColor(Qt::black));
pen.setWidth(1);
if(option->state & QStyle::State_Selected)
{
pen.setStyle(Qt::DashLine);
pen.setColor(QColor(Qt::green));
}
painter->setPen(pen);
painter->drawRect(this->boundingRect());
widget->style()->drawControl(QStyle::CE_SizeGrip, &opt, painter);
}

wysota
22nd July 2009, 19:45
I don't think setting corner and rect is enough. Did you look into QSizeGrip source code? You need to do whatever QStyleOption::init() does. You need to set (proper!) rect, corner, direction and palette, At least that's what CommonStyle uses for drawing the size grip.

Bill
23rd July 2009, 10:55
Hi,
Thanks for the help - yes, I had a look at the source of QStyleOption and QSizeGrip... In QStyleOption the init() method gets the different style settings from a widget (rect, direction, font metrics etc.). I also tried adding the QWidget as base class to MyRectangle, but it didn't change anything...



void MyRectangle::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
{
QStyleOptionSizeGrip opt;
opt.corner = Qt::BottomLeftCorner;
opt.rect = boundingRect().toRect();
opt.direction = QApplication::layoutDirection();
opt.palette = QApplication::palette();
opt.fontMetrics = QApplication::fontMetrics();
opt.state = option->state;
pen.setStyle(Qt::SolidLine);
pen.setColor(QColor(Qt::black));
pen.setWidth(1);
if(option->state & QStyle::State_Selected)
{
pen.setStyle(Qt::DashLine);
pen.setColor(QColor(Qt::green));
}
painter->setPen(pen);
QApplication::style()->drawControl(QStyle::CE_SizeGrip, &opt, painter);
painter->drawRect(this->boundingRect());
}


As you see I'm taking the settings from QApplication. The only problem is with the bounding rectangle. MyRectangles are created with another QGraphicsPixmapItem as a parent (rectangles on an image). The size grip tends to begin inside every rectangle and finish at the top of the parent image... There must be something wrong with the coordinates...

If you have any other suggestions, please reply.
Any help appreciated.

Regards,
Bill

Bill
23rd July 2009, 13:43
Ok,
I can consider this topic closed... I found here http://www.qtcentre.org/forum/f-qt-programming-2/t-drawing-and-resizing-shapes-18238.html exactly what I needed
Still - if someone finds a way to draw the QSizeGrip on QGraphicItems - I will be more than happy and grateful to know the solution.

Cheers,
Bill