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

NOOB Signals and Slots



  • I'm a beginner, and I've run into a question when it comes to Signals and Slots. What I've done so far is connect a QML onClick (signal) event to a slot in a C++ class, then have that class emit its own signal. Now I need another C++ class slot to listen to that signal. I'm having trouble connecting the signal to the slot though. I'm trying to connect C++ class A's signal to C++ class B's slot in C++ class B's constructor. I want to avoid connections in main, because I'm going to be creating more complex applications on the future. Here is some code to help visualize:

    //DataObject HEADER
    class DataObject : public QObject
    {
        Q_OBJECT
    public:
        DataObject(QObject *parent=0);
        DataObject(const QString &name, const double &max, const double &min, QObject *parent=0);
        QString name() const;
        void setName(const QString &name);
        double max() const;
        void setMax(const double &max);
        double min() const;
        void setMin(const double &min);
    signals:
        void nameChanged();
        void maxChanged();
        void minChanged();
        void updateSelection(); //THIS IS THE SIGNAL I'M SENDING
    public slots:
        void newSelection()  //THIS IS INVOKED BY THE QML
        {
            qDebug() << "Called the C++ slot";
            emit updateSelection();
        }
    private:
        QString m_name;
        double m_max;
        double m_min;
      };
    
    //UseData HEADER
    class UseData : public QObject
    {
        Q_OBJECT
    public:
        UseData(QObject *parent=0);    
    signals:
    public slots:
        void dataRefresh();  //THE SLOT I WANT TO INVOKE
    private:
    };
    
    //UseData DEFINITION
    UseData::UseData(QObject *parent) : QObject(parent)
    {
        connect(sender, SIGNAL(updateSelection()), this, SLOT(dataRefresh()));  //ERROR HERE
    }
    void UseData::dataRefresh()
    {
        qDebug() << "Called UseData Slot";
    }
    

    The error I'm getting says, "'QObject::sender': function call missing argument list; use'&QObject::sender' to create a pointer to member

    Any help would be great!



  • Hello & welcome,

    The problem is that in the scope where you call QObject::connect() (namely in the constructor of your UseData class) you don't have any object named sender. The first parameter of the QObject::connect() method needs to be a valid QObject that emits the signal you are going to connect.
    If the sender of the updateSelection() signal you are caring about isn't known/accessible in your UserData constructor you have to make the connect outside of the class (or anywhere else where the sender object is known).



  • @admiral142

    you need the pointer of the class DataObject in the class UseData. . The "sender" in the connect hast to be the pointe of the class DataObject.

    connect(objectA, SIGNAL(xxx()), objectB, SLOT(xxxx()));
    //this connect() is old. Please check the new syntax of the connecct() from 5.7(if your are using latest version)

    class UseData : public QObject
    {
        Q_OBJECT
    public:
        UseData(QObject *parent=0);   
        DataObject*  dataobject;	//******** you need the object of the class where the signal is 
    signals:
    public slots:
        void dataRefresh();  
    private:
    };
    
    //UseData DEFINITION
    UseData::UseData(QObject *parent) : QObject(parent)
    {
        connect(dataobject, SIGNAL(updateSelection()), this, SLOT(dataRefresh()));  //use that class object to connect
    }
    void UseData::dataRefresh()
    {
        qDebug() << "Called UseData Slot";
    }


  • Ok, that makes sense. The problem then becomes that DataObject is being used in a QList. So I'm newing up instances of it to add to the QList. My question is, if I were to connect a general instance of DataObject in my main to my general instance of UseData in my main, would any signal from any DataObject then reach my UseData class? I believe that's a scope question. Here is what I'm thinking:

    int main(int argc, char *argv[])
    {
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
        QGuiApplication app(argc, argv);
    
        QQmlApplicationEngine engine;
    
        UseData useData;  //GENERAL INSTANCE OF UseData
        DataObject dataObject  //ADDED - GENERAL INSTANCE OF DataObject
    
        QList<QObject*> dataList;
        dataList.append(new DataObject("This", 100, 0, 80, 50));
        dataList.append(new DataObject("That", 100, 0, 75, 70));
        
        connect(dataObject, &dataObject::updateSelection, useData, &useData::dataRefresh );  //ADDED - Signal and Slot connection.  Correct Syntax?
    
        QQmlContext *ctxt = engine.rootContext();
        ctxt->setContextProperty("pidList", QVariant::fromValue(dataList));
        ctxt->setContextProperty("activeGauge", &gaugeData);
    
        engine.load(QUrl(QLatin1String("qrc:/main.qml")));
    
        return app.exec();
    

    Would that do it? Thanks again!



  • @Ni.Sumi Wouldn't including the DataObject class in my UseData class cause them to become tightly coupled?


Log in to reply