Problem with custom signals and slots
Hello I am beginner in Qt framework and I can't seem to find an answer to my problem, so I eventually came here.
I am writing simple app for transferring data via RS232 using QextSerialPort open library, and I stopped at the beginning.
Basically I use event-driven notifications of device connection events with this code :
connect(&port_enumerator, SIGNAL(deviceDiscovered(const QextPortInfo &)),
this, SLOT(onDeviceDiscovered(const QextPortInfo &)));
connect(&port_enumerator, SIGNAL(deviceRemoved(const QextPortInfo &)),
this, SLOT(onDeviceRemoved(const QextPortInfo &)));@
and it works just fine. So that my port_enumerator which is QextSerialEnumerator object from this library is updated each time I install a new device.
However, each time my port_enumerator changes I want to change my ComboBox, in which I choose my ports, to do that I wanted to create another signal and slot, so that if a new device is discovered I get a refresh on ComboBox. And I can't seem to make it...
I made something like it
@connect(&ports, SIGNAL(PortListChanged(const QList<QextPortInfo> &)),
this, SLOT(setPortList(const QList<QextPortInfo> &)));@
But then how exactly are these custom signal and slot supposed to look like ? Can it even be done, I am pretty sure that with this powerful framework anything can be done.
Thanks in advance.
Custom signals and custom slots look exactly how you code them to look. The custom slot does whatever you code it to do.
If your first code snippet is in your UI class with access to the combo box then you don't need another signal or slot at all. Have onDeviceDiscovered() and onDeviceRemoved() update their list of ports (it seems you maintain such as list already) and then call a private helper to reload the combo box.
Hmm, what do you mean exactly? Do you mean to modify onDeviceDiscovered() function, because I can't do that :/
What is "this" then? Is onDeviceDiscovered() not a slot of your own writing?
You are connecting a signal originating in the port_enumerator object to a slot onDeviceDiscovered() in the the object "this" (of whatever type that is). port_enumerator is a QextSerialEnumerator and part of the QextSerialPort library. "this" is not part of the library, "this" is an object of a class you have written. This onDeviceDiscovered() slot has to be written by you; it does not magically exist.
Taken from documentation:
bq. To enable event-driven notification of device connection events, first call setUpNotifications() and then connect to the deviceDiscovered() and deviceRemoved() signals. Event-driven behavior is currently available only on Windows and OS X.
QextSerialEnumerator* enumerator = new QextSerialEnumerator();
connect(enumerator, SIGNAL(deviceDiscovered(const QextPortInfo &)),
myClass, SLOT(onDeviceDiscovered(const QextPortInfo &)));
connect(enumerator, SIGNAL(deviceRemoved(const QextPortInfo &)),
myClass, SLOT(onDeviceRemoved(const QextPortInfo &)));@
Well it says to use myClass, so I put "this" there, and it works. But that's not the point, I wanted to write a custom signal that will get triggered once QextSerialEnumerator is changed and I don't know how :/
Run your program and look at the output it generates to the console or debug window. You will find there is a message similar to this:
bq. Object::connect: No such slot YourClass::onDeviceDiscovered(const QextPortInfo &)
indicating that it is not working. Connections happen at run time not compile time.
To write a slot you declare a function in a class derived from QObject and then you implement it. It's just a C++ member function. To make it a slot you simply add the "slots" pseudo-keyword to the relevant access specifier. Here is a simple example with a slot called setValue(int):
You need to declare YourClass::onDeviceDiscovered(const QextPortInfo &info) and provide an implementation. In that implementation you can update the combo box.