PDA

View Full Version : how to arrange item of QGraphicsScene inside QGraphicsView



saman_artorious
6th August 2012, 16:17
hi
I want to have 14 rectangles, 2 in each row inside every QGraphicsView. I tried to follow the 4000 chips example, it is nice. I tried to draw two rectangles with background images inside QGraphicsView. But, the problem I have is that I cannot arrange the position of the rectangles inside the view at all. If anyone worked with QGraphicsView could tell me how to add 14 medium sized rectangles inside the view...

this is how I added the two rectangles inside the view:

void MainWindow::populateScene()
{
scene = new QGraphicsScene;

QImage image("");//:/dolphin.png

// Populate scene
int xx = 0;
int nitems = 0;
// for (int i = -11000; i < 11000; i += 110) {
// ++xx;
// int yy = 0;
// for (int j = -7000; j < 7000; j += 70) {
// ++yy;
// qreal x = (i + 11000) / 22000.0;
// qreal y = (j + 7000) / 14000.0;

QColor color(image.pixel(int(image.width() * 1), int(image.height() * 1)));
// QGraphicsItem *item = new Chip(color, xx, yy);
// item->setPos(QPointF(i, j));


QGraphicsItem *item = new Chip(color, 0, 1);
QGraphicsItem *item2 = new Chip(color, 0, 2);

item->setPos(QPointF(-300,0));
item2->setPos(QPointF(100, 100));
scene->addItem(item);

scene->addItem(item2);
++nitems;
// }
// }
}



/************************************************** **************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the demonstration applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
************************************************** **************************/

#include "chip.h"

#include <QtGui>

Chip::Chip(const QColor &color, int x, int y)
{
this->x = x;
this->y = y;
this->color = color;
setZValue((x + y) % 2);

setFlags(ItemIsSelectable | ItemIsMovable);
setAcceptsHoverEvents(true);
}

QRectF Chip::boundingRect() const
{
return QRectF(0, 0, 110, 70);
}

QPainterPath Chip::shape() const
{
QPainterPath path;
path.addRect(14, 14, 82, 42);
return path;
}

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

QColor fillColor = (option->state & QStyle::State_Selected) ? color.dark(150) : color;
if (option->state & QStyle::State_MouseOver)
fillColor = fillColor.light(125);

const qreal lod = option->levelOfDetailFromTransform(painter->worldTransform());
if (lod < 0.2) {
if (lod < 0.125) {
painter->fillRect(QRectF(0, 0, 110, 70), fillColor);
return;
}

QBrush b = painter->brush();
painter->setBrush(fillColor);
painter->drawRect(13, 13, 97, 57);
painter->setBrush(b);
return;
}

QPen oldPen = painter->pen();
QPen pen = oldPen;
int width = 0;
if (option->state & QStyle::State_Selected)
width += 2;

pen.setWidth(width);
QBrush b = painter->brush();
painter->setBrush(QBrush(fillColor.dark(option->state & QStyle::State_Sunken ? 120 : 100)));

// painter->drawRect(QRect(14, 14, 79, 39));
// painter->drawRect(QRect(0, 0, 200, 200));

//painter->setBrush(b);

//QRect rect(14, 14, 79, 39);
QRect rect(0, 0, 150, 150);
painter->drawRect(rect);

QImage image = QImage("dolphin.png", 0);
painter->drawImage(rect, image);

if (lod >= 1) {
// painter->setPen(QPen(Qt::gray, 1));
// painter->drawLine(15, 54, 94, 54);
// painter->drawLine(94, 53, 94, 15);
// painter->setPen(QPen(Qt::black, 0));
}

// Draw text
if (lod >= 2) {
// QFont font("Times", 10);
// font.setStyleStrategy(QFont::ForceOutline);
// painter->setFont(font);
// painter->save();
// painter->scale(0.1, 0.1);
// painter->drawText(170, 180, QString("Model: VSC-2000 (Very Small Chip) at %1x%2").arg(x).arg(y));
// painter->drawText(170, 200, QString("Serial number: DLWR-WEER-123L-ZZ33-SDSJ"));
// painter->drawText(170, 220, QString("Manufacturer: Chip Manufacturer"));
// painter->restore();
}

// Draw lines
QVarLengthArray<QLineF, 36> lines;
if (lod >= 0.5) {
// for (int i = 0; i <= 10; i += (lod > 0.5 ? 1 : 2)) {
// lines.append(QLineF(18 + 7 * i, 13, 18 + 7 * i, 5));
// lines.append(QLineF(18 + 7 * i, 54, 18 + 7 * i, 62));
// }
// for (int i = 0; i <= 6; i += (lod > 0.5 ? 1 : 2)) {
// lines.append(QLineF(5, 18 + i * 5, 13, 18 + i * 5));
// lines.append(QLineF(94, 18 + i * 5, 102, 18 + i * 5));
// }
}
if (lod >= 0.4) {
// const QLineF lineData[] = {
// QLineF(25, 35, 35, 35),
// QLineF(35, 30, 35, 40),
// QLineF(35, 30, 45, 35),
// QLineF(35, 40, 45, 35),
// QLineF(45, 30, 45, 40),
// QLineF(45, 35, 55, 35)
// };
// lines.append(lineData, 6);
}
// painter->drawLines(lines.data(), lines.size());

// Draw red ink
if (stuff.size() > 1) {
// QPen p = painter->pen();
// painter->setPen(QPen(Qt::red, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
// painter->setBrush(Qt::NoBrush);
// QPainterPath path;
// path.moveTo(stuff.first());
// for (int i = 1; i < stuff.size(); ++i)
// path.lineTo(stuff.at(i));
// painter->drawPath(path);
// painter->setPen(p);
}
}

void Chip::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
QGraphicsItem::mousePressEvent(event);
update();
}

void Chip::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
if (event->modifiers() & Qt::ShiftModifier) {
stuff << event->pos();
update();
return;
}
QGraphicsItem::mouseMoveEvent(event);
}

void Chip::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
QGraphicsItem::mouseReleaseEvent(event);
update();
}

d_stranz
6th August 2012, 22:48
You haven't shown enough code to understand what you are doing wrong.

Instead of hacking up the Chip code, you should start by simply inserting a QGraphicsRectItem into a scene and trying to move it to different positions:



int main(int argc, char **argv)
{
QApplication app(argc, argv);

QMainWindow mainWin;
QGraphicsView * view = new QGraphicsView;
mainWin.setCentralWidget( view );

QGraphicsRectItem * pItem1 = new QGraphicsRectItem();
pItem1->setRect( QRectF( 0, 0, 50, 50 ) );
pItem1->setPos( 25, 25 );
pItem1->setBrush( QBrush( Qt::red ) );

QGraphicsRectItem * pItem2 = new QGraphicsRectItem();
pItem2->setRect( QRectF( 0, 0, 75, 75 ) );
pItem2->setPos( 50, 50 );
pItem2->setPen( QPen( Qt::blue ) );

QGraphicsScene scene;
scene.addItem( pItem1 );
scene.addItem( pItem2 );

view->setScene( &scene );

mainWin.show();
return app.exec();
}


Added after 24 minutes:

Here is a little bit more complex an example. It shows how to use the z-values to put one object on top of another:



int main(int argc, char **argv)
{
QApplication app(argc, argv);

QMainWindow mainWin;
QGraphicsView * view = new QGraphicsView;
mainWin.setCentralWidget( view );

QGraphicsScene scene;
for ( int i = 0; i < 7; ++i )
{
QGraphicsRectItem * pItem1 = new QGraphicsRectItem( 0, 0, 25, 25 );
pItem1->setPos( 0, i * 50 );
pItem1->setBrush( Qt::red );
pItem1->setZValue( 10 );

QGraphicsRectItem * pItem2 = new QGraphicsRectItem( 0, 0, 25, 25 );
pItem2->setPos( 100, i * 50 );
pItem2->setBrush( Qt::yellow );
pItem2->setZValue( 0 );

scene.addItem( pItem1 );
scene.addItem( pItem2 );

// Connect item1 and item2 with a line
QGraphicsItem * pLine = scene.addLine(
QLineF( pItem1->mapToScene( pItem1->boundingRect().center() ),
pItem2->mapToScene( pItem2->boundingRect().center() ) ) );
pLine->setZValue( 5 );
}

view->setScene( &scene );

mainWin.show();
return app.exec();
}


Notice that the z-value for the left (red) rect is higher than that of the right (yellow) rect, and the z-value for the line is between the two. So, as expected, the line is hidden under the left rectangle, while it is painted on top of the right rectangle.

saman_artorious
7th August 2012, 08:53
thanks, that was so helpful! I created 13 rectangles, but, you know, there is a margin on the left n right side of the screen!
I tried removing it, but it doesn't change anything. as it starts adding the rectangle from the center.



QApplication app(argc, argv);

QMainWindow mainWin;
QGraphicsView * view = new QGraphicsView;
mainWin.setCentralWidget( view );

QGraphicsScene scene;

for ( int i = 0; i < 5; ++i )
{
QGraphicsRectItem * pItem1 = new QGraphicsRectItem( -1500, 5, 500, 200 );
pItem1->setPos( 0, i * 205 );
pItem1->setBrush( Qt::red );
pItem1->setZValue( 10 );


QGraphicsRectItem * pItem2 = new QGraphicsRectItem( -1500, 5, 500, 200 );
pItem2->setPos( 505, i * 205);
pItem2->setBrush( Qt::yellow );
pItem2->setZValue( 0 );


if( i < 3 )
{
QGraphicsRectItem * pItem3 = new QGraphicsRectItem( -1500, 5, 500, 200 );
pItem3->setPos( 1010, i * 205);
pItem3->setBrush( Qt::green);
pItem3->setZValue( 0 );

scene.addItem( pItem3 );
}

scene.addItem( pItem1 );
scene.addItem( pItem2 );


// Connect item1 and item2 with a line

// QGraphicsItem * pLine = scene.addLine(
// QLineF( pItem1->mapToScene( pItem1->boundingRect().center() ),
// pItem2->mapToScene( pItem2->boundingRect().center() ) ) );
// pLine->setZValue( 5 );
}

view->setScene( &scene );

mainWin.show();
return app.exec();


besides I tried to add a background image for each of the created rectangle, but it QGraphicsRectItem doesn not have the drawImage method. However, I added this to the Chip example to set the background images:


QImage image("BildgeSystem.png");
QRect rect(14, 14, 79, 39);

painter->drawImage (rect, image);


you know, I need to load a background image on each rectangle and add many svg switches n keys to it. I have never done that before, Could anyone explain this to me a bit. tnx : )

d_stranz
7th August 2012, 18:53
thanks, that was so helpful! I created 13 rectangles, but, you know, there is a margin on the left n right side of the screen!
I tried removing it, but it doesn't change anything. as it starts adding the rectangle from the center.

The view always centers the scene inside its viewport. You can change the location of the scene in the viewport by calling QGraphicsView::setAlignment() or by calling QGraphicsView::centerOn(). If you want the scene to grow or shrink according to the size of the view window, you can use QGraphicsView::fitInView() and pass the QGraphicsScene::sceneRect() as the argument.

I will modify my example to show you how to draw an image into the rectangle. I am not at my office computer now, so I will do it later.

saman_artorious
8th August 2012, 06:43
you know, I need to add some gauge, keys, or. . in other words add some embeded widget n svg-s to each rectangle particular background png image. I would thank if anyone could introduce some tutorial or show some sample code which does so.

d_stranz
8th August 2012, 17:48
OK, here's another example. I have derived a new class from QGraphicsPixmapItem. This class draws the pixmap, then draws more graphics (a rect and an ellipse) on top of the pixmap. If you need to use an SVG file instead of a pixmap, then derive a class from QGraphicsSvgItem instead. You will need the attached BMP file in order to build the application as I have posted it here.



#include <QtGui/QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsRectItem>
#include <QMainWindow>
#include <QPixmap>
#include <QGraphicsPixmapItem>

class ImageRectItem : public QGraphicsPixmapItem
{
public:
ImageRectItem( QGraphicsItem * pParent = 0 )
: QGraphicsPixmapItem( pParent )
{}

ImageRectItem( const QPixmap & pixmap, QGraphicsItem * pParent = 0 )
: QGraphicsPixmapItem( pixmap, pParent )
{}

public:
QRectF boundingRect() const
{
QRectF bounds( QGraphicsPixmapItem::boundingRect() );
QRectF trans = bounds.translated( -bounds.center().x(), -bounds.center().y() );
return trans;
}

QPainterPath shape() const
{
QPainterPath path;
path.addRect( boundingRect() );
return path;
}

void paint( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0 )
{
// Call the base class to draw the pixmap
QGraphicsPixmapItem::paint( painter, option, widget );

// Now draw some graphics on top of that
QRectF rect = QGraphicsPixmapItem::boundingRect();

QPen pen( Qt::red );
pen.setWidth( 4 );
painter->setPen( pen );
painter->drawRect( rect );

painter->setBrush( QBrush( Qt::blue ) );
painter->drawEllipse( rect.center(), 10, 10 );
}
};

int main(int argc, char **argv)
{
QApplication app(argc, argv);

QPixmap pixMap( "MadMagazine.bmp" );
QMainWindow mainWin;
QGraphicsView * view = new QGraphicsView;
mainWin.setCentralWidget( view );

QGraphicsScene scene;
qreal x = 50.0;
for ( int i = 0; i < 7; ++i )
{
ImageRectItem * pItem1 = new ImageRectItem( pixMap );
pItem1->setPos( -pixMap.width() - x, i * ( 10 + pixMap.height() ) );
pItem1->setZValue( 10 );

QGraphicsRectItem * pItem2 = new QGraphicsRectItem( 0, 0, 25, 25 );
pItem2->setPos( pixMap.width() + x, i * pixMap.height() );
pItem2->setBrush( Qt::yellow );
pItem2->setZValue( 0 );

scene.addItem( pItem1 );
scene.addItem( pItem2 );

// Connect item1 and item2 with a line
QGraphicsItem * pLine = scene.addLine(
QLineF( pItem1->mapToScene( pItem1->boundingRect().center() ),
pItem2->mapToScene( pItem2->boundingRect().center() ) ) );
pLine->setZValue( 5 );

x += 10.0;
}

view->setScene( &scene );

mainWin.show();
return app.exec();
}



Bitmap file: 8108