Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Cannot connect a signal from a subclass of QGraphicsScene to a slot in MainWindow



  • Hi experts,

    Here is the MainWindow part of the code:

    #include <QtWidgets/QMainWindow>
    #include "ui_MapEditor.h"
    
    class MapEditor : public QMainWindow {
        Q_OBJECT
    
    public:
        MapEditor(QWidget *parent = Q_NULLPTR);
    
    private slots:
        void on_loadButton_clicked();
        void on_spriteSheetView_clicked(); // <----- The one to link
    
    private:
        Ui::MapEditorClass ui;
        QString mapFilename;
        QPixmap p;
    };
    

    The connect is in on_loadButton_clicked:

    void MapEditor::on_loadButton_clicked() {
        mapFilename = QFileDialog::getOpenFileName(// Omitted);
        if (mapFilename.length() > 0) {
            ui.nameLabel->setText(mapFilename);
        }
        const QPixmap temp(mapFilename);
        p = temp;
    	
        if (!ui.spriteSheetView->scene()) {
            cTextureViewScene* scene = new cTextureViewScene(this);
            ui.spriteSheetView->setScene(scene);
            connect(scene, SIGNAL(scene->clicked), this, SLOT(this->on_spriteSheetView_clicked()));  // <---- doesn't work
        }
        ui.spriteSheetView->scene()->addPixmap(p);
    }
    

    And here is the subclass of QGraphicsScene:

    #include <QGraphicsScene>
    // #include <QtGui>
    #include <QGraphicsSceneMouseEvent>
    
    class cTextureViewScene : public QGraphicsScene {
    public:
    	explicit cTextureViewScene(QObject* parent = Q_NULLPTR) : QGraphicsScene(parent) {}
    protected:
    	void mousePressEvent(QGraphicsSceneMouseEvent* event) override;
    Q_SIGNALS:
    	void clicked(QGraphicsSceneMouseEvent* event); // <----- This to link
    };
    
    void cTextureViewScene::mousePressEvent(QGraphicsSceneMouseEvent* event) {
    	emit clicked(event);
    }
    
    void cTextureViewScene::clicked(QGraphicsSceneMouseEvent* event) {
    	qDebug() << event->scenePos();
    }
    

    I'd like to emit a signal from cTextureViewScene to MapEditor so that on_spriteSheetView_clicked() can be called whenever I click on cTextureViewScene.
    The problem is that the on_spriteSheetView_clicked() was never called, so I figured there is something wrong in connect() in on_loadButton_clicked().



  • OK I got it. I should NOT define a signal function. This is a surprise...



  • @Q74r3wq said in Cannot connect a signal from a subclass of QGraphicsScene to a slot in MainWindow:

            connect(scene, SIGNAL(scene->clicked), this, SLOT(this->on_spriteSheetView_clicked()));  // <---- doesn't work
    

    The use of the SIGNAL and SLOT macros is incorrect. They should be passed the name of the function including any arguments types, but not the instance of the object that they belong to.

        connect(scene, SIGNAL(clicked()), this, SLOT(on_spriteSheetView_clicked()));
    

    Or use the function pointer syntax.

        QObject::connect(scene, &cTextureViewScene::clicked, this, &MapEditor::on_spriteSheetView_clicked);
    

Log in to reply