找回密码
 立即注册
收起左侧

如何在QGraphicsItem对象中实现键盘控制的旋转和放大:

1
回复
8701
查看
[复制链接]
累计签到:5 天
连续签到:1 天
来源: 2016-3-1 21:25:06 显示全部楼层 |阅读模式
1Qter豆
本帖最后由 ltcxjtu 于 2016-3-1 21:28 编辑

自己在看作者的《qt及qt quick开发实战精解》中的方块游戏发现源码:
2-1/myGame中的键盘控制中的旋转无法实现:代码如:

    case Qt::Key_Up :
        //rotate(90);
    {
        qDebug()<<"hello:"<<"Key_Up"<<endl;
        QTransform transform;
        //transform.rotate(90);
        
        qreal x = boundingRect().center().x();
        qreal y = boundingRect().center().y();
        transform.translate(x,y).rotate(90).translate(-x,-y);
         this->setTransform(transform);
         
     /*   setTransform(QTransform()
          .translate(boundingRect().width() / 2,
                     boundingRect().height() /2)
          .rotate(90)
          .translate(-boundingRect().width() / 2,
                     -boundingRect().height() / 2));*/
        //setRotation(90);
        if(isColliding())
        {
          //  rotate(-90);
           // setRotation(-90);
            transform.rotate(-180);//we had a change here.
            this->setTransform(transform);
        }
        break;
    }
上面的代码在书上34页;我的实测结果是:只能旋转一次,以后再旋转无法实现。

基于上面的问题,我看了下网上有一个示例,可以很好的演示这个问题:
//myitem.h
#ifndef MYITEM_H
#define MYITEM_H

#include <QGraphicsItem>

class MyItem : public QGraphicsItem
{
public:
    MyItem();
    void keyPressEvent(QKeyEvent *event);
   // void mousePressEvent(QGraphicsSceneMouseEvent *event);
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
    QRectF boundingRect() const;
    //void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
private:
    QRectF rect;
    QPointF startPoint;
    QPointF offset;

};

#endif // MYITEM_H

//myitem.cpp

#include "myitem.h"
#include<QPainter>
#include<QGraphicsSceneEvent>
#include<QKeyEvent>
#include<QDebug>
MyItem::MyItem()
{
    setFlags(ItemIsFocusable|ItemIsMovable);
    //boundingRect();
    //rect.setRect(-18,-18,36,36);
}
QRectF MyItem::boundingRect() const
{
    //rect.setRect(-18,-18,36,36);
    return QRectF(-18,-18,36,36);//QRectF(rect);
}

void MyItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    rect.setRect(-18,-18,36,36);
    painter->drawRect(rect);
}
void MyItem::keyPressEvent(QKeyEvent *event)
{
    switch (event->key())
    {
    case Qt::Key_4 :
        //rotate(-30);
        qDebug()<<"hehe"<<endl;
        setRotation(-30);    重点代码
        break;
    case Qt::Key_6 :
        //rotate(30);
        break;
    case Qt::Key_Up:
        //scale(1.2,1.2);
        qDebug()<<"haha"<<endl;
        setScale(1.2);            重点代码
        break;
    case Qt::Key_Down:
       // scale(1/1.2,1/1.2);
        moveBy(-20,-20);    重点代码
        break;
    case Qt::Key_Right:
        moveBy(20,20);
    }
}


//main.cpp
#include<QApplication>
#include"myitem.h"
#include<QGraphicsScene>
#include<QGraphicsView>
int main(int argc,char *argv[])
{
    QApplication app(argc,argv);
    QGraphicsScene scene;
    scene.setSceneRect(-200, -150, 400, 300);

    MyItem *item = new MyItem;
    item->setFocus();
    scene.addItem(item);
    item->setPos(50,50);

    QGraphicsView view;
    view.setScene(&scene);
    view.show();

    return app.exec();
}


上面的程序中对于moveBy()能够正常执行,而对于setScale()和setRotation()只能第一次执行,后面就无法执行了,但是上面的按键事件是传递进去的。。。。
http://bbs.csdn.net/topics/391049508
解释为:
关于坐标的问题我已经解决了,问题的结症主要在于ITEM本地坐标重建的问题,Item的本地坐标应该始终保持圆点在坐标系中心的位置,本身QGraphicsItem没有考虑改变大小的问题,所以改变大小后,本地坐标系也被破坏了。解决问题的方法也挺简单,就是改变大小后重建一下本地坐标系统。
http://www.qter.org/forum.php?mo ... p;extra=&page=1



这是和这个问题相关的两个帖子,自己看的不是很明白。求解释
第一次发帖,不知道怎么用nakedown格式编辑代码。也不知道怎么把源码附上去。

回复

使用道具 举报

累计签到:5 天
连续签到:1 天
2016-3-1 21:31:24 显示全部楼层
本帖最后由 ltcxjtu 于 2016-3-1 21:32 编辑
  1.     case Qt::Key_Up :
  2.         //rotate(90);
  3.     {
  4.         qDebug()<<"hello:"<<"Key_Up"<<endl;
  5.         QTransform transform;
  6.         //transform.rotate(90);
  7.         
  8.         qreal x = boundingRect().center().x();
  9.         qreal y = boundingRect().center().y();
  10.         transform.translate(x,y).rotate(90).translate(-x,-y);
  11.          this->setTransform(transform);
  12.          
  13.      /*   setTransform(QTransform()
  14.           .translate(boundingRect().width() / 2,
  15.                      boundingRect().height() /2)
  16.           .rotate(90)
  17.           .translate(-boundingRect().width() / 2,
  18.                      -boundingRect().height() / 2));*/
  19.         //setRotation(90);
  20.         if(isColliding())
  21.         {
  22.           //  rotate(-90);
  23.            // setRotation(-90);
  24.             transform.rotate(-180);//we had a change here.
  25.             this->setTransform(transform);
  26.         }
  27.         break;
  28.     }
复制代码
  1. //myitem.h
  2. #ifndef MYITEM_H
  3. #define MYITEM_H

  4. #include <QGraphicsItem>

  5. class MyItem : public QGraphicsItem
  6. {
  7. public:
  8.     MyItem();
  9.     void keyPressEvent(QKeyEvent *event);
  10.    // void mousePressEvent(QGraphicsSceneMouseEvent *event);
  11.     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
  12.     QRectF boundingRect() const;
  13.     //void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
  14. private:
  15.     QRectF rect;
  16.     QPointF startPoint;
  17.     QPointF offset;

  18. };

  19. #endif // MYITEM_H

  20. //myitem.cpp

  21. #include "myitem.h"
  22. #include<QPainter>
  23. #include<QGraphicsSceneEvent>
  24. #include<QKeyEvent>
  25. #include<QDebug>
  26. MyItem::MyItem()
  27. {
  28.     setFlags(ItemIsFocusable|ItemIsMovable);
  29.     //boundingRect();
  30.     //rect.setRect(-18,-18,36,36);
  31. }
  32. QRectF MyItem::boundingRect() const
  33. {
  34.     //rect.setRect(-18,-18,36,36);
  35.     return QRectF(-18,-18,36,36);//QRectF(rect);
  36. }

  37. void MyItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
  38. {
  39.     rect.setRect(-18,-18,36,36);
  40.     painter->drawRect(rect);
  41. }
  42. void MyItem::keyPressEvent(QKeyEvent *event)
  43. {
  44.     switch (event->key())
  45.     {
  46.     case Qt::Key_4 :
  47.         //rotate(-30);
  48.         qDebug()<<"hehe"<<endl;
  49.    [color=Red] [b]    setRotation(-30);    重点代码[/b][/color]
  50.         break;
  51.     case Qt::Key_6 :
  52.         //rotate(30);
  53.         break;
  54.     case Qt::Key_Up:
  55.         //scale(1.2,1.2);
  56.         qDebug()<<"haha"<<endl;
  57. [color=Red]  [b]      setScale(1.2);            重点代码[/b][/color]
  58.         break;
  59.     case Qt::Key_Down:
  60.        // scale(1/1.2,1/1.2);
  61. [color=Red]    [b]    moveBy(-20,-20);    重点代码[/b][/color]
  62.         break;
  63.     case Qt::Key_Right:
  64.         moveBy(20,20);
  65.     }
  66. }


  67. //main.cpp
  68. #include<QApplication>
  69. #include"myitem.h"
  70. #include<QGraphicsScene>
  71. #include<QGraphicsView>
  72. int main(int argc,char *argv[])
  73. {
  74.     QApplication app(argc,argv);
  75.     QGraphicsScene scene;
  76.     scene.setSceneRect(-200, -150, 400, 300);

  77.     MyItem *item = new MyItem;
  78.     item->setFocus();
  79.     scene.addItem(item);
  80.     item->setPos(50,50);

  81.     QGraphicsView view;
  82.     view.setScene(&scene);
  83.     view.show();

  84.     return app.exec();
  85. }
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

公告
可以关注我们的微信公众号yafeilinux_friends获取最新动态,或者加入QQ会员群进行交流:190741849、186601429(已满) 我知道了