Unsolved 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 yourUseData
class) you don't have any object namedsender
. The first parameter of theQObject::connect()
method needs to be a validQObject
that emits the signal you are going to connect.
If the sender of theupdateSelection()
signal you are caring about isn't known/accessible in yourUserData
constructor you have to make the connect outside of the class (or anywhere else where the sender object is known). -
you need the pointer of the
class DataObject
in theclass 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?