我创建了一个对象:
class Button : public QObject, public QGraphicsPixmapItem
{
Q_OBJECT
public:
Button();
virtual QRectF boundingRect() const override;
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
// QGraphicsItem interface
protected:
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
signals:
void clicked();
private:
bool m_pressed;
QPixmap m_buttonPixmap, m_pressedButtonPixmap;
};
接下来我实现了几个功能:
Button::Button()
: m_pressed(false)
{
m_buttonPixmap = PixmapManager::Instance()->getPixmap(PixmapManager::Button);
m_pressedButtonPixmap = PixmapManager::Instance()->getPixmap(PixmapManager::PressedButton);
setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable);
}
QRectF Button::boundingRect() const
{
return QRectF(-m_buttonPixmap.width() / 2.0f,
-m_buttonPixmap.height() / 2.0f,
m_buttonPixmap.width(),
m_buttonPixmap.height());
}
void Button::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
if (m_pressed) {
//painter->drawPixmap(0,0, m_pressedButtonPixmap);
}
else {
painter->setBrush(Qt::red);
painter->drawRect(boundingRect());
//painter->drawPixmap(0,0, m_buttonPixmap);
}
}
void Button::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
qDebug() << "pressed ";
m_pressed = true;
update();
QGraphicsPixmapItem::mousePressEvent(event);
}
void Button::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
qDebug() << "released ";
m_pressed = false;
update();
QGraphicsPixmapItem::mouseReleaseEvent(event);
}
我还创建了一个带有 Button 项目的 QGraphicsScene:
MenuScene::MenuScene(QObject *parent)
: QGraphicsScene(parent)
{
setSceneRect(0,0, SCREEN::PHYSICAL_SIZE.width(), SCREEN::PHYSICAL_SIZE.height());
addItem(&m_startButton);
}
void MenuScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
qDebug() << "Scene pressed";
QGraphicsScene::mousePressEvent(event);
}
void MenuScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
qDebug() << "Scene released";
QGraphicsScene::mouseReleaseEvent(event);
}
如果我点击一个按钮,我只能从 MenuScene 获得信息,例如“按下场景”/“释放场景”
在main.cpp中我使用:
MenuScene* ms = new MenuScene();
QGraphicsView gv;
gc.show();
我尝试使用: m_startButton.setAcceptedMouseButtons(Qt::AllButtons); m_startButton.setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable); 但没有结果。
items()
函数和 Qt::IntersectsItemShape
标志来检查哪些项目可能受到鼠标事件的影响,这意味着结果始终基于项目的 shape()
。
虽然 QGraphicsItem 的默认行为是基于
boundingRect()
返回 QPainterPath,但并非所有子类都是这种情况,包括 QGraphicsPixmapItem,它基于其像素图(并可能考虑其掩码)构造路径。
由于您从未在项目上调用
setPixmap()
,因此从 shape()
生成的路径为空,因此对于鼠标事件(以及其他项目的碰撞检测,无论其价值如何),它始终是透明。
最简单的解决方案是在构造函数中调用
setPixmap(m_buttonPixmap)
,然后在相关鼠标事件处理程序中使用任一像素图再次调用 setPixmap()
。
或者,您可以覆盖
shape()
,创建一个 QPainterPath,使用 addRect(boundingRect())
,然后返回它(您还应该考虑缓存边界矩形和路径,以避免不必要的开销)。
但请注意,您实际上没有利用任何 QGraphicsPixmapItem 功能:您不仅没有使用它的偏移、转换模式或遮罩功能,而且最终还需要自己绘制像素图。
考虑到这一点,从一开始就对其进行子类化确实没有什么意义,您可能只需从 QGraphicsObject 继承,它已经从 QObject 和 QGraphicsItem 继承了。