Qt" mousePressEvent"修改可点击区域

时间:2015-03-31 15:26:40

标签: c++ qt

我遇到了mousePressEvent(QGraphicsSceneMouseEvent *event)的问题,实际上可点击区域似乎很小,偏离了它所链接的QGraphicsPixmapItem

http://i.stack.imgur.com/znpgW.png

红线是QGraphicsPixmapItem可点击的地方。

我如何将它居中并最终使其更大并改变它的形状?

以下是我的代码中可能有用的部分:

在player.h中

class Player:public QObject, public QGraphicsPixmapItem{
    Q_OBJECT
public:
    Player();
    void place_player(int x, int y);
    void mousePressEvent(QGraphicsSceneMouseEvent *event);
};

在player.cpp中

Player::Player(): QGraphicsPixmapItem(){
}

void Player::place_player(int x,int y)
{
    this->setPixmap(QPixmap("test.png"));
    this->setPos(x,y);
    game->scene->addItem(this);
}

void Player::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    qDebug()<<  event;
};

在game.cpp中

Game::Game(){

    setFixedSize(1600,900);

    scene = new QGraphicsScene(this);
    scene->setSceneRect(0,0,1600,900);

    setScene(scene);
}

void Game::start(){
    player1 = new Player();
    player1->place_player(300,300);
}

void Game::mousePressEvent(QMouseEvent *event)
{
    QGraphicsView::mousePressEvent(event);
}

最后是main.cpp

int main(int argc, char *argv[]){

    QApplication a(argc, argv);

    game = new Game();

    game->show();
    game->start();

    return a.exec();
}

非常感谢你的帮助

1 个答案:

答案 0 :(得分:2)

QGraphicsItem的可点击区域由其boundingRectshape函数定义。

我首先不使用QGraphicsPixmapItem。您需要一个自定义图形项,它具有信号和插槽的功能,因此派生自QGraphicsObject

class Player : public QGraphicsObject
{
};

正如我们现在从这个类派生的那样,我们需要覆盖几个纯虚函数;即boundingRectpaint

class Player : public QGraphicsObject
{
    public:
        QRectF boundingRect() const;
        void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget);
}; 

boundingRect函数定义本地坐标中的对象。例如,假设字符的宽度和高度为100.如果我们将boundingRect设置为返回(0,0,100,100),则它将围绕左上角定向。相反,我们希望将边界矩形置于我们的播放器中心:

QRectF Player::boundingRect() const
{
    return QRectF(-50, -50, 100, 100); // local coordinates, centered on the Player
}

要绘制我们的播放器,请将QPixmap存储在类

class Player : public QGraphicsObject
{
    public:
        QRectF boundingRect() const;
        void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget);

    private:
        QPixmap m_playerPixmap;
}; 

我假设您知道如何加载像素图,并且可以在播放器的构造函数中执行此操作。

我们现在需要的是渲染播放器,我们还将显示可点击区域,该区域由boundingRect()函数定义: -

void Player::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget)
{
    // draw the player
    painter->drawPixmap(0, 0, m_playerPixmap);

    // set the pen to draw debug rect
    painter->setPen(QColor(255, 0, 0, 127));

    // for debug purposes, show the bounding rect (clickable area)
    painter->drawRect(boundingRect());
}

最初我提到可点击区域由boundingRect和shape函数定义。由于Player具有统一的形状(矩形),我们只关心boundingRect。在形状不规则的情况下,您还可以覆盖形状函数。

  

我如何将它居中并最终使其更大并改变它的形状?

希望您现在知道要使播放器更大,只需增加其在boundingRect函数中返回的本地坐标即可。所以,如果我们想要将其宽度和高度加倍,我们会这样做:

QRectF Player::boundingRect() const
{
    return QRectF(-100, -100, 200, 200); // local coordinates, centered on the Player
}

要更改其形状,请实现shape()函数并调试,绘制从该函数返回的painterPath,而不是绘制boundingRect。

例如,让我们有一个圆形,可点击的区域。

假设您已将形状声明添加到播放器标题:

QPainterPath Player::shape() const
{
    QPainterPath path;
    path.addEllipse(-100, -100, 200, 200);
    return path;
}

void Player::paint(QPainter * painter, const QStyleOptionGraphicsItem, QWidget*)
{
    // draw the player
    painter->drawPixmap(0, 0, m_playerPixmap);

    // set the pen to draw debug path
    painter->setPen(QColor(255, 0, 0, 127));

    // for debug purposes, show the path (clickable area)
    painter->drawPath(shape());
}

最后要注意的是,如果你要覆盖shape函数,你仍然必须实现boundingRect。