Qt 视图框架QGraphicsItem

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt 视图框架QGraphicsItem相关的知识,希望对你有一定的参考价值。

参考技术A 视图框架的一部分,为绘制你自己的item提供了一个轻量级的窗口。支持很多特性,例如:鼠标、键盘事件、拖放、分组、碰撞检测等。

通常在演示工具中使用分组,当用户想要将多个较小的 items 组合成一个大的 item 时,以简化 items 的移动和复制。

QGraphicsItemGroup 是一种特殊类型的复合 item,将自身及其所有子项视为一个 item(即,其所有子项的所有事件和几何图形都被合并在一起)。

QGraphicsItemGroup 的 boundingRect() 函数返回位于其中所有 items 的边界矩形。QGraphicsItemGroup 忽略其子项上的 ItemIgnoresTransformations 标记(即,相对于 QGraphicsItemGroup 的 geometry,子项被视为可变换的)。

要构造一个 QGraphicsItemGroup,有两种方式:
1、将一个 items 列表(例如:所有选择的 items)传递给 QGraphicsScene::createItemGroup(),它返回一个新的 QGraphicsItemGroup(最简单、最常见的方式)。
2、手动构造一个 QGraphicsItemGroup,使用 QGraphicsScene::addItem() 将其添加到场景中,然后通过调用 addToGroup() 为 group 手动添加 item,一次只能添加一个。
左上角为(0, 0)点,宽400,高300这样的矩形,线性映射的示意图如下:

从 QGraphicsItem 派生类绘制 QGraphicsScene

【中文标题】从 QGraphicsItem 派生类绘制 QGraphicsScene【英文标题】:Drawing on QGraphicsScene from a QGraphicsItem derived class 【发布时间】:2012-11-24 23:24:24 【问题描述】:

我正在使用图形视图框架在 Qt 中开发一款 RPG 游戏。我创建了一个类“Player”,它继承了 QGraphicsItem。现在,我正在尝试制作一个“攻击”动画,所以每次我按空格键时,角色前面都会有一个动画。我已经使用“advance()”函数实现了移动动画。

所以,每次我按空格键时,“is_attacking”变量都会变为真。每 85 毫秒,程序检查“is_attacking”是否为真,如果是,动画将前进(绘制下一帧)并更新。当所有帧都用完后,"is_attacking" 变为 false。

问题是我不能使用“播放器”类来绘制动画。 QGraphicsItem 是独立的,有自己的坐标系。我已经完成了攻击系统,但我无法将动画绘制到场景中。

void Player::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)

painter->drawPixmap(QRect(0, 0, 32, 32), *pixmap, QRect(position.x(), position.y(), 32, 32));

if(its_attacking())
    switch(pos)
case NORTH: // draw animation frame to x, y - 32
break;
case SOUTH: // draw animation frame to x, y + 32
break;
case WEST: // draw animation frame to x - 32, y
break;
case EAST: // draw animation frame to x + 32, y

     


    


如何使用 QGraphicsItem 中的“paint()”来绘制项目所属的 QGraphicsScene?

【问题讨论】:

【参考方案1】:

paint() 用于在本地坐标中绘制项目。更改项目位置所需的是 setPos() 函数,它设置项目在父坐标中的位置。

动画不应该在paint()函数中处理(除非你想改变项目的位置),而是在定时器超时调用的槽中:

// Slot called at 85 ms timer's timeout
void Player::timerTimeoutSlot()

   if(its_attacking())
      switch(pos)
        case NORTH: // draw animation frame to x, y - 32
            setPos(QPointF(pos().x(), pos().y()-32);
            break;
        case SOUTH: // draw animation frame to x, y + 32
            setPos(QPointF(pos().x(), pos().y()+32);
            break;
        case WEST: // draw animation frame to x - 32, y
            setPos(QPointF(pos().x()-32, pos().y());
            break;
        case EAST: // draw animation frame to x + 32, y
            setPos(QPointF(pos().x()+32, pos().y());
            break;
     
   

请注意,为了启用信号/插槽,您应该从 QGraphicsObject 而不是 QGraphicsItem 继承。

【讨论】:

感谢您的帮助,但我如何从插槽中绘制动画帧? 您将同时使用 paint() 来绘制动画,并从插槽中更改项目的位置 但是动画只是一个精灵表,一个QPixmap。我怎么能移动像素图?像素图是工作表,所以我只画了一部分。 玩家是否在移动? 不,我的意思是玩家有一个移动动画,但它不会干扰攻击动画。

以上是关于Qt 视图框架QGraphicsItem的主要内容,如果未能解决你的问题,请参考以下文章

✎Qt-doc—QGraphics图形视图框架&坐标系统

✎Qt-doc—QGraphics图形视图框架&坐标系统

Qt图形视图体系结构

Qt基础之二十九:图形视图框架(Graphics View Framework)及其应用

Qt 视图框架QGraphicsItem

Qt开发技术:图形视图框架场景QGraphicsSceneQGraphicsItem与QGraphicsView详解