LEGO clickable QLabel

I’ve seen a bunch of questions on how to make images clickable in QT on the huge abyss that is the Internet. Not many of the poor peeps with queries have them answered however, even if the solution is pretty simple.

I’ve zipped the final solution to this example and put it online, go ahead and download the source code. If you can’t get the code up and running, please follow our guide on how to set up your Python IDE together with QT.
Lets start with the part where the problem first shows itself. You’ve found a amazing button image and you want to add it to your GUI. Now, the best way you know showing this button is by adding it to a QLabel, naturally. You connect the signals and slots beautifully and run your code. You click the image, and nothing happens. You scratch your head and ask yourself “What did I miss?” as you head to the coffee machine.
Lets see how that code you wrote looked:

MainUI.py

A nice little QT Widget that has an image, that we want to click.

Main.py

This is the Main class, nothing much to comment about this code I guess. We import the necessary stuff and our MainUi class. We init the QApplication and the MainUi and show it.


Looks as if it might work, but it doesn’t. The reason for this is that the QLabel doesn’t emit the clicked() signal. Now lets see how we can fix it!

How to make the image clickable

To enable the click signal we need to extend QLabel and create our own Label class. You can call it whatever you want, but I call i ExtendedLabel. It is implemented as shown below.

ExtendedQLabel.py

This class extends QLabel. It fetches the mouseReleaseEvent and emits an “clicked()” signal. We can then connect to this signal, thus making the QLabel clickable.

What we’ve done here is that we’ve taken the QLabel and added a method that captures the mouseReleaseEvent. That method then emits the “clicked()” signal we are used to get from buttons. Now the ExtendedLabel can be used exactly how you would use a button.

MainUi.py

Lets head back to our MainUi class. Import ExtendedQLabel and replace QLabel with ExtendedQlabel in this class to make it work. The “clicked()” event in ExtendedLable is now connected to the buttonClicked() method.

Now when we click the image a clicked() signal will be emitted and since it is connected to buttonClicked() this method will be called.

Further extension of QLabel

Now what more can we do? Just to show you that other mouse events can be captured I’ll show you and example on how to get mouse wheel events from our QLabel. It is basically done the same way as above. With the mouse wheel event however it might be nice to send in what direction and with how much the scroll should be performed.

ExtendedQLabel.py

Lets start with our extended QLabel. Apart from the code that we wrote earlier we have now added a wheelEvent method that captures the wheel event. In that method we emit a signal with a parameter that holds the direction and amount that was scrolled.

MainUi.py

We need to connect the scroll signal to a slot in MainUi as well. The code below shows how the signal is connected to wheelScrolled() where the image and window is resized depending on scrollAmount. I didn’t spend time on making the image scale proportionally so it won’t look good scaled. I also set the QLabel to scale its content when resized.

Conclution

The QLabel can easily be extended to capture and emit whatever signal we would like it to simply by extending it. One might wonder why the original QLabel doesn’t emit the clicked() signal in its original form. Many poor QT programmers must have scratched their heads and wondering how to solve this problem. I hope this tutorial (example) has been usefull and if you find something to be wrong or simply enjoyed the post, please leave a comment!
If you have question on how to build your PyQT python application please read our guide here at popdevelop: Setting Up IDE and Creating A Cross Platform QT Python Application.

Further Reading

The solutions on how to make the QLabel clickable are scarce. There are however a couple of solutions out there.