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
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.