Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct
Automatic generation and linking of signals and slots (at run-time or compile-time)
As long as I know, the Qt Signals&Slots mechanism is a static, compile-time mechanism. You cannot create a signal and a slot at runtime and connect each other. Unfortunately, I just stumbled upon a case in which it would be very useful to have such a possibility.
I'm trying to create a form (a dialog box) that shows a database record and allows the user to edit it. In other terms, the typical DB Edit Form you can see in many DB front-ends. Here, I can easily query the underlying model (it is a QSqlTableModel in my case) and get both the name and the type of the fields so I can create both the widgets and the labels required to populate the form. I can even connect the widgets to the database table automagically thanks to the very fine QDataWidgetsMapper.
What I cannot do anymore is connecting my runtime-generated widgets to signals and slots. In my previous version, I used these links to enable/disable a couple of buttons when the user changed the text in the editLines. Now that the name of the widgets is decided at runtime, I cannot do that anymore.
Put aside my specific, temporary and very personal case, I thought that this was a aspect of Qt worth a deeper investigation so I went at Google and looked around.
It seems there are at least three different ways to face this "limit" (if we can call this a "limit"...):
To some extent, you can use (or abuse) the automatic connection mechanism provided by Qt, as described here: "A Qt Way: automatic connection":http://qtway.blogspot.com/2010/08/automatic-connections-using-qt-signals.html
It seems, as well, that someone (smarter and more skilled than me, for sure) was able to get a (partial?) solution by using a template class, as described here: "Qt Centre: Add signals and Slots at runtime":http://www.qtcentre.org/threads/14395-add-signal-slots-at-runtime
And, of course, there is the "official" solution proposed by Nokia/Trolltech: "QT Quarterly 16":http://doc.qt.nokia.com/qq/qq16-dynamicqobject.html
A few more solutions are examined in this old thread: "Qt3: Creating Signals in Runtime":http://lists.trolltech.com/qt-interest/2005-08/thread00658-0.html
I would add to this list some kind of static code generation, maybe based on "COG":http://www.python.org/about/success/cog/ or on some other "template engine" used in the web dev arena ("Cheetah":http://cheetahtemplate.org/, "Smarty":http://www.smarty.net/, etc.)
Now, I would be happy to hear some consideration/comment on this topic from the people who was here long before I arrived.
Does anybody else had to face a similar problem? How solved it?
Did he/she used a run-time approach? If so, which one?
Did he/she used a compile-time approach? Did he/she (ab)used the moc for this? Used a different code generator (COG, Ruby, Python...)? What else?
What do you think (or even feel) about the solution I listed above? Which ones you would use, in case of need, and which ones you would avoid?
ludde last edited by
Have you had a look at the "new variant of QObject::connect()":http://developer.qt.nokia.com/doc/qt-4.8/qobject.html#connect-2 in Qt 4.8 that takes "QMetaMethods":http://developer.qt.nokia.com/doc/qt-4.8/qmetamethod.html as arguments instead of strings? I haven't used it myself, but believe it might have been added to enable something like what you are trying to do.
Thanks for the suggestion, Ludde. It looks like I can use this method for my purpose (and that it represents a all-round solution to the problem I devised in my original post). At the moment I'm still searching and studying the available documentation (forum discussions, blog articles and Qt bugtracker original suggestion) in order to understand how exactly this method was intended to be used. I hope to adopt it in a couple of days.
ludde last edited by
You're welcome! Please let us know how/if it worked when you've tried it.
actually, I ended up using a much simpler solution that does not involve QObject::connect(). It turned out that, thinking twice to my problem, it can be solved with "regular" Qt C++ code.
I'm still working on it (in my freetime) and I hope I can show you some interesting code in a few weeks.
PS: Qt is just fantastic. You just have to make a wish and it promptly supplies you with the required functionality. It's like Santa Claus...