In Qt, we have an alternative to the callback technique: We use signals and slots. A signal is emitted when a particular event occurs. Qt's widgets have many predefined signals, but we can always subclass widgets to add our own signals to them. A slot is a function that is called in response to a particular signal. To use it, create a QTimer, connect its timeout signal to the appropriate slots, and call start. From then on, it will emit the timeout signal at constant intervals. In this example, we'll use Qt Console application. The first example uses three separate handler functions, or slots, for each check box. The second example uses a single slot for all three check boxes. Follow the tutorial steps below to build the two QCheckBox example programs. Create a New Qt Widgets Application. Open Qt Creator and start a new Qt Widgets Application called checkbox. In between creating the thread and starting it you do: QObject::connect(thread, SIGNAL(started), &a, SLOT(processList), Qt::AutoConnection); which means that when the thread starts it will immediately start processing the first slot processList. Only after this slot finishes will the thread be able to process the next event from its event loop.
Build complex application behaviours using signals and slots, and override widget event handling with custom events.
As already described, every interaction the user has with a Qt application causes an Event. There are multiple types of event, each representing a difference type of interaction — e.g. mouse or keyboard events.
Events that occur are passed to the event-specific handler on the widget where the interaction occurred. For example, clicking on a widget will cause a QMouseEvent
to be sent to the .mousePressEvent
event handler on the widget. This handler can interrogate the event to find out information, such as what triggered the event and where specifically it occurred.
You can intercept events by subclassing and overriding the handler function on the class, as you would for any other function. You can choose to filter, modify, or ignore events, passing them through to the normal handler for the event by calling the parent class function with super()
.
However, imagine you want to catch an event on 20 different buttons. Subclassing like this now becomes an incredibly tedious way of catching, interpreting and handling these events.
Thankfully Qt offers a neater approach to receiving notification of things happening in your application: Signals.
Instead of intercepting raw events, signals allow you to 'listen' for notifications of specific occurrences within your application. While these can be similar to events — a click on a button — they can also be more nuanced — updated text in a box. Data can also be sent alongside a signal - so as well as being notified of the updated text you can also receive it.
The receivers of signals are called Slots in Qt terminology. A number of standard slots are provided on Qt classes to allow you to wire together different parts of your application. However, you can also use any Python function as a slot, and therefore receive the message yourself.
Load up a fresh copy of `MyApp_window.py` and save it under a new name for this section. The code is copied below if you don't have it yet.
First, let's look at the signals available for our QMainWindow
. You can find this information in the Qt documentation. Scroll down to the Signals section to see the signals implemented for this class.
Qt 5 Documentation — QMainWindow Signals
As you can see, alongside the two QMainWindow
signals, there are 4 signals inherited from QWidget
and 2 signals inherited from Object
. If you click through to the QWidget
signal documentation you can see a .windowTitleChanged
signal implemented here. Next we'll demonstrate that signal within our application.
Qt 5 Documentation — Widget Signals
The code below gives a few examples of using the windowTitleChanged
signal.
Try commenting out the different signals and seeing the effect on what the slot prints.
We start by creating a function that will behave as a ‘slot’ for our signals.
Then we use .connect on the .windowTitleChanged
signal. We pass the function that we want to be called with the signal data. In this case the signal sends a string, containing the new window title.
If we run that, we see that we receive the notification that the window title has changed.
Next, let’s take a quick look at events. Thanks to signals, for most purposes you can happily avoid using events in Qt, but it’s important to understand how they work for when they are necessary.
As an example, we're going to intercept the .contextMenuEvent
on QMainWindow
. This event is fired whenever a context menu is about to be shown, and is passed a single value event
of type QContextMenuEvent
.
To intercept the event, we simply override the object method with our new method of the same name. So in this case we can create a method on our MainWindow
subclass with the name contextMenuEvent
and it will receive all events of this type.
If you add the above method to your MainWindow
class and run your program you will discover that right-clicking in your window now displays the message in the print statement.
Sometimes you may wish to intercept an event, yet still trigger the default (parent) event handler. You can do this by calling the event handler on the parent class using super
as normal for Python class methods.
This allows you to propagate events up the object hierarchy, handling only those parts of an event handler that you wish.
However, in Qt there is another type of event hierarchy, constructed around the UI relationships. Widgets that are added to a layout, within another widget, may opt to pass their events to their UI parent. In complex widgets with multiple sub-elements this can allow for delegation of event handling to the containing widget for certain events.
However, if you have dealt with an event and do not want it to propagate in this way you can flag this by calling .accept()
on the event.
Alternatively, if you do want it to propagate calling .ignore()
will achieve this.
In this section we've covered signals, slots and events. We've demonstratedsome simple signals, including how to pass less and more data using lambdas.We've created custom signals, and shown how to intercept events, pass onevent handling and use .accept()
and .ignore()
to hide/show eventsto the UI-parent widget. In the next section we will go on to takea look at two common features of the GUI — toolbars and menus.
The Raspberry pi is a mini computer which is designed in a single board with all the essential components required for running an operating system. The Raspberry pi board runs on the Broadcom controller chip which is a SoC (System on Chip). This powerful processor and the controller having the peripherals like timers, interrupt controller, GPIO, PCM / I2S, DMA controller, I2C, SPI slave, PWM, UART, USB, graphical processing unit (GPU) which includes VideoCore, MPEG-2 and MPEG-4 and a 512 MB SDRAM makes it a mini-computer. The board is provided with a RCA connector which can be used to connect it directly to a TV screen which is based on PAL and NTSC standard. The board also has a HDMI connector output which can be used to connect the board to a HD TV.
The Raspberrypi board is powerful enough to run large operating systems like Linux, Mac and Windows. Linux operating systems especially Ubuntu is preferred for all kind of programming and development. Since the board capable of generating graphics on standard display screen needs a perfect application using which the programmers can exploit that capability. The ‘QT’ is a widely used platform for creating GUIs in Linux environment. The ‘QT’ is a widely used platform for creating GUIs in Linux environment. Qt is an application which helps in developing the UI framework using the Qt IDE. Qt uses standard C++ but it also supports support many compilers, including the GCC C++ compiler and the Visual Studio suite.
The GUI or graphical user interface makes it easy for the user to control or communicate with the applications which are connected to that particular GUI. The most unavoidable components of a GUI window are ‘buttons’ and this article discusses how to create a button and use it with the help of QT.
In this project the Raspberrypi board is loaded with Ubuntu and is remotely accessed using VNC. The Raspberrypi board is also connected to the internet. Downloading and installing the fourth version, QT4 using commands are already discussed in a previous article. There is another article which discusses about how to start with programming in QT, a hello world program using QT.
Once the installation is complete the user can find them listed under the installed programs for ‘Programming’ as shown in the following image;
Fig. 2: QT Listed In Installed Programs
The list includes “Qt 4 Assistant”, “Qt 4 Designer”, “Qt 4 Linguist” and “Qt Creator”. The “Qt 4 Assistant” is basically provides help in the form of documentations related to the topics in QT. “Qt 4 Designer” is where the user can create a design and save it as a ‘.ui’ file which can then be used in QT projects. The “Qt 4 Linguist” provides a language view of the design created. The “Qt Creator” is where all these things can be done in the same IDE which helps in creating a GUI using QT.
Click on the “Qt Creator” and the following window opens up which includes options for creating a project as explained in the article hello world program using QT.
As soon as a new project is created the “Edit” window of the Qt Creator will open up. Expand the “Forms” where the “mainwindow.ui” can be seen listed. Now double click on the “mainwindow.ui” and the Qt Creator’s “Design” window opens up:
Fig. 3: Drag And Drop ‘Push Button’ QT Creator Window In Ubuntu
Drag and drop a ‘Push Button’ from the list of ‘Buttons’ into the dialogue box as shown in the above image. Right click on the ‘Push Button’ and the text displayed on the button can be modified by selecting the “Change text” option.
Fig. 4: Editing Text of Push Button In QT Creator Window For GUI In Raspberry Pi
Every component in the designer is represented as an object in the code in the editor and every object has a specific default name also. It is possible to change the name of the object as per the convenience of the user, necessary when using many numbers of buttons or other components. Right click on the ‘Push Button’ and the object name of the button can be modified by selecting the “Change object name” option.
Fig. 5: Changing Object Name And Text In QT Creator Window
Here the object name is modified to “button_1” and the text displayed on the button is changed to “Say hello”. As soon as the object name is changed the same change can be visible as marked in the following image:
Fig. 6: Push Button Name Changed To Say Hello
In the following steps how to assign a particular function to the button is discussed. There are terms called ‘Signals’ and ‘Slots’. Slots are basically functions which are associated with an object and the Signals are send to execute those functions whenever the object is enabled. For example whenever the user clicks on a button a Signal will be send to the corresponding Slot function.
To create a Slot and Signal corresponding to an object just right click on the button and select the option “Go to Slot”.
Fig. 7: Creating Slot For Object Button To Assign Function With QT
The user will be provided with a list of Signals corresponding to that Push Button type object. Since the button is commonly used for clicking, here the signal ‘clicked ()’ has been selected.
Fig. 8: Creating Signal For Object Button To Execute Function With QT
Once clicked on the “OK” button it will instantly direct the user to the Editor window where the corresponding Slot can be visible in the code, here “_on_button_1_clicked ()”
Fig. 9: Slot Visible In Code Of Editor Window
This function will be called whenever the button object named “button_1 is clicked. Just to test it the user can write a simple printf () statement as shown in the following image, don’t forget to add the <stdio.h> header file.
Fig. 10: Testing The Code With Print f Command
The coding is finished with that and now save the project using “File >> Save All”.
Fig. 11: Saving The Project Using File From QT Creator Tool Bar
Build the code and run it as explained in the articlehello world program using QT.
Fig. 12: Build Code And Run Using QT
As the GUI runs it prints the string “HELLO WORLD” each and every time the button “Say Hello” is clicked.
Fig. 13: “HELLO WORLD” Printed As GUI Executes Command