2015-03-31 197 views
2

我遇到了mousePressEvent(QGraphicsSceneMouseEvent *event)问题,的确,可点击区域看起来很小,并且偏离了它所链接的QGraphicsPixmapItemQt“mousePressEvent”修改了可点击区域

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

一个的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),则这个角色将围绕左上角。取而代之的是,我们要集中在我们的播放器的边界RECT:

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函数。由于玩家的形状是统一的(一个矩形),我们只关心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()); 
} 

的最后一件事是,如果你要替换形状功能,你仍然必须实现boundingRect。

+1

非常感谢你:) – 2015-03-31 20:43:06