PDA

View Full Version : Signals/slots best practices?



gfunk
17th August 2007, 01:10
Hey there,

I've been looking at the maintainability of other people's code when they've written stuff that uses signals and slots, and have been starting to get the feeling that it's just hard to read - when the signal arrives, the code jumps to the slot function, which seems very much like a GOTO statement, and it can be tiring to find out which signal called the slot, and where the code goes to next after the slot function has completed. I'm wondering what sorts of "best practices" people use to make signal/slots code more readable and easier to follow.

wysota
17th August 2007, 03:22
If a slot starts, it starts from the event loop. If a slot completes, it returns to the event loop (QApplication::exec()). That's not technically always true, but that's the abstraction that is safe to assume. With "goto" there is no comming back while a slot is just a regular function call. You can use a debugger to trace such calls like any other functions. If you need more, use a signal spy.

Brandybuck
17th August 2007, 20:07
Withing a thread, signals are synchronous by default. Emitting a signal is like making a direct function call to the slot. If you're comfortable with function calls jumping to the code in the called function, then you should be comfortable emitting signals.

Where it may get confusing is that the UI is event driven. When the user clicks the mouse on a QPushButton out in the UI, an event will be added to the event cue, and it will subsequently generated a clicked() signal. Thus, you will never have linear program flow.

Don't let the name fool you, this is not at all like a "signal" in Unix. Qt signals will never interrupt your program's flow. Unless you call processEvents(), your function will complete before any signals get sent in response of UI events.

Michiel
17th August 2007, 20:30
I've always thought of signals and slots approximately like this (only more complex). Pseudo-code:


template <typeList T>
class Signal {
public void emit(T params) {
foreach (slot in _slotList) {
slot(params);
}
}

public void connectSlot(void slot(T)) {
_slotList.pushBack(slot);
}

private list<void function(T)> _slotList;
}

You know what I mean. It's like the observer pattern, only more flexible.

(I never thought the event loop had anything to do with it.)

wysota
17th August 2007, 20:52
(I never thought the event loop had anything to do with it.)

It's an abstraction. If you disable direct connections, all slots will be delivered from within the event loop (that's the only safe place to disturb an event driven thread). Signals and slots as a paradigm are asynchronous and only as a simplification they are delivered in a synchronous way within a thread like Brandybuck said.

Brandybuck
18th August 2007, 19:50
(I never thought the event loop had anything to do with it.)
Most signals will be emitted as a response to an event. You click the mouse, for example, and you get a clicked() signal. That's why most GUI programs are said to be "event driven". The good part about Qt is that it abstacts the events with meaningful signals.