Pergunta

I'm learning PyQt (I haven't used C++ Qt before).

I don't understand the reason for signals and slots. That is, it seems I can do everything by calling the methods of classes directly. Doing so seems more Pythonic, uses less code and is easier to read. What am I missing?

For clarification, I'm asking why I would do this:

def mouseReleaseEvent(self):  
    self.clicksignal.connect(ui.iconClicked) 
    self.clicksignal.emit()

when I can do this:

def mouseReleaseEvent(self): 
    ui.iconClicked()
Foi útil?

Solução

The reason signals and slots exist is because you cannot change the GUI from any other thread of the application except the UI thread.

If you have some heavy CPU intensive calculation to do, or any task that waits for IO or something like that... if you do it the UI thread (for example if you fetch a url or something that lasts some time), your UI thread will be busy, and the GUI event loop wont be able to update itself, so the GUI will seem frozen.

To do these kind of operations. you execute them in a separate (background worker) thread, so the UI thread can continue updating the GUI.

Now the problem is that you cannot access the elements of the GUI and change their state from any other thread except the UI thread. So signals and slots are introduced. When you emit a signal it is guaranteed to be caught in the UI thread, and the slot will be executed in the UI thread.

I'm not exactly sure what you try to accomplish in your example, but this is the main reason why signals and slots exist. Basically UI thread should only deal with the UI, and everything else should be done in the background worker thread that sends a signal that gets caught in the UI thread and the slot that update the GUI is executed in the UI thread.

Outras dicas

Well... yes, you can. But you need to think bigger. In your example code, caller of mouseReleaseEvent must have the reference to the object that receives the notification, and explicitly invoke appropriate method. Using slot & signals mechanism decouples event producer (e.g. widget) from event consumer - pretty much arbitrary other object. This makes setting up communication and control flow easier and external to the low-level UI components, which is the good thing. It also makes such components reusable - by moving wiring code outside, we make it independent of the application logic.

In addition to the answers by @ViktorKerkez and @Wilbur, signals and slots provide a notification system of fire and forget, as well as decoupling classes.

A great advantage of this is that a class can emit a signal, not knowing what or who is going to receive the message. It may be just one object that has a slot connected, or it could be dozens. Alternatively, you may want a single class with one slot that is connected to multiple signals. So it can be used as a notification system.

For example, imagine a program where many different types of objects send information to a log. The objects simply emit a Log(text) signal and do not care about what actually does the logging. These signals can be connected to a log class which can be either logging to a file, over a network, to the screen, or all at once. The objects logging don't care.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top