When you trying to link the slots and signals together you need to have a QObject::connect and also a emitting, I have created a basic demonstration of this with a QPushButton (link to qt signal and slots, and a QT link for the signal and slots)
The basics of slot(s) and signal(s) with emit(ting) is that a slot is where the emit(ed) signal goes to, when a signal is emit(ed) via a class. For example if you want to link a value changed event then you would emit a signal from within the class and then use that signal with the QObject::connect to link to a slot within class as well.
I have created a class called EmitterTest that has a function within it called
void setValueAndEmit(int v); |
this function will set the value and emit the signal for any QObject::connect to link to a slot. To emit the signal you just
emit valueChanged(v); |
where the valueChanged is the signal within the class definition (you do not define that function because it is kinder like a virtual function).
To allow for these slots and signals to be defined within the class you need to call the macro Q_OBJECT at the top of the class (within a private area) so that all of the necessary attachments to the class can be created (within the moc file associated with the class when you run the qmake later on).
To define a signal and slot there is keywords within the “new” class structure available because of the Q_OBJECT and you can just use them like public and private declarations
public slots : void setValue(int v); signals: void valueChanged(int newV); |
signals are always public in there access rights.
What the code below does is to create a slot and signal with a function that will emit a signal when called (the function that is) so the signal is “fired” off to what ever is listening to it, to connect a signal to a slot you use the QObject::connect as below
EmitterTest em1, em2; QObject::connect(&em1, SIGNAL(valueChanged(int)), &em2, SLOT(setValue(int))); |
where the EmitterTest is the class that I am creating, and the object em1 signal valueChanged is linked to the same class type but different instance of it, em2 slot setValue.
Here is the code below for the full EmitterTest, here is the header file for the emitting test class, if you save as emitting.h
#ifndef EMITTING_H #define EMITTING_H #include <QObject> class EmitterTest : public QObject { Q_OBJECT public: EmitterTest() { mem_value = 0;} int getValue() const { return mem_value;} void setValueAndEmit(int v); // these pick up the emitted signal public slots : void setValue(int v); // these are what are sent out over emitted signals // you do not implement the signals since they are just virtual functions // as such that you call with emit then the value within the parameter(s) // is passed to the slot. signals: void valueChanged(int newV); private: int mem_value; }; #endif // EMITTING_H |
and here is the emitting.cpp file, that holds the main runtime main function.
#include <QObject> #include <QString> #include <stdio.h> #include "emitting.h" void EmitterTest::setValue(int v) { // if the value has changed printf("The new value for %d\n", v); mem_value = v; } void EmitterTest::setValueAndEmit(int v) { // if the value has changed if (v != mem_value) { mem_value = v; emit valueChanged(v); } } int main() { EmitterTest em1, em2; QObject::connect(&em1, SIGNAL(valueChanged(int)), &em2, SLOT(setValue(int))); em1.setValueAndEmit(10); printf("The connection from the object connection em1 %d should equal em2 %d \n", em1.getValue(), em2.getValue()); em2.setValueAndEmit(15); printf("The connection from the object connection em1 %d should NOT equal em2 %d \n", em1.getValue(), em2.getValue()); // the values are not the same because I have not connected them even though I have called the emit within the // setValueAndEmit return 0; } |
if you save them into a directory and then to compile you need to have the qmake and also make (nmake for windows) to make the relevant files to build a qt project. The qmake project creates the necessary .pro file to build the project, the qmake will build the necessary files (moc files) for the make (or nmake) to build the project into a executable file
qmake -project qmake make |
and then there will be a executable file within that directory and the output will be once you have run it
The new value for 10 The connection from the object connection em1 10 should equal em2 10 The connection from the object connection em1 10 should NOT equal em2 15 |
as you notice since I only connected em1 signal to em2, if you change em2 mem_value then em1 does not change as well because the em2 signal is not linked back to the em1 slot.
If you get this error when you are trying out any emit test
undefined reference to `vtable for --- your class name |
, it is because for some reason if you use the Q_OBJECT you need to define the class within a .h (header file) and then it will compile instead if you try and use the same .cpp for the main source code then you will get this error message.