I am fairly new to Qt and creating a simple application that initializes a number of custom QGraphicsItems in a custom QGraphicsScene. Each item is initialized with a random start position and a Weight value which is dependent on the position of the item. On a mouse move event, i want the Weight value of the items to update based on the position of the mouse cursor
I think my the mouseMoveEvent is not recognized within the graphicsScene, it seems to work fine in the main window where i implemented a label in the status bar to show the number of mouseMoveEvents and the X-Y position of the mouseMoveEvent
Here is the code:
Custom graphics Scene .h:
class ParticleScene : public QGraphicsScene
{
public:
ParticleScene();
protected:
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
private:
qreal WTotal;
Particle *particle;
}
Custom Graphics Scene .cpp:
ParticleScene::ParticleScene()
{
//this->setBackgroundBrush(Qt::gray);
this->setSceneRect(0,0,500,500);
WTotal=0;
int ParticleCount =5;
for (int i =0; i<ParticleCount; i++)
{
particle= new Particle();
particle->StartX= rand()%500;
particle->StartY= rand()%500;
particle->W= qSqrt(qPow(particle->StartX,2) + qPow(particle->StartY,2));
particle->setPos(particle->StartX,particle->StartY);
this->addItem(particle);
particle->setFocus();
WTotal+=particle->W;
}
}
void ParticleScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
update();
QGraphicsScene::mouseMoveEvent(event);
}
Particle.h:
I added the Keypress event function and this moved only the last item that was added to the scene, i assume only one item can get focus.
The mouseMove event on the other hand didn't do anything
class Particle :public QGraphicsItem
{
public:
Particle();
QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
int StartX;
int StartY;
qreal W;
protected:
//added keyPressEvent to test
virtual void keyPressEvent(QKeyEvent *event);
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
};
Particle.cpp:
Particle::Particle()
{
// setFlag(ItemIsMovable);
setFlag(ItemIsFocusable);
}
QRectF Particle::boundingRect() const
{
return QRect(0,0,120,30);
}
void Particle::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
QRectF rec= boundingRect();
QBrush Brush(Qt::white);
painter->fillRect(rec,Brush);
painter->drawText(15,15,"Weight: "+QString::number(W));
painter->drawRect(rec);
}
void Particle::keyPressEvent(QKeyEvent *event)
{
switch(event->key()){
case Qt::Key_Right:{
moveBy(30,0);
break;}
case Qt::Key_Left:{
moveBy(-30,0);
break;}
case Qt::Key_Up:{
moveBy(0,-30);
break;}
case Qt::Key_Down:{
moveBy(0,30);
break;}
}
update();
}
void Particle::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
this->W= this->W / qSqrt(qPow(event->pos().x(),2) + qPow(event->pos().y(),2));
moveBy(30,0);
update();
}
MainWindow .h and cpp: the status bar label here displays the mouse coordinates correctly i.e. mouseMoveEvent functions here
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void mouseMoveEvent(QMouseEvent *event);
protected:
private:
Ui::MainWindow *ui;
ParticleScene *scene;
QLabel *statlabel;
int moves;
};
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
statlabel=new QLabel(this);
ui->statusBar->addWidget(statlabel);
statlabel->setText ("Mouse Coordinates");
setCentralWidget(ui->graphicsView);
centralWidget()->setAttribute(Qt::WA_TransparentForMouseEvents);
ui->graphicsView->setMouseTracking(true);
scene= new ParticleScene();
ui->graphicsView->setScene(scene);
ui->graphicsView->setRenderHint(QPainter::Antialiasing);
moves=0;
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
moves+=1;
statlabel->setText("MouseMoves " +QString::number(moves)+ " X:"+QString::number(event->pos().x())+"-- Y:"+QString::number(event->pos().y()));
}
What am I missing in the program that causes the mousemoveevent to not function and Is there a way to focus all the items together? Would i need to perhaps, make them into QList?
In the Next step of the program, I would like the items to update their weight value based on the sum of all their weights and also move based on an algorithm that uses the new weight value to determine a new position.
You are missing some kind of container in which you can save all your Particles. In the current implementation ParticleScene has particle pointer as a private variable. You are creating multiple Particles in the loop (which are QGraphicsItem's) but only the last pointer is stored in you custom Scene. As you said, you can use, for example, QList to save your Particles.
Also I assume you would like to move you items around the scene. For that you can also make you own implementation for MousePress event (to catch when item was pressed and at what coordinate), MouseMove(for actual moving the item around..you have done this already, and mouseRelease (for instance, for computing weights or sending the signal which will trigger computation of weights for all the items)
Instead of keeping all the items inside of custom scene better create a new class, for instance, ItemsManager in which all the items will be stored and the pointer to the scene. In this class you can perform all the operations concerning computation of weights for items or other operations which are required.
Related
We are having an issue with artifacts in an application using multiple QGraphicsScene/QGraphicsViews. Essentially it seems the problem is when when in mousePosChanged event handler for a scene, and call setPos() on an item in a different scene, as well as update a region on the view for the other scene, it leaves artifacts.
I tried to set up a minimal example that hopefully will be easy to spot what is wrong
Essentially I have two scenes (scene 1 and scene 2), each with one ellipse item. When the mouse moves in the first scene, its ellipse item tracks the mouse. It also sends out a signal with mouse position. The second scene is connected to this signal, and updates the position of its ellipse item to the same location. The second graphics view is also connected to the signal, and it updates its viewport in an arbitrary location.
The second graphics view ends up with artifacts as you move the mouse around (see picture below)
This is the code from my minimal example:
class MyView : public QGraphicsView
{
Q_OBJECT
public:
MyView(QGraphicsScene *scene, QWidget *parent = 0);
public slots:
void onMouseMoveEvent();
};
class MyScene : public QGraphicsScene
{
Q_OBJECT
public:
MyScene(QObject *parent = 0);
public slots:
void setTrackerPos(const QPointF &pos);
signals:
void mousePosChanged(const QPointF &pos);
protected:
void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent);
private:
QGraphicsEllipseItem *mCursorTracker;
};
MyScene::MyScene(QObject *parent) :
QGraphicsScene(QRectF(0.,0.,1000.,1000.), parent),
mCursorTracker(new QGraphicsEllipseItem(0., 0., 50., 50.))
{
mCursorTracker->setFlag(QGraphicsItem::ItemSendsGeometryChanges);
mCursorTracker->setBrush(QBrush(Qt::red, Qt::SolidPattern));
addItem(mCursorTracker);
}
void MyScene::setTrackerPos(const QPointF &pos)
{
mCursorTracker->setPos(pos);
}
void MyScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
mCursorTracker->setPos(mouseEvent->scenePos());
emit mousePosChanged(mouseEvent->scenePos());
}
MyView::MyView(QGraphicsScene *scene, QWidget *parent) :
QGraphicsView(scene, parent)
{
setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
setMouseTracking(true);
}
void MyView::onMouseMoveEvent(const QPointF &pos)
{
viewport()->update(QRect(0,0,250,250));
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget *w = new QWidget;
QHBoxLayout *layout = new QHBoxLayout(w);
MyScene *scene1 = new MyScene(w);
MyScene *scene2 = new MyScene(w);
MyView *view1 = new MyView(scene1, w);
MyView *view2 = new MyView(scene2, w);
layout->addWidget(view1);
layout->addWidget(view2);
QObject::connect(scene1, SIGNAL(mousePosChanged(QPointF)), scene2, SLOT(setTrackerPos(QPointF)));
QObject::connect(scene1, SIGNAL(mousePosChanged(QPointF)), view2, SLOT(onMouseMoveEvent()));
w->show();
return a.exec();
}
I understand that changing to a full update on the view will fix this. However in our real application it is too expensive to repaint the whole scene. The update on the viewport is for a small foreground layer, and only one graphics item position changes (like in this example)
I am trying to create a round button by subclassing and setting the region mask so that I can reuse it in my project. I know we can override paintEvent method and draw a circle to show it as a round button. But the problem with this approach is that if user clicks outside the circle (but within button rect) it will be treated as a button click. This problem we don't see when set the region mask.
I tried to set the region by calling setmask method inside resizeEvent/paintEvent. In either of case, button will be blank. I am trying to figure out the place inside the subclass to set the region mask.
RoundAnimatingButton.h ->
#include <QPushButton>
namespace Ui {
class CRoundAnimatingBtn;
}
class CRoundAnimatingBtn : public QPushButton
{
Q_OBJECT
public:
explicit CRoundAnimatingBtn(QWidget *parent = nullptr);
~CRoundAnimatingBtn();
void StartAnimation(QColor r);
void StopAnimation();
public slots:
void timerEvent(QTimerEvent *e);
private:
Ui::CRoundAnimatingBtn *ui;
bool m_Spinning;
// QWidget interface
protected:
void resizeEvent(QResizeEvent *event) override;
void paintEvent(QPaintEvent * e) override;
};
#endif // ROUNDANIMATINGBTN_H
RoundAnimatingButton.cpp
CRoundAnimatingBtn::CRoundAnimatingBtn(QWidget *parent)
: QPushButton (parent)
, ui(new Ui::CRoundAnimatingBtn)
, m_Spinning(false)
{
ui->setupUi(this);
}
CRoundAnimatingBtn::~CRoundAnimatingBtn()
{
delete ui;
}
void CRoundAnimatingBtn::paintEvent(QPaintEvent *e)
{
QPushButton::paintEvent(e);
if(m_Spinning)
{
// Animating code
}
}
void CRoundAnimatingBtn::StartAnimation(QColor r)
{
m_Spinning=true;
startTimer(5);
}
void CRoundAnimatingBtn::StopAnimation()
{
m_Spinning=false;
this->update();
}
void CRoundAnimatingBtn::timerEvent(QTimerEvent *e)
{
if(m_Spinning)
this->update();
else
killTimer(e->timerId());
}
void CRoundAnimatingBtn::DrawRing()
{
}
void CRoundAnimatingBtn::resizeEvent(QResizeEvent *event)
{
// -----------------------------------
// This code didn't work
// -----------------------------------
QRect rect = this->geometry();
QRegion region(rect, QRegion::Ellipse);
qDebug() << "PaintEvent Reound button - " << region.boundingRect().size();
this->setMask(region);
// ----------------------------------
// ------------------------------------
// This code worked
// -------------------------------------
int side = qMin(width(), height());
QRegion maskedRegion(width() / 2 - side / 2, height() / 2 - side / 2, side,
side, QRegion::Ellipse);
setMask(maskedRegion);
}
Qt doc. provides a sample for “non-rectangular” widgets – Shaped Clock Example.
(Un-)Fortunately, I remembered this not before I got my own sample running.
I started in Qt doc. with
void QWidget::setMask(const QBitmap &bitmap)
Causes only the pixels of the widget for which bitmap has a corresponding 1 bit to be visible. If the region includes pixels outside the rect() of the widget, window system controls in that area may or may not be visible, depending on the platform.
Note that this effect can be slow if the region is particularly complex.
The following code shows how an image with an alpha channel can be used to generate a mask for a widget:
QLabel topLevelLabel;
QPixmap pixmap(":/images/tux.png");
topLevelLabel.setPixmap(pixmap);
topLevelLabel.setMask(pixmap.mask());
The label shown by this code is masked using the image it contains, giving the appearance that an irregularly-shaped image is being drawn directly onto the screen.
Masked widgets receive mouse events only on their visible portions.
See also mask(), clearMask(), windowOpacity(), and Shaped Clock Example.
(When reading this, I still missed the link to example.)
At first, I prepared a suitable pixmap for my purpose – dialog-error.png:
for which I converted an SVG from one of my applications.
I tried to apply it to a QPushButton as icon and as mask. This looked very strange. I'm not quite sure what exactly was the problem:
- using the resp. QPushButton as toplevel widget (i.e. main window)
- the fact that QPushButtons icon rendering and the mask may not match concerning position or size.
Without digging deeper, I changed the code and fixed both issues in next try:
making a derived button (like described by OP)
using the button as non-toplevel widget.
This worked soon. I added some code to make the effect more obvious:
a mouse press event handler for main window to show whether shape is considered correctly
a signal handler to show whether clicks on button (in shape) are received correctly.
So, I came to the following sample – testQPushButtonMask.cc:
#include <QtWidgets>
class MainWindow: public QWidget {
public:
explicit MainWindow(QWidget *pQParent = nullptr):
QWidget(pQParent)
{ }
virtual ~MainWindow() = default;
MainWindow(const MainWindow&) = delete;
MainWindow& operator=(const MainWindow&) = delete;
protected:
virtual void mousePressEvent(QMouseEvent *pQEvent) override;
};
void MainWindow::mousePressEvent(QMouseEvent *pQEvent)
{
qDebug() << "MainWindow::mousePressEvent:" << pQEvent->pos();
QWidget::mousePressEvent(pQEvent);
}
class RoundButton: public QPushButton {
private:
QPixmap _qPixmap;
public:
RoundButton(const QPixmap &qPixmap, QWidget *pQParent = nullptr):
QPushButton(pQParent),
_qPixmap(qPixmap)
{
setMask(_qPixmap.mask());
}
virtual ~RoundButton() = default;
RoundButton(const RoundButton&) = delete;
RoundButton& operator=(const RoundButton&) = delete;
virtual QSize sizeHint() const override;
protected:
virtual void paintEvent(QPaintEvent *pQEvent) override;
};
QSize RoundButton::sizeHint() const { return _qPixmap.size(); }
void RoundButton::paintEvent(QPaintEvent*)
{
QPainter qPainter(this);
const int xy = isDown() * -2;
qPainter.drawPixmap(xy, xy, _qPixmap);
}
int main(int argc, char **argv)
{
qDebug() << "Qt Version:" << QT_VERSION_STR;
QApplication app(argc, argv);
QPixmap qPixmap("./dialog-error.png");
// setup GUI
MainWindow qWin;
qWin.setWindowTitle(QString::fromUtf8("QPushButton with Mask"));
QVBoxLayout qVBox;
RoundButton qBtn(qPixmap);
qVBox.addWidget(&qBtn);
qWin.setLayout(&qVBox);
qWin.show();
// install signal handlers
QObject::connect(&qBtn, &RoundButton::clicked,
[](bool) { qDebug() << "RoundButton::clicked()"; });
// runtime loop
return app.exec();
}
The corresponding Qt project file testQPushButtonMask.pro
SOURCES = testQPushButtonMask.cc
QT += widgets
Compiled and tested on cygwin64:
$ qmake-qt5 testQPushButtonMask.pro
$ make && ./testQPushButtonMask
Qt Version: 5.9.4
MainWindow::mousePressEvent: QPoint(23,22)
MainWindow::mousePressEvent: QPoint(62,24)
MainWindow::mousePressEvent: QPoint(62,61)
MainWindow::mousePressEvent: QPoint(22,60)
RoundButton::clicked()
Concerning the output:
I clicked into the four corners of button.
I clicked on the center of button.
I have created an Image Viewer application that opens and saves an image and load the image on QLabel,then I created a ScrollArea to scroll for large images, in my second step I am trying to draw a selection rectangle to select a specific sub area , the steps I have taken to paint the selection rectangle as follows:
1- I used an PaintEvent to paint the rectangle.
2- I used MouseEvent to select the sub area.
The problem is, when I run my code, I can draw the rectangle on the QWidget but not on the ScrollArea.
Here is my code:
in imageviewer.h
class ImageViewer : public QWidget{
Q_OBJECT
public:
explicit ImageViewer(QWidget *parent = 0);
~ImageViewer();
private:
Ui::ImageViewer *ui;
private slots:
void on_openButton_pressed();
void on_saveButton_pressed();
private:
QPixmap image;
QImage *imageObject;
bool selectionStarted;
QRect selectionRect;
QMenu contextMenu;
protected:
void paintEvent(QPaintEvent *e);
void mousePressEvent(QMouseEvent *e);
void mouseMoveEvent(QMouseEvent *e);
void mouseReleaseEvent(QMouseEvent *e);
};
this is imageviewer.cpp
ImageViewer::ImageViewer(QWidget *parent) :
QWidget(parent),
ui(new Ui::ImageViewer)
{
ui->setupUi(this);
ui->scrollArea->setWidget(ui->imageLabel);
}
open & save functions:
void ImageViewer::on_openButton_pressed()
{
QString imagePath = QFileDialog::getOpenFileName(this, tr("Open File") , "" ,
tr("JPEG (*.jpg *.jpeg);;PNG (*.png);;BMP (*.bmp)"));
imageObject = new QImage();
imageObject->load(imagePath);
image = QPixmap::fromImage(*imageObject);
ui->imageLabel->setPixmap(image);
ui->imageLabel->adjustSize();
}
void ImageViewer::on_saveButton_pressed()
{
QString imagePath = QFileDialog::getSaveFileName(this, tr("Save File") , "" ,
tr("JPEG (*.jpg *.jpeg);;PNG (*.png);;BMP (*.bmp)"));
*imageObject = image.toImage();
imageObject->save(imagePath);
}
paint & mouse event functions:
void ImageViewer::paintEvent(QPaintEvent *e){
QWidget::paintEvent(e);
QPainter painter(this);
painter.setPen(QPen(QBrush(QColor(0,0,0,180)),1,Qt::DashLine));
painter.setBrush(QBrush(QColor(255,255,255,120)));
painter.drawRect(selectionRect);
}
void ImageViewer::mousePressEvent(QMouseEvent *e){
if(e->button() == Qt::RightButton){
if(selectionRect.contains(e->pos()))
contextMenu.exec(this->mapToGlobal(e->pos()));
}
else{
selectionStarted = true;
selectionRect.setTopLeft(e->pos());
selectionRect.setBottomRight(e->pos());
}
}
void ImageViewer::mouseMoveEvent(QMouseEvent *e){
if(selectionStarted){
selectionRect.setBottomRight(e->pos());
repaint();
}
}
void ImageViewer::mouseReleaseEvent(QMouseEvent *e){
selectionStarted = false;
}
and this is a screenshot for my application
How can I draw a selection rectangle on QScrollArea?
You need QRubberBand which supposed to be directly applied to ui->imageLabel widget you use to display an image you want to scroll. Whether or not you should overload QLabel for ui->imageLabel is a question of implementation. Please see the example for mouse events which, of course better be applied to your label image class.
I understand from the way the code looks you used Qt Designer? That complicates overriding that label class but you can either not use .ui file or use event filter for trapping all the events for the given object.
What you currently have can be finally polished enough to be good for actual use, of course. It just makes much more effort for you. You can avoid overloading paintEvent etc. and the key is to apply the right approach directly where it needs to be applied.
// the example applied to authors code as requested
class MyImageLabel : public QLabel
{
public:
explicit MyImageLabel(QWidget *parent = 0) : QLabel(parent), rubberBand(0) {}
private:
QRubberBand* rubberBand;
QPoint origin;
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event)
};
void MyImageLabel::mousePressEvent(QMouseEvent *event)
{
origin = event->pos();
if (!rubberBand)
rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
rubberBand->setGeometry(QRect(origin, QSize()));
rubberBand->show();
}
void MyImageLabel::mouseMoveEvent(QMouseEvent *event)
{
rubberBand->setGeometry(QRect(origin, event->pos()).normalized());
}
void MyImageLabel::mouseReleaseEvent(QMouseEvent *event)
{
rubberBand->hide();
// determine selection, for example using QRect::intersects()
// and QRect::contains().
}
ImageViewer::ImageViewer(QWidget *parent) :
QWidget(parent),
ui(new Ui::ImageViewer)
{
ui->setupUi(this);
// resolve this better than:
delete ui->imageLabel; // you already have the QLabel object here?
ui->imageLabel = new MyImageLabel;
ui->scrollArea->setWidget(ui->imageLabel);
}
I was trying to do a simple animation on QGrapichScene. I implemented void QGraphicsItem::advance(int) in class, that inherites QGraphicsItem, but after calling advance() my item not redrawn. In colliding mice example it works.
What have I done wrong?
Here is my code:
widget.h:
class Widget : public QWidget
{
Q_OBJECT
private:
QGraphicsScene *scene;
QGraphicsView *view;
QHBoxLayout *layout;
QTimer t;
public:
Widget(QWidget *parent = 0);
~Widget();
};
widget.cpp:
Widget::Widget(QWidget *parent) : QWidget(parent)
{
layout = new QHBoxLayout(this);
view = new QGraphicsView(this);
scene = new QGraphicsScene(0, 0, 400, 400, view);
scene->addItem(new MyItem());
view->setScene(scene);
layout->addWidget(view);
setLayout(layout);
connect(&t, SIGNAL(timeout()), scene, SLOT(advance()));
t.start(100);
}
Widget::~Widget()
{
}
my_item.h:
class MyItem : public QGraphicsItem
{
private:
QRect bRect;
enum directon { left, right };
directon currentDir;
protected:
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
public:
MyItem(int w = 20);
virtual void advance(int phase);
virtual QRectF boundingRect() const
{ return QRectF(bRect); }
};
my_item.cpp:
MyItem::MyItem(int w)
{
currentDir = right;
bRect = QRect(0, 0, w, w);
}
void MyItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
qDebug() << "In void MyItem::paint(QPainter*, "
"const QStyleOptionGraphicsItem*, "
"QWidget*)";
painter->fillRect(bRect, Qt::red);
}
void MyItem::advance(int phase)
{
qDebug() << "In void MyItem::advance(int);"
<< "Phase =" << phase;
if(!phase)
return;
// Than move item to new positon...
}
It's on you to inform the graphics scene that your item's contents have changed. You have to call update() at the end of advance(). If you're simply moving the item, without changing its contents, then you don't need to call update() of course - the scene will detect such changes automatically.
I found something strange:
connect(&timer, SIGNAL(timeout()), scene, SLOT(advance()));
The slot need to combined after the Widget is shown, or the slot will never been called!
As the Qt example shown, you can combine it in the main function.
I have this:
mapdialog2.h
namespace Ui {
class MapDialog2;
}
class MapDialog2 : public QDialog
{
Q_OBJECT
public:
explicit MapDialog2(QWidget *parent = 0);
~MapDialog2();
protected:
void closeEvent(QCloseEvent * event);
void reject();
void mousePressEvent(QGraphicsSceneMouseEvent *event);
void wheelEvent(QWheelEvent* event);
private:
Ui::MapDialog2 *ui;
QGraphicsScene *scene;
};
and this:
mapdialog2.cpp
MapDialog2::MapDialog2(QWidget *parent) :
QDialog(parent),
ui(new Ui::MapDialog2)
{
ui->setupUi(this);
QGraphicsScene* scene = new QGraphicsScene(this);
scene->addPixmap(QPixmap(":/new/image/project_images/Screenshot from 2015-03-09 15:37:24.png"));
scene->activePanel();
ui->graphicsView->setDragMode(QGraphicsView::ScrollHandDrag);
for(int i=0; i<10; i++) {
scene->addRect(50+i*30,100,50,100, QColor(0,200,0,100),QColor(20+i*20,0,0,100));
}
ui->graphicsView->setScene(scene);
}
void QGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
qDebug() << "Debug Message";
QPointF mousePos(event->buttonDownScenePos(Qt::LeftButton).x(),
event->buttonDownScenePos(Qt::LeftButton).y());
qDebug() << mousePos;
}
I want to capture the mouse position when I press the left mouse button. But that function is never called. No presses are ever captured. Why?
The zoom and panning is all working okay, but I can't capture mouse events on the scene. I Think the problem lies with the fact that I should capture within the scene and not the QGraphisView, or the QWidget for that matter.