0

ここでは、いくつかの形状を印刷するカスタム ウィジェットを開発しました。しかし、ここで私のMouseReleaseとMouseMoveイベントが機能していません.wh tは私のコードの問題です. 同様に、いくつかのアサートが実行されます。これを解決するのを手伝ってください。

これは私のヘッダーファイルです

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

}
4

3 に答える 3

2

QGraphicsSceneMouseEventを使用します。

于 2012-06-25T12:04:47.023 に答える
1

あなたは何をしようとしているのかを私たちにまったく伝えていません。Qt のグラフィック シーン/ビュー システムは、低レベルのマウス イベントを処理するためのコードを記述する必要なく、アイテムのドラッグをサポートするのに十分強力です。それがあなたの求めているものなら、それはそうです。

マウスの押下はウィジェットではなく child で発生するため、マウスの移動イベントは呼び出されませんQGraphicsScene。子供に発生するマウス プレスは、ウィジェット内でマウス トラッキングをトリガーしません。

Painter クラスで子ウィジェットを管理するレイアウトを追加した場合、 の外側の余白をクリックすると、マウス移動イベントが処理されることに気付くでしょうQGraphicsView。以下のコードは、シーン ビューを含むウィジェットにレイアウトを設定する方法を示しています。

以下のコードは、ランダムなサイズの移動可能でフォーカス可能な円を作成する完全で、できれば正しい例です。次のことも示します。

  • 親ウィジェットからシーン自体に座標を適切にマッピングする方法。
  • そのシーンをクリアするには、アイテムを手動で追跡する必要はありません。
  • 単純な機能を追加するために事前定義されたアイテムから派生する方法。
  • フォーカスのあるアイテムの操作方法。
  • シーンの子が削除されたときにシーンに通知されるため、子アイテムを削除するだけで完全に安全です。
  • によって返される可能性のある nullポインターdeleteを安全に無視しますQGraphicsScene::focusItem()
  • オブジェクト名を使用して、 という名前のスロットを自動的にアタッチする方法on_name_signal
  • 最後に .moc ファイルを含めることで、.cpp ファイル内に Q_OBJECT クラスを含める方法。
  • 値によってメンバーを保持し、メモリ管理をコンパイラに任せる方法。

この例は自己完結型で、それぞれ 1 つの .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
于 2012-06-27T01:10:07.080 に答える