【问题标题】:mouserelease and move events of QWidget is not workingQWidget 的 mouserelease 和 move 事件不起作用
【发布时间】:2017-03-28 23:44:08
【问题描述】:

在这里,我开发了一个自定义小部件来打印一些形状。但是在这里我的 MouseRelease 和 MouseMove 事件不起作用。这是我的代码的问题。以及一些断言被执行。请帮我解决这个问题。

这是我的头文件

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

}

【问题讨论】:

  • 您预计会发生什么?显示了哪些断言? “move”打印出来了吗?
  • 我想在运行时画一个圆。所以我必须得到鼠标位置

标签: qt


【解决方案1】:

【讨论】:

    【解决方案2】:

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

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

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

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

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

    该示例是自包含的,每个仅包含一个 .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
    

    【讨论】:

      【解决方案3】:

      在 QWidget 中鼠标跟踪(当没有按下鼠标按钮时)默认是不启用的。要启用它,请添加以下代码:

      painter->setMouseTracking(true);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-20
        • 1970-01-01
        • 2016-08-06
        • 2023-03-12
        • 2014-01-19
        • 1970-01-01
        • 2020-05-08
        • 1970-01-01
        相关资源
        最近更新 更多