Users can easily use an app they have never seen before if the GUI is well-designed. GUIs provide an attractive design and simple way for users to access technology. They can easily chat with pals, make online purchases, and watch popular shows. In this tutorial, we will learn how to use Python and Delphi to create a simple but visually appealing app that allows users to register and log in to a system. So, let’s dive right in!
Table of Contents
What is the importance of the GUI in a Login Registration App?
Login and registration are required in many apps, just as they are in any website or software. The purpose is to authenticate its users to protect their private content and provide them with a personalized experience.
Regarding human-computer interaction, the GUI is an important component of software application programming, replacing text-based commands with user-friendly actions. Its goal is to provide the user with simple decision points to locate, understand, and apply.
Moreover, the GUI experience for the login and registration screens contributes to whether a user will stick around to use the app or move on. Therefore, it is important that GUI’s are intuitive and interactive, providing users with an appealing interface, promoting a positive experience and impression, that in turn may lead to them continuing to use the app.
How to create a Python GUI for your app with PythonGUI Tools?
Let’s create a simple Login and Registration App that will allow our users to Login or Register to the app. The app would serve two basic functions: a login form that checks a user’s credentials against stored credentials in a database and a register form that allows new users to register to our app.
What are the requirements to create the Python GUI for an app?
For this tutorial, you will need:
- Python
- PythonFMXBuilder
- Delphi4PythonExporter
- Delphi CE
- PyScripter or any other IDE.
We’ve got you covered if you don’t have these tools installed on your laptop or PC. You can check out this article on Powerful Python GUI Project Setup to get started.
In addition, you will also need a basic understanding of Python and the Python sqlalchemy library to host our database.
You can grab the code for this tutorial from our GitHub repository using the following link: https://github.com/Embarcadero/PythonBlogExamples/tree/main/Login_Registration_App
Now that we have our requirements installed and ready, let’s begin this tutorial by creating our forms.
How to make basic screen forms and layouts in Delphi?
Open up Delphi CE, and under the develop
tab, select create a new project
. Next, select the Multi-Device application and create a blank application.
If you are not familiar with the various sections of the Delphi IDE, we recommend referring to our free eBook bundle, which covers the Delphi Python EcoSystem and all Python GUI offerings.
This will create a new project for you with a blank form. We have named our project as Login_Registration_App
. By default, Delphi launches a project with a blank form. We will begin by creating a sign-in form, so we have renamed our form as SignIn
.
Let’s begin by renaming our form, so right click on the form and select QuickEdit
. Here we will name our form as SignInForm
with the caption SignIn
.
Now, let’s add labels to our form. Head to the standard palette and select TLabel
.
Next, rename the text of each label by right-clicking on that label and selecting Quick Edit
.
For example, we have named our password label as Password
, as this label will only contain the text "Password:"
.
To log into the app, we will need our users to add their email and password which we will check against entries in our database. So head on over to the standard palette and add some TEdit
boxes. These will allow our user to input their details and login credentials to our app. Rename these TEdit
labels and give them intuitive names which will help us in our program later. Here we have named our email and password input boxes as EmailText
and PasswordText
respectively.
Moreover, we need to add some buttons to our form. So head to the palette and add some TButtons
. We have named our buttons Signin
and Signup
. The Signin
button will allow our user to log in to our application, whereas the Signup
button will redirect us to the registration form. In addition to this, we add a small text label named Status
right above the Signin
button that displays an error if the user uses incorrect login credentials.
Here is what our form looks like:
Next, we need to create another registration form that will allow a new user to register for our application. So right-click on Login_Registration_App.exe
and select Add New > Multi-Device Form
.
This will create a new blank form, which we have renamed as SignUp
.
Next, we will populate our form with labels, text boxes, and buttons that will help our users log in to our application. We will give them intuitive names as we add elements to the form. Here is what our final registration form looks like:
Finally, we need to add some function that will help us add some code to each button. To do this, we need to double-click each button on both of our forms. For example, double-clicking on the Signin
button on the SignIn
form creates a SigninClick
event in the SignIn.pas
file that is associated with our SignIn.pas
form. The event is triggered each time the button is clicked.
By default, Delphi cleans up your code to remove redundant or unused functions and procedures. Therefore, in the event method, we must add at least a single comment //
in each button click event so that the Delphi IDE will not automatically remove it. This will ensure the method remains when we save the file.
How to export our Python GUI screen as Python Code?
Now that we have our forms ready, it is time that we export our project as Python scripts using Delphi4PythonExporter. To do this, select Tools > Export To Python > Export Current Entire Project
on the top menu bar.
In the Project Export
menu, select your desired project directory. Next, select the Application Main Form
as the SignIn
form. Finally, click on Export
.
This action will generate 3 Python scripts Login_Registration_App.py,
SignIn.py
, and SignUp.py
that contain each function and the functionality of each form in our chosen directory. With this, there are 2 .pyfmx
files that contain all the visual information of the forms.
The code in the Login_Registration_App.py
is as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
from delphifmx import * from SignIn import SignInForm def main(): Application.Initialize() Application.Title = 'Login_Registration_App' Application.MainForm = SignInForm(Application) Application.MainForm.Show() Application.Run() Application.MainForm.Destroy() if __name__ == '__main__': main() |
Next, let’s take a look at the content of the SignIn.py
form that will allow our user to sign in:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import os from delphifmx import * class SignInForm(Form): def __init__(self, owner): self.Login = None self.Email = None self.PasswordText = None self.Password = None self.Signin = None self.EmailText = None self.Status = None self.Signup = None self.LoadProps(os.path.join(os.path.dirname(os.path.abspath(__file__)), "SignIn.pyfmx")) def SigninClick(self, Sender): pass def SignupClick(self, Sender): pass |
Here is are the contents of SignUp.py
where we will be adding logic for signing up to our app:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
import os from delphifmx import * class SignUpForm(Form): def __init__(self, owner): self.Register = None self.FnameText = None self.Fname = None self.LNameText = None self.LName = None self.EmailText = None self.Email = None self.PasswordText = None self.Password = None self.CPasswordText = None self.CPassword = None self.Signup = None self.Status = None self.LoadProps(os.path.join(os.path.dirname(os.path.abspath(__file__)), "SignUp.pyfmx")) def SignupClick(self, Sender): pass |
How to create a database with Python to store user information?
Before we can start creating our functions for our forms, we first need to create a database to store our user information. To do this, we will create a Python script named database.py
in the projects folder. Open up the file and import create_engine
, MetaData
, Table
, Column
, and VARCHAR
from SQLAlchemy:
1 2 |
from sqlalchemy import create_engine, MetaData, Table, Column, VARCHAR |
Next, establish a connection or create a database using the create_engine
function and specify the name. Here we have named our database users.db
.
1 2 3 |
engine = create_engine( 'sqlite:///users.db') |
In addition, we need to define the format of data in our database. To do this, first, create a MetaData
object instance and bind it to the engine:
1 2 3 |
# initialize the Metadata Object meta = MetaData(bind=engine) |
Next, create a table called users
with attributes of different types using the Table
function and assign it to a variable:
1 2 3 4 5 6 7 8 |
users = Table( 'users', meta, Column('email', VARCHAR, primary_key=True), Column('fname', VARCHAR), Column('lname', VARCHAR), Column('password', VARCHAR) ) |
Finally, execute the query using the create_all
method of MetaData
:
1 2 |
meta.create_all(engine) |
Here is what our final database.py
looks like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# import necessary packages from sqlalchemy import create_engine, MetaData, Table, Column, VARCHAR # establish connections - create new file db and connect of connect if it already exists engine = create_engine( 'sqlite:///users.db') # initialize the Metadata Object meta = MetaData(bind=engine) # create a table schema users = Table( 'users', meta, Column('email', VARCHAR, primary_key=True), Column('fname', VARCHAR), Column('lname', VARCHAR), Column('password', VARCHAR) ) meta.create_all(engine) |
Running the script will create a database in our projects directory that we can use to store all the user information.
How to add the Login and Registration GUI function to our Python App?
Now that we have our forms up and running let’s start adding logic to our code. Let’s begin by modifying our SignIn
form and finishing our SigninClick
function.
The first thing we will need to do is establish a connection to our database. Open up SignIn.py
and import the create_engine
and text function from the sqlalchemy
library. Next, establish a connection to our users.db
by using the create_engine
function:
1 2 3 4 5 6 |
from sqlalchemy import create_engine, text # establish connections - create new file db and connect of connect if it already exists engine = create_engine( 'sqlite:///users.db') |
Next, we check is whether the email or password entries are empty. Navigate to the SigninClick
function and check the EmailText
and PasswordText
boxes using the .Text
property. We can then display the error on our Status
label if either text box is empty:
1 2 3 |
if self.EmailText.Text == "" or self.PasswordText.Text == "": self.Status.Text = "Incomplete details" |
Now, if the user enters some email or password, we need to check it against all of the entries in our database. To do this, we write an SQL query using the text function, run the query, commit the changes, fetch all instances using engine.execute(sql).fetch_all()
, and finally check the results to see if there was a matching found in the database. We write a message to the Status
label, whether the details were found in the database.
1 2 3 4 5 6 7 8 9 10 11 |
else: # write the SQL query inside the text() block sql = text("SELECT * FROM users WHERE users.email='{}' AND users.password='{}'".format(self.EmailText.Text, self.PasswordText.Text)) result = engine.execute(sql).fetchall() print(result) if len(result) == 0: self.Status.Text = "Incorrect or invalid login details" else: Fname = result[0][1] self.Status.Text = "Successful login. Welcome {}".format(Fname) |
Here is what our function SigninClick
function looks like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
def SigninClick(self, Sender): if self.EmailText.Text == "" or self.PasswordText.Text == "": self.Status.Text = "Incomplete details" else: # write the SQL query inside the text() block sql = text("SELECT * FROM users WHERE users.email='{}' AND users.password='{}'".format(self.EmailText.Text, self.PasswordText.Text)) result = engine.execute(sql).fetchall() print(result) if len(result) == 0: self.Status.Text = "Incorrect or invalid login details" else: Fname = result[0][1] self.Status.Text = "Successful login. Welcome {}".format(Fname) |
To finish our SignIn
form, we need to write the logic for our SignupClick
function. The function should open the SignUp
form whenever the Signup button is clicked. To do this, we first import the form SignUp
form from SignUp.py
:
1 2 |
from SignUp import SignUpForm |
Next, we create a new instance of the SignUpForm
and assign it to a new variable named signup_form. We then use the Show()
method to display the new form.. Here is our final SignupClick
function:
1 2 3 4 5 |
def SignupClick(self, Sender): signup_form = SignUpForm(self) signup_form.Show() #self.Show() |
Let’s finish up our SignUp
form. First, open up SignUp.py
, import create_engine from sql_alchemy
, and create a database engine using the create_engine
function. If a database is already created create_engine
creates a new database with the supplied name. Otherwise, it establishes a connection to an existing database. In this case, we have named our database as users.db
.
1 2 3 4 5 6 |
from sqlalchemy import create_engine # establish connections - create new file db and connect of connect if it already exists engine = create_engine( 'sqlite:///users.db') |
Before completing our SignUpClick
function, we need to create an owner for our form that will allow us to navigate back to our main form. To do this navigate to the __init__
function and create a new variable named self.owner
. Now simply assign the owner
parameter to this new variable. Here is what our new __init__
function looks like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
def __init__(self, owner): self.Register = None self.FnameText = None self.Fname = None self.LNameText = None self.LName = None self.EmailText = None self.Email = None self.PasswordText = None self.Password = None self.CPasswordText = None self.CPassword = None self.Signup = None self.Status = None self.LoadProps(os.path.join(os.path.dirname(os.path.abspath(__file__)), "SignUp.pyfmx")) self.owner = owner |
Next, we check whether any of the text boxes are empty. We do this by checking the .Text
property of the TEdit
boxes. If a text box is empty, we display an error:
1 2 3 |
if self.FnameText.Text == "" or self.LNameText.Text == "" or self.EmailText.Text == "" or self.PasswordText.Text == "" or self.CPasswordText.Text == "": self.Status.Text = "Incomplete details!" |
The next thing to check is if the password and the confirm password fields match:
1 2 3 |
elif self.CPasswordText.Text != self.PasswordText.Text: self.Status.Text = "Passwords do not match!" |
Finally, if all text fields are filled, we can simply remove the text from each label and use an INSERT
query to add the user to the existing database. We then display a “Successful SignUp” message in the SignInForm
using the Status
label, and destroy the current form:
1 2 3 4 5 6 7 8 9 10 |
else: query = "INSERT INTO users VALUES ('{}', '{}','{}', '{}')".format(self.EmailText.Text, self.FnameText.Text, self.LNameText.Text, self.PasswordText.Text) # execute the insert record statement engine.execute(query) self.owner.Status.Text = "Successful SignUp. Login Now!!" self.Destroy() #self.owner.Show() |
Here is our final SignupClick
function:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
def SignupClick(self, Sender): if self.FnameText.Text == "" or self.LNameText.Text == "" or self.EmailText.Text == "" or self.PasswordText.Text == "" or self.CPasswordText.Text == "": self.Status.Text = "Incomplete details!" elif self.CPasswordText.Text != self.PasswordText.Text: self.Status.Text = "Passwords do not match!" else: query = "INSERT INTO users VALUES ('{}', '{}','{}', '{}')".format(self.EmailText.Text, self.FnameText.Text, self.LNameText.Text, self.PasswordText.Text) # execute the insert record statement engine.execute(query) self.owner.Status.Text = "Successful SignUp. Login Now!!" self.Destroy() #self.owner.Show() |
How to make a Python app GUI look more appealing?
Now that everything is ready, let’s make our app more appealing by making changes to the FMX code in the .pyfmx
files. Let’s start by improving our SignIn
form. Let us begin by fixing the caption to our form. Open up SignIn.pyfmx
, and navigate to the Caption
property. Here you can see that our Caption
has been defined as 'Form3'
. We can change this by simply renaming our form to SignIn
.
Next, let’s add some background color to our form. You can do this by defining a color Fill.Color
property inside the form. In addition, you will also have to specify the type of color that you are adding in HEX as ARGB where A defines the opacity of your color. Moreover, we need to define the type of color we want, which can be a gradient or solid color. Here we are defining it to be a solid color using the Fill.Kind
property:
Let’s now change the "LogIn"
label of our form. To do this, navigate to the Login object.
Add a property named TextSettings.Font.Family
and set it to “Rockwell
“. Next, check out the TextSettings.Font.Size
property and size it accordingly. We have defined it to be 26pt
. Finally, align the label to the center by changing the TextSettings.HorzAlign
to Center
. This will help us center our label. Here is what the final object label looks like:
If your Login
label still isn’t centered, chances are that your label isn’t wide enough to align itself to the center of your form automatically. You can easily overcome this by setting the Size.Width
property of the Login
label to the width of your form (306pt
in our case).
Now, let’s change the font of all our other objects and labels; we can do this by first adding style settings to our objects. For example, let’s take a look at the Email
label.
As you can see, there is no style defined for our label. Therefore, to add any format to the label or any other object, we add StyledSettings
property and define it as Size
, Style
, and FontColor
. We then proceed to change the font by adding TextSettings.Font.Family = 'Rockwell'
to the objects in our form. Here is what our object looks like:
Note that we have added two additional style settings, namely FontColor
, and Size
, which we have not defined. These settings will allow you to use TextSettings.FontColor
property and TextSettings.Font.Size
to define the color and size of your text. We can similarly define the same settings for different labels and buttons in our app. This helps us style our app according to our needs. Running the Login_Registation_App.py
we can see what our final form looks like:
Similarly, we can define different properties of the SignUp
form. Here is what our final registration form looks like:
How to test our SignIn-SignUp Python App?
So now that we have completed working on the functionality and visuals of the app, let’s go ahead and test everything out. As expected, when we run the file Login_Registration_App.py
, the SignIn
form appears. Now if we try to sign in without adding the required details, we get a warning:
If we fill out the details but are incorrect, meaning the user is not stored in the users.db
database, then we get another message:
So let’s sign up by clicking on the signup button and filling out the SignUp
form details:
Submitting the form will open up the SignIn
form with the success message:
Note that if we had not filled all the required fields, then we would have gotten an error message as we did in the SignIn
form.
After a successful signup, when we add the user credentials just registered, we are successfully signed in, and the user gets a greeting with her first name acquired from the database:
So the app works just as expected and looks impressive too!
Are you ready to create beautiful Python GUI apps with Delphi?
Today, you have learned a lot about Python GUIs. A graphical user interface significantly boosts usability for the typical individual. GUI apps are self-descriptive, provide rapid feedback, and use visual cues to stimulate and direct discoverability. A combination of tools, such as DelphiFMX, DelphiCE, PyScripter, and Delphi4PythonExporter, allows users to create simple, attractive, and powerful apps in just a few steps.
DelphiFMX from Embarcadero is the ideal feature set for creating visually appealing user interfaces. It is relatively simple and supports several systems, including Windows, macOS, and Linux. The bulk of Python GUIs is considered difficult to use by rookie developers due to a lack of suitable functionality. DelphiFMX addresses these issues by enabling the creation of visually attractive GUIs.
What are the FAQs regarding building an attractive GUI for a Python app?
What is P4D?
Python for Delphi (P4D) is a free set of components that integrates the Python DLL into Delphi. They simplify the execution of Python programs and the creation of new Python modules and types. Python extensions, among other things, can be created as DLLs.
What is Delphi CE?
Embarcadero Delphi Community Edition is an excellent starting point for creating visually appealing, high-performance native Delphi apps for Windows, macOS, iOS, and Android. Delphi Community Edition includes a streamlined IDE, code editor, integrated debugger, award-winning visual designers to speed development, powerful data access components, and data binding technologies, hundreds of visual components, and a commercial use licence with a limited commercial use license.
What is DelphiFMX?
DelphiFMX from Embarcadero is the ideal feature set for creating visually appealing user interfaces. It is relatively simple to use and supports several systems, including Windows, macOS, and Linux. The bulk of Python GUIs is considered difficult to use by inexperienced developers due to a lack of suitable functionality. DelphiFMX addresses these issues by enabling the creation of visually attractive GUIs. DelphiFMX eliminates compatibility concerns by including Stencils for FireMonkey, which enable the development of multi-build device apps. DelphiFMX is an excellent choice for creating visually appealing GUIs.
What is Delphi4PythonExporter?
Delphi4PythonExporter is an essential component of a healthy Python and Delphi environment. By exploiting Delphi’s flagship UI design tools, Python developers can save time writing design code in Python. They may use a WYSIWYG preview, including styles, as you design.
Furthermore, users can use the features throughout the design phase to connect event methods to various events on the GUI application. Finally, Pythoneers can use these techniques to scale their large-scale Python GUI applications.
What is a multi-device application?
A multi-device application can run on any platform that RAD Studio supports; multi-device apps are not limited to desktop or mobile platforms. FireMonkey and RTL, two of RAD Studio’s three main libraries, are used in multi-device applications.