PDA

View Full Version : QGraphicsRectItem with list of QStrings



January
23rd April 2012, 22:34
Hi,
I want to make a class which will represent single entity in entity relationship diagram.
It should be an rect object with name and attributes which will adjust it's size to the text it is containing.
Because of that I am new to qt I started to play with qt doc and intuition which have led me to something like this:


class Entity : public QObject, public QGraphicsRectItem {
Q_OBJECT;

public:
Entity(QGraphicsItem *parent = 0);

void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget = 0);
void setName(QString name);
void addField(QString field);

private:
void adjustRect();

QString name;
QList<QString> fields;


};

Entity::Entity(QGraphicsItem *parent)
: QGraphicsRectItem(parent)
{
setFlag(QGraphicsItem::ItemIsMovable);
setFlag(QGraphicsItem::ItemIsSelectable);
}

void Entity::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
painter->setPen(Qt::black);
painter->setBrush(QColor(230,230,230));
painter->drawRect(rect());

QPointF pos = QPointF(rect().x() + 10, rect().y() + 20);
painter->drawText(pos, name);

qDebug() << rect().width();

painter->drawLine(pos.x() - 10, pos.y() + 5, pos.x() + rect().width() - 10, pos.y()+5);

QString str;
foreach(str, fields) {
pos.setY(pos.y() + 20);
painter->drawText(pos, str);
}

}

void Entity::setName(QString name)
{
this->name = name;
adjustRect();
}

void Entity::addField(QString field)
{
fields.append(field);
adjustRect();
}

void Entity::adjustRect()
{
qreal maxx = 20;

maxx = (maxx < name.length()*10 ? name.length()*10 : maxx);

QString str;
foreach(str, fields) {
maxx = (maxx < str.length()*10 ? str.length()*10 : maxx);
}

setRect(rect().x(), rect().y(), maxx, fields.count()*30 + 10);
}

It even works but it seems weird to me and I know there is better solution. Can you point me what am I doing wrong and where should I look for (classes, etc.).

I also don't know why entities are not selectable despite the fact I set the flag to ItemIsSelectable.

qlands
24th April 2012, 14:16
Hi,

QGraphic items are drawn in a scene. An and scene is displayed in a QGraphicsView. If you want is draw entities in a relationship diagram you can draw all the fields inside a rectangle... But I would encourage you to look at ProxyWidget. With it, you can have a widgets like listviews to be draw in a scene. You can create a widget to handle your entities as complex as needed and QT will draw it in the scene. You can embed a proxywidget inside a QGraphicsRectItem by setting the parent of proxy = the rectangle.

For now, from your example, I reckon you don't need to re-implement the paint event.

I can post an example if you need.

Carlos

January
24th April 2012, 16:02
Hi Carlos,

Thanks for reply


I can post an example if you need.

I would be grateful if you did.

qlands
24th April 2012, 16:52
Hi,

You can download the example from here:

http://www.qlands.com/other_files/scenexample.tar.gz

I documented the example. You will see that I used a container to embed the proxy widget. I use a container because then you can easily use free transformations in the container (size/rotate) and the proxy will react accordingly. See example on free mouse transformations here:

http://qt-apps.org/content/show.php/At+will+transformations+example?content=133531

Carlos. :)

January
24th April 2012, 20:04
Thanks for your example. I was rather thinking of simple graphics objects to be entities not complex ones but it really helped me.
I even figured out how to make an application using a designer :)
Thank you again.