在这里,我开发了一个自定义小部件来打印一些形状。但是我的MouseRelease和MouseMove事件不起作用。这是我的代码的问题。以及一些Asserts被执行。请帮我解决这个问题。
这是我的头文件
//painter.h
#ifndef PAINTER_H
#define PAINTER_H
#include <QWidget>
#include <QGraphicsView>
#include <math.h>
#include <QVector>
#include <QMouseEvent>
#include <QPoint>
class painter : public QWidget
{
Q_OBJECT
private:
enum Shape{CIRCLE,RECTENGEL,TRIANGEL} shape;
QGraphicsView *graphic;
QGraphicsScene *Scene;
QPoint *start;
QPoint *end;
QPen *pen;
QBrush *brush;
QVector<QGraphicsItem*> *items;
public:
explicit painter(QWidget *parent = 0);
void setSize(double width,double height);
void setShape(Shape value);
void addItem();
void clear();
void scale();
signals:
public slots:
protected:
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
};
#endif // PAINTER_H
这是我的CPP文件
//painter.cpp
#include "painter.h"
#include <QDebug>
#include <QGraphicsView>
#include <iterator>
painter::painter(QWidget *parent) :
QWidget(parent)
{
graphic = new QGraphicsView(this);
Scene = new QGraphicsScene(this);
pen = new QPen;
brush = new QBrush;
start = new QPoint;
end = new QPoint;
items = new QVector<QGraphicsItem*>();
graphic->setScene(Scene);
//Scene->addEllipse(10,10,50,50,*pen,*brush);//Scene->addLine(0,0,1,1);
// Scene->addRect(70,70,50,50,*pen,*brush);
graphic->setSceneRect(0,0,500,500);
Scene->addEllipse(20,20,20,20,*pen,*brush);
}
void painter::setSize(double width,double height)
{
graphic->setSceneRect(0,0,width,height);
}
void painter::setShape(Shape value)
{
if(value==CIRCLE)
shape = CIRCLE;
else if(value==RECTENGEL)
shape = RECTENGEL;
else if(value=TRIANGEL)
shape=TRIANGEL;
else
throw("Invalid Shape");
}
void painter::addItem()
{
QGraphicsItem *newItem;
double length = sqrt(pow((double)(start->x()-end->x()),2)+ pow((double)(start->y()-end->y()),2));
if(shape==TRIANGEL)
{
// QPolygonF triangel;
// triangel.
// Scene->addPolygon(,pen,brush);
}
else if(shape==RECTENGEL)
newItem = (QGraphicsItem*)Scene->addRect(end->x()-length,end->y()-length,2*length,2*length,*pen,*brush);
else
newItem = (QGraphicsItem*)Scene->addEllipse(end->x()-length,end->y()-length,2*length,2*length,*pen,*brush);
items->push_back(newItem);
}
void painter::clear()
{
for(int i=0;i<items->size();i++)
Scene->removeItem(items->at(i));
}
void painter::scale()
{
}
void painter::mousePressEvent(QMouseEvent *event)
{
end->setX(50);
end->setY(50);
start->setX(event->x());
start->setY(event->y());
shape = RECTENGEL;
addItem();
}
void painter::mouseMoveEvent(QMouseEvent *event)
{
qDebug("move");
}
void painter::mouseReleaseEvent(QMouseEvent *event)
{
end->setX(event->x());
end->setY(event->y());
addItem();
}
答案 0 :(得分:2)
答案 1 :(得分:1)
你根本没有告诉我们你想做什么。 Qt的图形场景/视图系统功能强大,足以支持拖动项目,而无需编写任何代码来处理低级鼠标事件。如果这就是你所追求的,那就是。
您的鼠标移动事件未被调用,因为您的鼠标按下不会发生在您的小部件中,而是发生在子级QGraphicsScene
中。在儿童中发生的鼠标按下不会触发小部件中的鼠标跟踪。
如果您添加了一个布局来管理Painter类中的子窗口小部件,您会注意到如果单击QGraphicsView
之外的边距,则会处理鼠标移动事件。下面的代码显示了如何在包含场景视图的窗口小部件上设置布局。
以下代码是创建随机大小,可移动和可聚焦圆圈的完整且有希望的正确示例。它也证明了:
delete
安全地忽略空指针,例如可能由QGraphicsScene::focusItem()
返回。on_name_signal
的插槽。该示例是自包含的,每个只包含一个.pro和.cpp文件。它在Qt 4和Qt 5下工作,并利用C ++ 11。
// https://github.com/KubaO/stackoverflown/tree/master/questions/scene-movable-circles-11188261
// main.cpp
#include <QtGui>
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
#include <QtWidgets>
#endif
#include <cmath>
class Circle : public QGraphicsEllipseItem {
QBrush m_inBrush{Qt::red}, m_outBrush{Qt::lightGray};
public:
Circle(const QPointF & c) {
const qreal r = 10.0 + (50.0*qrand())/RAND_MAX;
setRect({c.x()-r, c.y()-r, 2.0*r, 2.0*r});
setFlag(QGraphicsItem::ItemIsMovable);
setFlag(QGraphicsItem::ItemIsFocusable);
setPen({Qt::red});
setBrush(m_outBrush);
}
void focusInEvent(QFocusEvent *) override { setBrush(m_inBrush); }
void focusOutEvent(QFocusEvent *) override { setBrush(m_outBrush); }
};
class Painter : public QWidget {
Q_OBJECT
QGridLayout m_layout{this};
QGraphicsView m_view;
QPushButton m_clear{"Clear"};
QPushButton m_remove{"Remove"};
QGraphicsScene m_scene;
public:
explicit Painter(QWidget *parent = nullptr);
protected:
Q_SLOT void on_remove_clicked();
void mousePressEvent(QMouseEvent *event) override;
};
Painter::Painter(QWidget *parent) : QWidget(parent) {
m_layout.addWidget(&m_view, 0, 0, 1, 2);
m_layout.addWidget(&m_clear, 1, 0);
m_layout.addWidget(&m_remove, 1, 1);
m_remove.setObjectName("remove");
QMetaObject::connectSlotsByName(this);
connect(&m_clear, SIGNAL(clicked()), &m_scene, SLOT(clear()));
m_view.setRenderHint(QPainter::Antialiasing);
m_view.setScene(&m_scene);
m_view.setSceneRect(0,0,500,500);
}
void Painter::mousePressEvent(QMouseEvent *event) {
auto center = m_view.mapToScene(m_view.mapFromParent(event->pos()));
m_scene.addItem(new Circle(center));
}
void Painter::on_remove_clicked() {
delete m_scene.focusItem();
}
int main(int argc, char ** argv)
{
QApplication app{argc, argv};
Painter p;
p.show();
return app.exec();
}
#include "main.moc"
# scene-movable-circles-11188261.pro
greaterThan(QT_MAJOR_VERSION, 4) {
QT = widgets
CONFIG += c++11
} else {
QT = gui
unix:QMAKE_CXXFLAGS += -std=c++11
macx {
QMAKE_CXXFLAGS += -stdlib=libc++
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.7
QMAKE_CXXFLAGS_WARN_ON += -Wno-inconsistent-missing-override
}
}
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x050800
TARGET = scene-movable-circles-11188261
TEMPLATE = app
SOURCES += main.cpp
答案 2 :(得分:0)
在QWidget鼠标跟踪(没有按下鼠标按钮时)默认情况下不启用。要启用它,请添加以下代码:
painter->setMouseTracking(true);