PDA

View Full Version : Transform(move) Circle starting point - it needs to rotate and stay fixed



petar
11th November 2009, 08:41
hi, i'm new to QT (ofcourse): i have a problem and don't know if it is the right aproach.


In short: I just want the circle to rotate and stay fixed - instead of dancing

I have a Qmainwindow, in the middle there is a graphicview, on the scene there is a circle divided in 4 pieces (2 lines) and a button "rotate". So i need the circle to rotate when you push the button.

Because i don't know yet how to deal with time (e.g. rotating the circle for N seconds) i rotate it for 30 degrees. The problem is that i need the circle to be fixed and the starting point to be in the middle of the circle, so that when i push the button it rotates around his own axis. I hope you understand what i mean.
Now it's rotating around the default starging point (0,0) i upper left corner of my BoundingRect so the circle isn't fixed but rather it rotates all over the view around the default (0,0) instead of staying fixed and rotating on place.

Here is a picture what i mean:

http://lookpic.com/i/458/sLrZpv4v.jpeg (http://lookpic.com/i/458/sLrZpv4v.jpeg)

I think i need to transform the default starting point (0,0) of my QRectF to the middle of my circle -> so that what it will stay fixed and rotate around his own axis. I'm not sure if i've got it right.

Code:


//constructor of main class (RuletV1.cpp)
RuletV1::RuletV1(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
ui.setupUi(this);
QGraphicsScene *scena = new QGraphicsScene();
ui.graphicsView->setScene(scena);
m_elipsa = new CircleItem(); //note: QGraphicsItem *m_elipsa;
scena->addItem(m_elipsa);
}


//push method
void RuletV1::on_pushButton_clicked()
{
dynamic_cast<CircleItem*>(m_elipsa)->rotate(30); // is there better way rotating?
}


//circeitem.cpp
#include "circleitem.h"

//constructor
CircleItem::CircleItem(QGraphicsItem *parent)
: QGraphicsItem(parent)
{}
//destructor
CircleItem::~CircleItem()
{}
//return QRectF
QRectF CircleItem::boundingRect() const
{
return QRectF(0,0,100,100);
}
//Paint
void CircleItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget)
{
painter->setRenderHint(QPainter::Antialiasing);
painter->drawLine(0,50, 100, 50); //line one
painter->drawLine(50, 0, 50, 100); //line two
painter->drawEllipse(0, 0, 100, 100); //circle
}

p.s: i'v excluded some .h files as they are not so crucial right now


//main.cpp
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
RuletV1 w;
w.show();
return a.exec();
}

I hope this is enough info - thx in advanced

jano_alex_es
11th November 2009, 08:51
//push method
void RuletV1::on_pushButton_clicked()
{
dynamic_cast<CircleItem*>(m_elipsa)->rotate(30); // is there better way rotating?
}


Yep, what it does is the normal behavour; so you need to translate it first.

From docs:

QGraphicsItem::rotate ( qreal angle )

So, in your case, x and y should be width/2 and height/2 of your item.

yogeshgokul
11th November 2009, 09:10
You can use QTransform for this.


QTransform tra;
qreal dx; //Set is properly according the radius of your circle.
qreal dy; //Set is properly according the radius of your circle.
tra.translate(dx,dy);
tra.rotate(qreal angle);
tra.translate(-dx, -dy);
dynamic_cast<CircleItem*>(m_elipsa)->setTransform(tra);

petar
11th November 2009, 09:14
Yes thx, that does it. But it only works for 1 time, it doesn't rotate a second time.


void RuletV1::on_pushButton_clicked()
{
dynamic_cast<CircleItem*>(m_elipsa)->setTransform(QTransform().translate(50,50).rotate( 30).translate(-50,-50));
}

jano_alex_es
11th November 2009, 09:31
Try to save your current Angle in a member variable, add 30 degrees each time you press the button and rotate it later that variable.

Maybe "it rotates until degree x", no "it rotates x degrees".

yogeshgokul
11th November 2009, 09:34
Try to save your current Angle in a member variable, add 30 degrees each time you press the button and rotate it later that variable.
Maybe "it rotates until degree x", no "it rotates x degrees".
Absolutely right. :)

petar
11th November 2009, 10:42
Yes thanks guys - it works wonderfull :)

Code.


void RuletV1::on_pushButton_clicked()
{
QTransform tra;
qreal dx = 50;
qreal dy = 50;
tra.translate(dx,dy);
tra.rotate(Sumarum(30)); //every time add 30 and return
tra.translate(-dx,-dy);
dynamic_cast<CircleItem*>(m_elipsa)->setTransform(tra);
}



qreal RuletV1::Sumarum(qreal num) { return myangle+=num; }


//public: qreal Sumarum(qreal Broj);
//private: qreal myangle;

................
Side questions -> just a little direction needed

1) If i recall CSS i would make elastic design web pages - i need to do the same in QT: Resizing the window (QMainWindow) needs to resize all elements on the view (QGraphicsView)

2) If i want to rotate my circle for a few seconds, what are my possibilites? Is there a built-in mechanism? wich class if apropriate
.........................

THX