0

I am trying to make an application with a QGraphicsView in it. I tried to get the position of a mouse when the mouse was pressed with QGraphicsSceneMouseEvent, but it doesn't seem to work. The entire function is never called when I press the mouse.

I would like to make an application that can load an image into the QGraphicsView and then when you press the mouse button, it should add a small circle.

This is my code:

dialog.cpp:

#include "dialog.h"
#include "ui_dialog.h"

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
    ui->graphicsView = new GraphicsView();
}

Dialog::~Dialog()
{
    delete ui;
}

graphicsview.h:

#ifndef GRAPHICSVIEW_H
#define GRAPHICSVIEW_H
#include <QGraphicsView>
#include <QMouseEvent>
#include <QDebug>

class GraphicsView : public QGraphicsView
{
public:
    GraphicsView();
protected:
    void mousePressEvent(QMouseEvent *event) override;

private:
    QGraphicsScene *scene;
};

#endif // GRAPHICSVIEW_H

graphicsview.cpp:

#include "graphicsview.h"

GraphicsView::GraphicsView()
{
    scene = new QGraphicsScene();
    this->setScene(scene);
}

void GraphicsView::mousePressEvent(QMouseEvent *event)
{
    if(event->button() == Qt::LeftButton)
    {
        qDebug() << "The left button was pressed!";
    }
}
  • Did you ...: Enable mouse tracking on the `QGraphicsView`? Connect signals correct? Find the memory leak in the function you posted (Hint: https://doc.qt.io/qt-5/qgraphicsscene.html#addEllipse)? – Zaiborg Oct 07 '19 at 11:39
  • As additional questsion: How is your `scene` invoking the function `Dialog::mousePressEvent`? – Zaiborg Oct 07 '19 at 11:45
  • @Zaiborg I just edited my post and included all the code from the dialog class – JustProgrammingQuestions Oct 07 '19 at 12:03
  • Not an answer, but you'll probably want `event->scenePos()` from the way you used the position in your code. That is, `x = int(event->scenePos().x());` and same with `y`. – Osama Kawish Oct 07 '19 at 12:08
  • @MadManiac yes I went back and forth a few times, but using scenePos didn't solve the problem. – JustProgrammingQuestions Oct 07 '19 at 12:09
  • Since I can't find much Qt documentation with examples on `QGraphicsSceneMouseEvent`, I'm not entirely sure how Qt wants that class to work. But regardless, for a solution that will work, you can implement your custom `GraphicsView` class which inherits `QGraphicsView`, and override `mousePressEvent` in that class. That will work for sure, since I've done it myself. – Osama Kawish Oct 07 '19 at 12:17
  • 1
    In fact, I think you're supposed to reimplement this by inheriting `QGraphicsScene`. In the documentation for [QGraphicsScene](https://doc.qt.io/qt-5/qgraphicsscene.html), its protected `mousePressEvent` is `virtual void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)` (ie. the input variable's type is `QGraphicsSceneMouseEvent` instead of the usual `QMouseEvent` like in most classes), meaning that's how mouse events of graphics scenes are supposed to be implemented. Since your class inherits `QDialog`, it's probably the reason it doesn't work. – Osama Kawish Oct 07 '19 at 12:19
  • @MadManiac okay so I should make a new class for the QGraphicsScene and override QMouseEvent? Thanks I'll try that. – JustProgrammingQuestions Oct 07 '19 at 12:26
  • @MadManiac I updated my source code in the question but it still isn't working. Would you mind looking at it or sharing how you implemented the QMouseEvent into your custom QGraphicsView? Thanks! – JustProgrammingQuestions Oct 07 '19 at 14:01
  • @JustProgrammingQuestions I doubt this is supposed to make much of a difference, but one different thing I did was go directly to the ui and promote my QGraphicsView to a GraphicsView (my custom class). Beyond that, I'm not sure I see too many differences between what you did and I did, and my implementation was more towards an Adobe Illustrator-type project than a Photoshop-type one. I'll try to test your code though. – Osama Kawish Oct 07 '19 at 14:31
  • Btw, how does your mainWindow open your dialog? Do you just open it by calling the dialog directly? – Osama Kawish Oct 07 '19 at 14:32
  • Okay. I figured this out. I'd message you if I knew how since this is getting hefty for a comment section. But I'll respond with an answer. – Osama Kawish Oct 07 '19 at 14:44

1 Answers1

0

You're almost there.

Just change GraphicsView::GraphicsView() to:

GraphicsView::GraphicsView(QWidget *parent=nullptr) : QGraphicsView(parent) {}

and change ui->graphicsView = new GraphicsView(); to

QVBoxLayout *verticalLayout = new QVBoxLayout(this);
verticalLayout->addWidget(new GraphicsView(this));

This will make the graphics view a parent of the dialog. Make sure that your dialog doesn't have anything in it when you add the code above. Alternatively, you can add a vertical layout to the dialog in your dialog.ui file and do

ui->verticalLayout->addWidget(new GraphicsView(this));

I believe that solves your problem. Respond if you still have any issues.

Make sure you always have a parent parameter. Without it, you're not telling your program where it's supposed to add your widget.

Osama Kawish
  • 312
  • 1
  • 5
  • 15