Unsolved Does the old style connect (using macros) really support duck typing?
-
I am wanting to have my treeview I am designing to be independent of type. I want it to only know about QAbstractItemModel. I tried connecting to some signals that are specific to a derived type QFileSystemModel (FileSystemModel in my case, I needed more features). Using the new style connect it needs to know the type and the pointer type must match. So it requires dynamic_cast. However, if I use old style connect it doesn't seem to need to have a pointer of the correct type to get the signal.
void FileSystemTreeView::setModel(QAbstractItemModel *model) { qInfo() << "FileSystemTreeView::setModel"; if (m_model == model) return; if(m_model){ //auto tmodel = dynamic_cast<QFileSystemModel*>(m_model); //disconnect(tmodel, &QFileSystemModel::directoryLoaded, this, &FileSystemTreeView::directoryLoaded); disconnect(m_model, SIGNAL(directoryLoaded(const QString&)), this, SLOT(directoryLoaded(const QString&))); } m_model = model; //auto tmodel = dynamic_cast<QFileSystemModel*>(m_model); //if(tmodel){ // connect(tmodel, &QFileSystemModel::directoryLoaded, this, &FileSystemTreeView::directoryLoaded); //} connect(m_model, SIGNAL(directoryLoaded(const QString&)), this, SLOT(directoryLoaded(const QString&))); emit modelChanged(); }
This is really useful as I can duck type my classes from different derived types to have a common interface. Also, if something isn't there then it just will fail to connect.
-
Since the old style connect evaluates during runtime, the metatype / connections are known so the connect will not fail. But it's not really usefull to do a connect on a class which does not have to signals/slots since it may fail during runtime then without any (real) notice.
-
Hi
It's two very different systems.
https://doc.qt.io/qt-5/signalsandslots-syntaxes.htmlThe new syntax wins with compile-time evaluation and use of lambdas and frankly any type of
function pointer. But it is type aware.The old system will compile anything
connect(nullptr, SIGNAL("i will eat anything"), this, SLOT("without complains"));and then fail at runtime.
-
@fcarney said in Does the old style connect (using macros) really support duck typing?:
Using the new style connect it needs to know the type and the pointer type must match. So it requires dynamic_cast.
I highly recommend using
qobject_cast
instead of dynamic_cast.This is really useful as I can duck type my classes from different derived types to have a common interface.
It's not really duck typing. Rather, it's a string-lookup at runtime.
All QObjects have a
QMetaObject
attached to them. This object allows you to query the list of available signals and slots, without knowing the object's type:- https://doc.qt.io/qt-5/qmetaobject.html#indexOfSignal
- https://doc.qt.io/qt-5/qmetaobject.html#indexOfSlot
Again, this lookup is based only on the name of the signal/slot and the name of the parameter types. This system does not understand C++ types -- it will fail if you use a typedef or a namespace (see the article that @mrjj linked).
If you want to know how the internals work, read https://woboq.com/blog/how-qt-signals-slots-work.html