mouseWlease和QWidget的移动事件无法正常工作

时间:2012-06-25 11:13:56

标签: qt

在这里,我开发了一个自定义小部件来打印一些形状。但是我的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();

}

3 个答案:

答案 0 :(得分:2)

答案 1 :(得分:1)

你根本没有告诉我们你想做什么。 Qt的图形场景/视图系统功能强大,足以支持拖动项目,而无需编写任何代码来处理低级鼠标事件。如果这就是你所追求的,那就是。

您的鼠标移动事件未被调用,因为您的鼠标按下不会发生在您的小部件中,而是发生在子级QGraphicsScene中。在儿童中发生的鼠标按下不会触发小部件中的鼠标跟踪。

如果您添加了一个布局来管理Painter类中的子窗口小部件,您会注意到如果单击QGraphicsView之外的边距,则会处理鼠标移动事件。下面的代码显示了如何在包含场景视图的窗口小部件上设置布局。

以下代码是创建随机大小,可移动和可聚焦圆圈的完整且有希望的正确示例。它也证明了:

  • 如何正确地将坐标从父窗口小部件映射到场景本身。
  • 清除场景不需要手动跟踪物品。
  • 如何从预定义项目派生以添加简单功能。
  • 如何操作具有焦点的项目。
  • 当删除子项时会通知场景,因此只需删除子项就可以了。
  • delete安全地忽略空指针,例如可能由QGraphicsScene::focusItem()返回。
  • 如何使用对象名称自动附加名为on_name_signal的插槽。
  • 如何通过在末尾包含.moc文件在.cpp文件中包含Q_OBJECT类。
  • 如何按值保留成员,将内存管理降级为编译器。

该示例是自包含的,每个只包含一个.pro和.cpp文件。它在Qt 4和Qt 5下工作,并利用C ++ 11。

screnshot from running the example code

// 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);