Building a simple facial recoginition application with PyQt5 (Part 3 - Connecting the buttons)

Part 3 of a series of articles where we build a facial recognition application from scratch using PyQt5, as demostrated at the ATE webinar. Now, we connect the buttons.

2 minute read

15/12/2020

In part 1, I took us through building the user interface of our application, and part 2 was all about setting up the python backend of the application.

To be able to follow along with this article, I recommend you go back and read the previous two. If you just want the code, all the project files are available on github.

The core functionality of our app is to be able to sign employees into a company by recognising their faces. When a face is recognised, the employee clicks a button and is signed in. In this article, we will be wiring up our buttons to respond to user input.

Where we last left off, our user interface looked like below.

app_ui_screenshot

User interface so far.

Our python backend also had the following code in it.

app.py
python
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5 import uic
class AppWindow(QMainWindow):
"""Entry point into our application"""
# Initialise our application window class
def __init__(self):
QMainWindow.__init__(self)
# Load the ui file we created
uic.loadUi('mainwindow.ui', self)
# Start the application event loop
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
window = AppWindow()
window.show()
window.raise_()
sys.exit(app.exec_())

Catching signals

If you are here after building applications on windows using windows forms, you know that in your ui code-behind, you usually reference buttons, and define what functionality should occur when click events are triggered.

WPF introduced binding, and you can subscribe to events such as the button click event and bind those events to the functions you want executed when those events are fired.

Qt handles this in a manner somewhat similar to how it is done in WPF. Every interactive widget in your user interface has corresponding "signals", that are emitted based on user interaction.

These signals are fired irrespective, and all you have to do is define what you want to happen whenever those signals are emitted, and Qt takes care of the rest.

The QtPushButton widget we're using has four signals that can be emitted when it is interacted with, namely

python
pressed() # When the left moused button is pressed with the cursor on the pushbutton
released() # When the left mouse button is released
clicked() # When the left mouse button is clicked (Pressed and released)
toggled() # When the button holds state, and it is toggled on or off

A lot more can be said about these signals, but for the sake of brevity let us focus on the signal that applies to our application. Can you guess what it is?

Yes, we want to listen for the clicked() signal.

Remember how I said we should give our widget sensible names so we can know what we are referring to in our code? Well, this is a situation where that practice comes in handy.

First, let us define what we want to happen when the button is clicked. We want to sign an employee in for one, and out for the other.

However, since we aren't recognising employees yet, let us set the buttons to print a message to the terminal when clicked.

We add the following highlighted code to our app.py file.

app.py
python
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5 import uic
class AppWindow(QMainWindow):
"""Entry point into our application"""
# Initialise our application window class
def __init__(self):
QMainWindow.__init__(self)
# Load the ui file we created
uic.loadUi('mainwindow.ui', self)
def print_message_sign_in_button(self):
print("Sign in button clicked.")
def print_message_sign_out_button(self):
print("Sign out button clicked.")
# Start the application event loop
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
window = AppWindow()
window.show()
window.raise_()
sys.exit(app.exec_())

Side Note

You can define multiple functions that get triggered in response to a signal, so it's best to name your functions based on what they do, and not just after the widget they are listening to.

With our functions defined, we want to inform our application that it should trigger these functions when each button is clicked. This is done by connecting the signals to the functions we want invoked. This also has to be done when the application window is initialised.

Thus, we add the connection commands to the __init__() function of our application window as shown below.

app.py
python
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5 import uic
class AppWindow(QMainWindow):
"""Entry point into our application"""
# Initialise our application window class
def __init__(self):
QMainWindow.__init__(self)
# Load the ui file we created
uic.loadUi('mainwindow.ui', self)
# Connect the sign in button to the function
self.sign_in_button.clicked.connect(self.print_message_sign_in_button)
# Connect the sign out button to the function
self.sign_out_button.clicked.connect(self.print_message_sign_out_button)
def print_message_sign_in_button(self):
print("Sign in button clicked.")
def print_message_sign_out_button(self):
print("Sign out button clicked.")
# Start the application event loop
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
window = AppWindow()
window.show()
window.raise_()
sys.exit(app.exec_())

It is really that simple. Now we have added functionality to our user interface by connecting some elements to the python back end.

Here it is in action:

Testing the connected buttons.

There's still a lot more to be done. But, we are well on our way to getting our application ready.

A Challenge

A challenge: Play around with the button signal connected to the functions. Try to listen for the pressed() signal, or maybe just the released() signal. Print the corresponding message to the console.

If you've gotten this far, you're doing great. In the next article, we will be displaying the video feed.

Speak soon.

Share this article:

Credits

Got a cool project in mind?

Lets work together.

Hit me up.

ProjectsBlogAboutContact
LinkedInTwitterGithubEmail
©2021 Dr. Abbas Egbeyemi. All rights reserved. Privacy Policy.