Wednesday, August 11, 2010

Automatic Connections: using Qt signals and slots the easy way

One key and distinctive feature of Qt framework is the use of signals and slots to connect widgets and related actions. But as powerful the feature is, it may look compelling to a lot of developers not used to such a model, and it may take some time at the beginning to get used to understand how to use signals and slots properly. However, since version 4.4, we can relay on auto-connections to simplify using this feature.

Back in the old days, signals and slots connections were set up for compile time (or even run time) manually, where developers used the following sentence:
connect(btnUpdate, SIGNAL(clicked()), this, SLOT(processUpdate()));
this is, we stated the sender object's name, the signal we want to connect, the receiver object's name and the slot to connect the signal to.

Now there's an automatic way to connect signals and slots by means of QMetaObject's ability to make connections between signals and suitably-named slots. And that's the key: if we use an appropriate naming convention, signals and slots will be properly connected without the need to write additional code for that to happen. So by declaring and implementing a slot with a name that follows the following convention:
void on_<widget name="">_<signal name="">(<signal parameters="">);
uic (the User Interface Compiler of Qt) will automatically generate code in the dialog's setupUi() function to connect button's signal with dialog's slot.

So back to our example, the class implementing the slot must define it like this:
class UpdateDialog : public QDialog, private Ui::UpdateDialog
{
    Q_OBJECT

public:
    UpdateDialog(QWidget *parent = 0);

private slots:
    void on_btnUpdate_clicked();
    ...
};
We then write the method's implementatio to carry on an action when the signal is emitted:
...
UpdateDialog::on_btnUpdate_clicked()
{
    // start update process
    verifyUpdateStatus();
    doUpdate();
    notifyUpdateStatus();
    ...
}
In brief, we have seen that by using automatic connection of signals and slots we can count on both a standard naming convention and at the same time an explicit interface for designers to embrace. If the proper source code implements such a given interface, interface designers can later check that everything is working fine without the need to code.

1 comment:

  1. I found this out by accident! It took me a little while to realise why my slots were running twice when I had only made the connection once (or so I thought). Thanks for your blog post that allowed me to put my mind at rest.

    ReplyDelete