PDA

View Full Version : QGraphicsRectItem signal



kovacadam
30th September 2010, 20:12
Hello!

How can I use signals of QGraphicsRectItem?

I tried this:

m_rectangle = new QGraphicsRectItem( 0, 0, 40, 40 );
m_rectangle->setPen( QPen(Qt::black) );
m_rectangle->setBrush( QBrush( QColor( 0, 200, 0, 200 ) ) );

connect(m_rectangle, SIGNAL(MousePressEvent), this, SLOT(animate()));

but I get this:
no matching function for call to 'GraphicsViewDemo::connect(QGraphicsRectItem*&, const char*, GraphicsViewDemo* const, const char*)'

Lykurg
30th September 2010, 21:02
Where does a QGraphicsRectItem has a signal called MousePressEvent or any other signal at all? And items do not inherit QObject which is needed for connections.

So you have to do it yourself. Just create a custom item which inherits QObject.
class MyItem : public QObject, public QGraphicsRectItem

Urthas
30th September 2010, 21:33
That is one way to do it. :)

Or you could sidestep connections altogether and write a custom class that inherits from QGraphicsRectItem only, re-implementing mousePressEvent().

kovacadam
1st October 2010, 13:55
Sorry for my easy questions, but I'm new in qt. So if I have a class inherit QObject and QGraphicsRectItem why has it mousePressEvent signal? QObject and QGraphicsRectItem haven't mousePressEvent signal, have they?

qlands
1st October 2010, 14:19
Hi,

QGraphicsRectItem does not have a signal MousePressEvent. It has the protected function virtual void mousePressEvent ( QGraphicsSceneMouseEvent * event ).

If you want to emit a signal when mousePressEvent is called, then you need to subclass your m_rectangle from QObject and QGraphicsRectItem.

class MyItem : public QObject, public QGraphicsRectItem

For example:
myrectangle.h


#ifndef MYRECTANGLE_H
#define MYRECTANGLE_H

#include <QtGui>
#include <QGraphicsRectItem>

class myrectangle : public QObject, public QGraphicsRectItem
{
Q_OBJECT
public:
myrectangle();

signals:
void myPressSignal();
protected:
void mousePressEvent(QGraphicsSceneMouseEvent * event);
};

#endif // MYRECTANGLE_H


myrectangle.cpp


#include "myrectangle.h"

myrectangle::myrectangle()
{
}


void myrectangle::mousePressEvent(QGraphicsSceneMouseEv ent * event)
{
QGraphicsItem::mousePressEvent(event); //Call the ancertor

emit myPressSignal(); //Emits the signal
}

Lykurg
1st October 2010, 14:32
Sorry for my easy questions, but I'm new in qt.Then why don't you use the Newbie section? (-> moved)

Do you want only a "mouse click on item" signal or other signals as well. If you only need to be notified if a item was clicked then maybe following is a better solution than subclassing the item:
Make your items selectable and use QGraphicsScene::selectionChanged() to get notified.
Reimp QGraphicsScene::mousePressEvent() and detect the underlaying item with QGraphicsScene::itemAt().

kovacadam
1st October 2010, 14:40
Thank you. Now I have just one problem:
I created my QGraphicsRectItem int this way: m_rectangle = new QGraphicsRectItem( 0, 0, 40, 40 );
and I tried this in my class: QMyButton::QMyButton(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent) : QGraphicsRectItem(x, y, w, h, parent)
but I got this error: undefined reference to `QMyButton::QMyButton(float, float, float, float, QGraphicsItem*)'

Lykurg
1st October 2010, 14:42
Well you have to declare that constructor as well or use the standard constructor and set the geometry with a member method.

kovacadam
1st October 2010, 14:51
It's my qmybutton.h


#ifndef QMYBUTTON_H
#define QMYBUTTON_H

#include <QGraphicsRectItem>

class QMyButton : public QObject, public QGraphicsRectItem
{
Q_OBJECT
public:
QMyButton(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent = 0);

signals:
void myPressSignal();

protected:
void mousePressEvent(QGraphicsSceneMouseEvent * event);
};

#endif // QMYBUTTON_H


This line declare the constructor: QMyButton(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent = 0); ?
I already have this.

qlands
1st October 2010, 15:10
So the qmybutton.cpp should be something like:



QMyButton::QMyButton(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent)
{

}


void QMyButton::mousePressEvent(QGraphicsSceneMouseEven t * event)
{
QGraphicsItem::mousePressEvent(event); //Call the ancertor

emit myPressSignal(); //Emits the signal
}


Why do you need this constructor?

You can also have a simple constructor like: QMyButton();

then:


//Create the button
QMyButton mybutton = new QMyButton();
//Sets the rect
mybutton->setRect(0,0,100,100);
//Add it the scene.
myScene->addItem(mybutton);
//Or add it to a parent item:
mybutton->setParentItem(myParent);

Lykurg
1st October 2010, 15:11
Maybe you need to rerun qmake.

kovacadam
1st October 2010, 16:02
I know I can use simple constructor, but I used this constructor of QGraphicsRectItem: QGraphicsRectItem(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent = 0)
and I want create a constructor like: QMyButton::QMyButton(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent)
And I want to know why it doesn't work.

I use Qt Creator, so if I'm right qmake run ever when I build the project.

this is my qmybutton.h:

#ifndef QMYBUTTON_H
#define QMYBUTTON_H

#include <QGraphicsRectItem>

class QMyButton : public QObject, public QGraphicsRectItem
{
Q_OBJECT
public:
QMyButton();
QMyButton(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent = 0);

signals:
void myPressSignal();

protected:
void mousePressEvent(QGraphicsSceneMouseEvent * event);
};

#endif // QMYBUTTON_H


and this is my qmybutton.cpp:


#include "qmybutton.h"

QMyButton::QMyButton()
{
}

QMyButton::QMyButton(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent) :
QGraphicsRectItem(x, y, w, h, parent)
{
}

void QMyButton::mousePressEvent(QGraphicsSceneMouseEven t * event)
{
QGraphicsItem::mousePressEvent(event); //Call the ancertor

emit myPressSignal(); //Emits the signal
}

qlands
1st October 2010, 16:09
Can you provide the error message?

kovacadam
1st October 2010, 16:12
undefined reference to `QMyButton::QMyButton(float, float, float, float, QGraphicsItem*)'
In this file:


// Symbian Foundation Example Code
//
// This software is in the public domain. No copyright is claimed, and you
// may use it for any purpose without license from the Symbian Foundation.
// No warranty for any purpose is expressed or implied by the authors or
// the Symbian Foundation.
#include "graphicsviewdemo.h"

#include <QVBoxLayout>

#include <QPushButton>

#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsEllipseItem>
#include <QGraphicsRectItem>

#include <QGraphicsItemAnimation>
#include <QTimeLine>
#include <qmybutton.h>

GraphicsViewDemo::GraphicsViewDemo(QWidget *parent)
: QWidget(parent)
{
QVBoxLayout *layout = new QVBoxLayout( this );

QGraphicsView *view = new QGraphicsView();
view->setBackgroundBrush( QPixmap( ":/images/qt-tile.png" ) );
QPushButton *button = new QPushButton( tr("Animate") );

layout->addWidget( view );
layout->addWidget( button );

connect( button, SIGNAL(clicked()), this, SLOT(animate()) );

QGraphicsScene *scene = new QGraphicsScene( QRect( -50, -50, 100, 100 ) );
m_ellipse = new QGraphicsEllipseItem( 25, -10, 20, 20 );
m_ellipse->setPen( QPen(Qt::darkRed) );
m_ellipse->setBrush( Qt::red );

QMyButton *m_rectangle = new QMyButton( 0, 0, 40, 40 ); // <----------------------- In this line
m_rectangle->setPen( QPen(Qt::black) );
m_rectangle->setBrush( QBrush( QColor( 0, 200, 0, 200 ) ) );

scene->addItem( m_ellipse );
scene->addItem( m_rectangle );

connect(m_rectangle, SIGNAL(myPressSignal), this, SLOT(animate()));

view->setScene( scene );
}

void GraphicsViewDemo::animate()
{
QTimeLine *timeLine = new QTimeLine(3000);
timeLine->setFrameRange(0, 100);

QGraphicsItemAnimation *ellipseAnimation = new QGraphicsItemAnimation();
ellipseAnimation->setItem(m_ellipse);
ellipseAnimation->setTimeLine(timeLine);

/* QGraphicsItemAnimation *rectAnimation = new QGraphicsItemAnimation();
rectAnimation->setItem(m_rectangle);
rectAnimation->setTimeLine(timeLine);
rectAnimation->setPosAt(2, QPointF(30, 30));*/

for (int i = 0; i <= 200; ++i)
{
ellipseAnimation->setRotationAt( i/200.0, 360.0 * i/200.0 );
//rectAnimation->setRotationAt( i/200.0, -720.0 * i/200.0 );
qreal s = i>100?(1.0-((i-100)/100.0)):(i/100.0);
//rectAnimation->setScaleAt( i/200.0, 1.0+s, 1.0+s );
}

connect( timeLine, SIGNAL(finished()), timeLine, SLOT(deleteLater()) );
connect( timeLine, SIGNAL(finished()), ellipseAnimation, SLOT(deleteLater()) );
//connect( timeLine, SIGNAL(finished()), rectAnimation, SLOT(deleteLater()) );

timeLine->start();
}

qlands
1st October 2010, 16:16
Try and see if using local includes fix the error:

#include "qmybutton.h"