我遇到了mousePressEvent(QGraphicsSceneMouseEvent *event)
的问题,实际上可点击区域似乎很小,偏离了它所链接的QGraphicsPixmapItem
。
红线是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();
}
非常感谢你的帮助
答案 0 :(得分:2)
QGraphicsItem的可点击区域由其boundingRect和shape函数定义。
我首先不使用QGraphicsPixmapItem。您需要一个自定义图形项,它具有信号和插槽的功能,因此派生自QGraphicsObject。
class Player : public QGraphicsObject
{
};
正如我们现在从这个类派生的那样,我们需要覆盖几个纯虚函数;即boundingRect,paint
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。