-1

Below is a working C++ QT code that simply displays an image with mouse events. To implement the events, I nested a custom QGraphicsPixmapItem class within my MainWindow class. The problem I am having is accessing and modifying the private variable a in the MainWindow outer class from within the event function of the MainWindow::myGraphicsPixmapItem inner class. I have tried and failed to pass mainWindow by reference or by using friend class.

I am using the event implementation from How to get mouse press event on a QPixmap but have also tried event filters without much luck. Help appreciated.

main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[ ])
{
QApplication app(argc, argv);
MainWindow mainWindow;
mainWindow.show();
return app.exec();
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QCoreApplication>
#include <QMainWindow>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsPixmapItem>

class MainWindow : public QMainWindow
{
        Q_OBJECT;
    public:
        explicit MainWindow(QWidget *parent = 0);
    private:
        QGraphicsScene *scene;
        QGraphicsView *view;
        int a; //inaccessible from myGraphicsPixmapItem
        class myGraphicsPixmapItem;
        QGraphicsPixmapItem *img;
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"

class MainWindow::myGraphicsPixmapItem: public QGraphicsPixmapItem {
public:
    myGraphicsPixmapItem(QPixmap pixmap): QGraphicsPixmapItem(pixmap) {};
    ~myGraphicsPixmapItem() {};
    void mouseReleaseEvent(QGraphicsSceneMouseEvent* event){
        qDebug("Mouse release Detected!");
        a = 0; //problem
    };
    void mousePressEvent(QGraphicsSceneMouseEvent* event) {
        qDebug("Mouse press Detected!");
    };
};
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
    view = new QGraphicsView(this);
    scene = new QGraphicsScene;
    view->setScene(scene);
    setCentralWidget(view);
    img = new myGraphicsPixmapItem(QPixmap(":/img.bmp"));
    scene->addItem(img);
}

error message

mainwindow.cpp: In member function ‘virtual void MainWindow::myGraphicsPixmapItem::mouseReleaseEvent(QGraphicsSceneMouseEvent*)’:
mainwindow.cpp:9:9: error: invalid use of non-static data member ‘MainWindow::a’
         a = 0;
         ^
In file included from mainwindow.cpp:1:0:
mainwindow.h:18:13: note: declared here
         int a;
             ^
Alec Mitchell
  • 53
  • 1
  • 6

1 Answers1

1

You need an instance of your MainWindow class in order to reference it's non-static members. So the quick fix is to make a static:

// mainwindow.h
class MainWindow
{
private:
    static int a;
}

// mainwindow.cpp
int MainWindow::a = 0;

If that doesn't work for you, then you'll probably need to pass in the MainWindow instance into your myGraphicsPixmapItem constructor and store a member pointer to it.

class MainWindow::myGraphicsPixmapItem: public QGraphicsPixmapItem {
public:
    myGraphicsPixmapItem(MainWindow *window, QPixmap pixmap)
        : QGraphicsPixmapItem(pixmap),
        m_window(window)
    {}
private:
    MainWindow *m_window;
};

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
    img = new myGraphicsPixmapItem(this, QPixmap(":/img.bmp"));
}
JarMan
  • 7,589
  • 1
  • 10
  • 25
  • Thank you for your reply. I have already attempted `static int a;` which gives an error `undefined reference to 'MainWindow::a'`. The second solution, I am unsure how `myGraphicsPixmapItem(QPixmap pixmap): QGraphicsPixmapItem(pixmap) {};` would be modified to account for passing in a MainWindow instance. – Alec Mitchell Sep 18 '20 at 19:06
  • That's because you have to define the static instance. I'll make an edit to my post. – JarMan Sep 18 '20 at 19:07
  • 1
    I also added an edit to show more details on the second option. – JarMan Sep 18 '20 at 19:12
  • The first solution gives the new error `error: qualified-id in declaration before ‘=’ token int MainWindow::a = 0;`. Fortunately, your second solution works perfectly! Note that `a=0;` needs to also be changed to `m_window->a = 0;`. This helps me so much, thank you! – Alec Mitchell Sep 18 '20 at 19:21