B
B
BogBel2015-05-09 18:35:23
Qt
BogBel, 2015-05-09 18:35:23

How to implement element rotation inside QGraphicsScene?

I am writing Tetris, there are a lot of crutches and bicycles in the code, but in the process of execution, I ran into the problem of rotating elements.
Own shape class.

class enemy :public QObject, public QGraphicsRectItem, public QTransform//, public QGraphicsPolygonItem
{
    Q_OBJECT
private:
    QTimer *timer;
    QTransform ThisTransform=transform();
public:
    enemy();

    void keyPressEvent(QKeyEvent *event);
    void drawFigureRect();
    void drawFigureArrow();
    void drawFigureLine();
    void drawFigureL();
    
public slots:
    bool moving();
};

и cpp файл в котором это все реализовано

enemy::enemy()
{

    int a=rand()%3;
    switch (a)
    {
        case 0:this->setBrush(QBrush(Qt::green));
        this->setPen(QPen(Qt::gray));
        break;
    case 1:this->setBrush(QBrush(Qt::blue));
        this->setPen(QPen(Qt::gray));
        break;
    case 2:this->setBrush(QBrush(Qt::yellow));
        this->setPen(QPen(Qt::gray));
        break;

    }
    int b=rand()%2;
    switch(b)
    {
    case 0: this->drawFigureLine();
        this->setPos(0,0);
        break;
    case 1: this->drawFigureRect();
        this->setPos(0,0);
        break;
    }

    //this->setPos(scene()->width()/2,10);
   // this->setRect(0,0,40,40);
   // this->setPos(scene()->width()/2,10);
   // scene()->addItem(this);
    this->setFlag(QGraphicsItem::ItemIsFocusable);
    this->setFocus();
    qDebug()<<"New fcn enemy";
    timer=new QTimer();
    //qDebug()<<timer->stop();
    QObject::connect(timer,SIGNAL(timeout()),this,SLOT(moving()));
    //bool a=moving();
   // if(a)
    //timer->stop();
    //QObject::connect(timer,SIGNAL(timeout()),timer,SLOT(stop());
     timer->start(80);




}

void enemy::keyPressEvent(QKeyEvent *event)
{
    if(event->key()==Qt::Key_Up)
    {

        this->setTransformOriginPoint(this->rect().width()/2,this->rect().height()/2);
        ThisTransform.rotate(90);
        this->setTransform(ThisTransform);
    }
    if(event->key()==Qt::Key_Down)
    {

        qDebug()<<"rotation";
    }
    if(event->key()==Qt::Key_Left && pos().x()>0 && scene()->itemAt(this->x()-1,this->y()+rect().height(),QTransform())==0)
    {
        setPos(x()-30,y());
       qDebug()<<"yeah";
    }
    else if(event->key()==Qt::Key_Right && pos().x()+this->rect().width()<scene()->width() && scene()->itemAt(this->x()+rect().width()+1,this->y(),QTransform())==0)
    {
        setPos(x()+30,y());
        qDebug()<<"yeahh";
    }

}

void enemy::drawFigureRect()
{
this->setRect(0,0,60,60);
}

void enemy::drawFigureArrow()
{
//this->setPolygon(QPolygon(0,0,20,20,40,40,20,60));

}

void enemy::drawFigureLine()
{
    this->setRect(0,0,30,120);
}

void enemy::drawFigureL()
{

}

bool enemy::checkColliding(int x, int y)
{

    if(scene()->itemAt(x,y+this->rect().height()+1,QTransform())!=0 ||scene()->itemAt(x-1,y,QTransform())!=0||scene()->itemAt(x+this->rect().width()+1,y,QTransform())!=0 )
    {
        qDebug()<<1;
        return false;

    }
    qDebug()<<2;
    return true;


}

bool enemy::moving()
{

    QList<QGraphicsItem *> colliding=collidingItems();
    for(int i=0,n=colliding.size();i<n;i++)
    {
        if(typeid(*(colliding[i]))==typeid(enemy) && colliding[i]->x()==this->x())
     
            timer->stop();
          
           this->clearFocus();
           this->blockSignals(true);
           enemy *obj=new enemy();
           this->scene()->addItem(obj);
            return false;
        }
    }
    int a=this->rect().height();
    int h=this->scene()->height();
    //qDebug()<<h;
    if(this->y()+a<h && scene()->itemAt(this->x()+1,this->y()+rect().height()+1,QTransform())==0){
        setPos(this->x(),this->y()+5);


    }
    else
    {
        timer->stop();
       //this->killTimer(1000);
       this->clearFocus();
       this->blockSignals(true);
       enemy *obj=new enemy();
       this->scene()->addItem(obj);

       // delete this;
        
    }
}
а именно вот это:

void enemy::keyPressEvent(QKeyEvent *event)
{
    if(event->key()==Qt::Key_Up)
    {

        this->setTransformOriginPoint(this->rect().width()/2,this->rect().height()/2);
        ThisTransform.rotate(90);
        this->setTransform(ThisTransform);
    }
    if(event->key()==Qt::Key_Down)
    {

      
    }
    if(event->key()==Qt::Key_Left && pos().x()>0 && scene()->itemAt(this->x()-1,this->y()+rect().height(),QTransform())==0)
    {
        setPos(x()-30,y());
     
    }
    else if(event->key()==Qt::Key_Right && pos().x()+this->rect().width()<scene()->width() && scene()->itemAt(this->x()+rect().width()+1,this->y(),QTransform())==0)
    {
        setPos(x()+30,y());
       
    }

}

The rotation goes around the upper left vertex of the figure, I want to implement the rotation in place.
Sorry for the clumsy code, open to correction suggestions.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Armenian Radio, 2015-05-09
@gbg

Remove the QTransform class from the parents (it shouldn't be there, its presence is a sign of a disgusting class design) and the compiler will immediately show you where the error is (you set the rotation center for one transformation, but actually apply another).

D
DancingOnWater, 2015-05-15
@DancingOnWater

Oh god....
You don't understand the essence of the Qt Graphics Framework.
To rotate an Item you just need to call the setRotation method

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question