A GUI is a valuable part of software application programming regarding human-computer interaction, replacing text-based commands with user-friendly actions. Therefore, knowing how to develop GUI applications as an experienced Python developer will be helpful. So, if you want to learn how to make stunning GUI applications using Python, you have come to the right place! In this post, you will learn how to build a simple Currency Converter Android application with the help of some of the best Python GUI tools on the market.
Last time, we created a Currency Converter GUI application using the plain DelphiFMX python package. In this tutorial, we want to build the same application for Android devices by leveraging other tools and products like Delphi4PythonExporter, Delphi Community Edition, and PythonFMXBuilder in the Delphi-Python EcoSystem.
Table of Contents
What is DelphiFMX?
DelphiFMX is a Python package that is natively compiled and powered by the Python4Delphi library. It is freely redistributable and provides Python developers access to the Delphi programming language’s FireMonkey (FMX) GUI framework. GUI development for Windows, MacOS, Linux, and Android is supported.
Embarcadero Delphi’s FireMonkey (FMX) is a graphical user interface framework for native cross-platform application development. For hardware-accelerated rendering, it makes use of the GPU via DirectX or OpenGL. It has a robust styling system and is user-extensible. DelphiFMX for Python does not require Delphi or any previous knowledge of Object Pascal.
What is Delphi4PythonExporter?
Delphi4PythonExporter is a critical offering for a thriving Python and Delphi ecosystem.
Python developers can use Delphi IDE’s flagship UI design capabilities to save time writing design code in Python. You can use a WYSIWYG preview, including styles, as you design. In addition, users can also use the features at design time to connect event methods to various events on the GUI application (for example, OnClick
). Finally, Pythoneers can use the following approach to scale your large-scale Python GUI application.
Delphi developers can also benefit from the Exporter. They can use their Delphi skills to create great applications and then offer Python implementation of those applications, giving your new capabilities an entirely new dimension. This allows users to create open-source GUIs in Python without writing a single line of design code in Python.
What is PythonFMXBuilder?
The PythonFMXBuilder is an application builder for Python that uses DelphiFMX for Python to build and deploy Android applications. This allows you to bundle a custom Python script into an Android app, deploy it to your phone, and then you can submit it to the app store as per the requirement.
How can you create a currency conversion application for Android using these tools?
Let’s create a simple currency converter for Android where a user can provide the desired currency and the amount in that currency. The application would then output the exchange amount in a defined currency.
What are the requirements to complete this task?
For this tutorial, you will need Python, DelphiFMX, PythonFMXBuilder, Delphi4PythonExporter, Delphi, and any text editor or IDE that supports Python (PyScripter is recommended). In addition, you will also need a basic understanding of Python and Delphi, so we recommend checking out this article on mixing Python and Delphi.
If you don’t have these tools installed on your PC, check out this Powerful Python GUI Project Setup article to get started.
You can grab the code for this tutorial from our Git repository at: https://github.com/Embarcadero/PythonBlogExamples/tree/main/Currency_Converter_GUI_With_Exporter
How to create a form in Delphi?
Open Delphi CE and create a blank application (File > New > Multi-Device Application > Blank Application > Ok
). This will open up a new project for you with a blank form. We have named our Delphi unit as CurrencyConverter.pas
and the project as CurrencyConversion
.
Since we want to create a currency converter application, we should add some combo boxes – TCombobox
and text boxes – TEdit
, from the standard palette where the user can add their desired currencies and the amount they want to convert.
It is important to add labels – TLabel
, with each combo box and text box. We even need to add a button – TButton
, which when clicked, will calculate the currency conversion amount.
Next, rename the text of each label by right-clicking on that label and selecting Quick Edit
.
For instance, above, we have a label whose Name
is FromLabel
since the label will only have Text
"From"
.
Similarly, rename the Buttons with intuitive names that will help us program them later. In our case, we are editing the Name
and Text
of the button to Convert
.
In addition, we rename our Form to CurrencyConverterApp
using Quick Edit
.
This is what our Form looks like:
We can even add some color to the Form’s background by selecting the Form’s fill
property from the Object Inspector
. After these changes, our form will look much more visually attractive:
Since we are creating an Android app, let’s even view our form as it would appear on an Android device by changing the Style from Windows
to Android
:
This will change the appearance of our form:
Then as we double-click on that button, we have added to our form, a ConvertClick
event gets created with the code for its event method being added to the CurrencyConverter.pas
that corresponds to our CurrencyConverter.fmx
form.
In the event method, you must type at least a single comment (//). This will ensure the method remains as we save the file. There is no need to write any run-time implementation code because we don’t export the run-time implementation using the Delphi4PythonExporter.
How to export the Delphi form as a Python Script?
You can now convert and save this form as a Python script by selecting Tools > Export To Python > Export Current Entire Project.
Delphi generates the Python scripts (CurrencyConverter.py
and CurrencyConversion.py
) in your chosen directory. You can optionally rename CurrencyConversion.py
to CurrencyConverterMain.py
. With this, there is a .fmx
form that contains all the form’s visual information.
The generated code of CurrencyConverterMain.py
is as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
from delphifmx import * from CurrencyConverter import CurrencyConverterApp def main(): Application.Initialize() Application.Title = 'CurrencyConverter' Application.MainForm = CurrencyConverterApp(Application) Application.MainForm.Show() Application.Run() Application.MainForm.Destroy() if __name__ == '__main__': main() |
To get a detailed understanding of the above code, please go through the free eBook bundle that we developed. This eBook explains the ideology around Delphi-Python EcoSystem, all Python GUI offerings, and much more.
Now, let’s look at the contents of CurrencyConverter.py, where we will write the logic of our application
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
import os from delphifmx import * class CurrencyConverterApp(Form): def __init__(self, owner): self.FromAmount = None self.Currency1 = None self.Amount1 = None self.Currency2 = None self.Amount2 = None self.Title = None self.FromLabel = None self.ToLabel = None self.Convert = None self.FromCurrency = None self.ToCurrency = None self.ToAmount = None self.LoadProps(os.path.join(os.path.dirname(os.path.abspath(__file__)), "CurrencyConverter.pyfmx")) def ConvertClick(self, Sender): pass |
How to run your currency converter using the generated Python script?
Note that in the above code, the method CurrencyClick
is empty with a pass
statement. Therefore, we first need to add functionality to this button such that when a user has provided two currencies and the desired conversion amount of one of the currencies and then clicks on this button, it will display the converted amount at the appropriate place.
How to add functionality to the convert button?
To add a currency conversion logic, we first build a nested dictionary. The data
dictionary is the code below that provides a map between the given currencies. For example, you may want to check the conversion rate from USD to GIP. To do this, check the data['USD'
]['GIP'
] to find the worth of USD $1 in GIP. Next, we populate our combo boxes with the items in our nested dictionary. We do this by appending the keys of the dictionary to the Items
of the combo boxes. Here is what our final __init__()
function looks like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
def __init__(self, owner): self.data = { "USD":{"EUR":0.96, "CAD":1.34, "CHF":0.95, "GBP":0.84, "OMR":0.39, "GIP":0.85, "KYD":0.84, "JOD":0.71, "BHD":0.38, "KWD":0.31}, "EUR":{"USD":1.04, "CAD":1.39, "CHF":0.98, "GBP":0.87, "OMR":0.40, "GIP":0.87, "KYD":0.87, "JOD":0.74, "BHD":0.36, "KWD":0.32}, "CAD":{"EUR":0.72, "USD":0.75, "CHF":0.71, "GBP":0.63, "OMR":0.29, "GIP":0.64, "KYD":0.63, "JOD":0.53, "BHD":0.28, "KWD":0.23}, "CHF":{"EUR":1.02, "CAD":1.41, "USD":1.06, "GBP":0.89, "OMR":0.41, "GIP":0.90, "KYD":0.88, "JOD":0.75, "BHD":0.40, "KWD":0.33}, "GBP":{"EUR":1.15, "CAD":1.59, "CHF":1.13, "USD":1.19, "OMR":0.46, "GIP":1.00, "KYD":1.00, "JOD":0.84, "BHD":0.45, "KWD":0.37}, "OMR":{"EUR":2.50, "CAD":3.47, "CHF":2.46, "GBP":2.18, "USD":2.60, "GIP":2.32, "KYD":2.17, "JOD":1.84, "BHD":0.98, "KWD":0.80}, "GIP":{"EUR":1.15, "CAD":1.59, "CHF":1.13, "USD":1.19, "OMR":0.46, "GBP":1.00, "KYD":1.00, "JOD":0.84, "BHD":0.45, "KWD":0.37}, "KYD":{"EUR":1.15, "CAD":1.59, "CHF":1.13, "USD":1.19, "OMR":0.46, "GIP":1.00, "GBP":1.00, "JOD":0.84, "BHD":0.45, "KWD":0.37}, "JOD":{"EUR":1.36, "CAD":1.88, "CHF":1.33, "GBP":1.19, "OMR":0.45, "GIP":1.19, "KYD":0.43, "USD":1.41, "BHD":0.53, "KWD":0.43}, "BHD":{"EUR":2.56, "CAD":3.54, "CHF":2.51, "GBP":2.23, "OMR":1.02, "GIP":2.24, "KYD":0.82, "JOD":1.88, "USD":2.65, "KWD":0.82}, "KWD":{"EUR":3.13, "CAD":4.34, "CHF":3.07, "GBP":2.73, "OMR":1.25, "GIP":2.73, "KYD":2.72, "JOD":2.30, "BHD":1.22, "USD":3.25} } # Currency conversion data recorded on 7th Nov 2022 self.FromAmount = None self.Currency1 = None self.Amount1 = None self.Currency2 = None self.Amount2 = None self.Title = None self.FromLabel = None self.ToLabel = None self.Convert = None self.FromCurrency = None self.ToCurrency = None self.ToAmount = None self.LoadProps(os.path.join(os.path.dirname(os.path.abspath(__file__)), "CurrencyConverter.pyfmx")) # Load the currencies in key values of the self.data dictionary into the FromCurrency and ToCurrency combo boxes for key in self.data.keys(): self.FromCurrency.Items.append(key) self.ToCurrency.Items.append(key) |
Next, we extract the data from the text box – FromAmount
defined for the input currency and use it to calculate the conversion. Here is what our CurrencyClick
method looks like:
1 2 3 4 5 6 7 |
def ConvertClick(self, Sender): given = self.FromCurrency.Selected.Text to = self.ToCurrency.Selected.Text amountGiven = int(self.FromAmount.Text) amountCalculated = self.data[given][to] * amountGiven self.ToAmount.Text = round(amountCalculated, 2) |
You should also know that Delphi4Python Exporter exports the application initialization logic for a desktop-based application by default. Therefore, we need adjustments in Android’s app code compared to the desktop application code.
Our current application uses a Python dictionary to store a specific date’s conversion ratios. Instead, you can get real-time data on all the available currencies and exchange rates using APILayer’s Exchange Rates Data API. We have demonstrated currency conversion using API in one of our previous articles.
So your final CurrencyConverter.py
should look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
import os from delphifmx import * class CurrencyConverterApp(Form): def __init__(self, owner): self.data = { "USD":{"EUR":0.96, "CAD":1.34, "CHF":0.95, "GBP":0.84, "OMR":0.39, "GIP":0.85, "KYD":0.84, "JOD":0.71, "BHD":0.38, "KWD":0.31}, "EUR":{"USD":1.04, "CAD":1.39, "CHF":0.98, "GBP":0.87, "OMR":0.40, "GIP":0.87, "KYD":0.87, "JOD":0.74, "BHD":0.36, "KWD":0.32}, "CAD":{"EUR":0.72, "USD":0.75, "CHF":0.71, "GBP":0.63, "OMR":0.29, "GIP":0.64, "KYD":0.63, "JOD":0.53, "BHD":0.28, "KWD":0.23}, "CHF":{"EUR":1.02, "CAD":1.41, "USD":1.06, "GBP":0.89, "OMR":0.41, "GIP":0.90, "KYD":0.88, "JOD":0.75, "BHD":0.40, "KWD":0.33}, "GBP":{"EUR":1.15, "CAD":1.59, "CHF":1.13, "USD":1.19, "OMR":0.46, "GIP":1.00, "KYD":1.00, "JOD":0.84, "BHD":0.45, "KWD":0.37}, "OMR":{"EUR":2.50, "CAD":3.47, "CHF":2.46, "GBP":2.18, "USD":2.60, "GIP":2.32, "KYD":2.17, "JOD":1.84, "BHD":0.98, "KWD":0.80}, "GIP":{"EUR":1.15, "CAD":1.59, "CHF":1.13, "USD":1.19, "OMR":0.46, "GBP":1.00, "KYD":1.00, "JOD":0.84, "BHD":0.45, "KWD":0.37}, "KYD":{"EUR":1.15, "CAD":1.59, "CHF":1.13, "USD":1.19, "OMR":0.46, "GIP":1.00, "GBP":1.00, "JOD":0.84, "BHD":0.45, "KWD":0.37}, "JOD":{"EUR":1.36, "CAD":1.88, "CHF":1.33, "GBP":1.19, "OMR":0.45, "GIP":1.19, "KYD":0.43, "USD":1.41, "BHD":0.53, "KWD":0.43}, "BHD":{"EUR":2.56, "CAD":3.54, "CHF":2.51, "GBP":2.23, "OMR":1.02, "GIP":2.24, "KYD":0.82, "JOD":1.88, "USD":2.65, "KWD":0.82}, "KWD":{"EUR":3.13, "CAD":4.34, "CHF":3.07, "GBP":2.73, "OMR":1.25, "GIP":2.73, "KYD":2.72, "JOD":2.30, "BHD":1.22, "USD":3.25} } # Currency conversion data recorded on 7th Nov 2022 self.FromAmount = None self.Currency1 = None self.Amount1 = None self.Currency2 = None self.Amount2 = None self.Title = None self.FromLabel = None self.ToLabel = None self.Convert = None self.FromCurrency = None self.ToCurrency = None self.ToAmount = None self.LoadProps(os.path.join(os.path.dirname(os.path.abspath(__file__)), "CurrencyConverter.pyfmx")) # Load the currencies in key values of the self.data dictionary into the FromCurrency and ToCurrency combo boxes for key in self.data.keys(): self.FromCurrency.Items.append(key) self.ToCurrency.Items.append(key) def ConvertClick(self, Sender): given = self.FromCurrency.Selected.Text to = self.ToCurrency.Selected.Text amountGiven = int(self.FromAmount.Text) amountCalculated = self.data[given][to] * amountGiven self.ToAmount.Text = round(amountCalculated, 2) |
Let’s run the CurrencyConverterMain.py
file and check if it’s working well on the Desktop before converting it into an Android application.
How to run the currency converter as an Android application using PythonFMXBuilder?
Delphi4Python Exporter exports the application initialization logic for a desktop-based application by default, and PythonFMXBuilder will ship the application we have created to an Android app. But before we can export our application to Andriod, we need to make minor code adjustments.
Firstly, we don’t need the application initialization or to set a title because the Android application is a Delphi application and will be initialized automatically. Furthermore, we don’t need to set the Application.MainForm
, but need a variable for the Form. Lastly, we don’t need to run or destroy the application because Android will take care of the application life cycle.
So, we have to make changes to CurrencyConverterMain.py
file accordingly for it to be installed as an Android app.
Now let’s save our modified file as CurrencyConverterMain_Android.py
and is shown below:
1 2 3 4 5 6 7 8 9 10 |
from delphifmx import * from CurrencyConverter import CurrencyConverterApp def main(): Application.MainForm = CurrencyConverterApp(Application) Application.MainForm.Show() if __name__ == '__main__': main() |
Now, save the changes made above. Then open the PythonFMXBuilder application and click Project > New project
on the toolbar. Enter the name of the project that you want to build here.
Add your Python files and any other supporting project files that you use to create your application by selecting File > Add File
. One of the best practices is to take a modular approach to build your application where we can write all the logic/implementations in separate Python files and call them from the main Python file just like we did above:
Here, we’re setting the CurrencyConverterMain_Android.py
to the main file from our two script files by right-clicking on the file and selecting the option.
Now, we are all set to build and deploy our app to Android device. PythonFMXBuilder provides three options for developers to build applications, namely:
- Build,
- Deploy
- Run
To learn more about these options, download and read PythonGUI’s ebook.
To get the app up and running on your phone, you must first enable USB debugging on your Android device. To do so, on your Android device, go to Settings > About Phone > Version and tap on the Build Number a few times. It displays a message that says, “You are now a developer.” Then, in Developer Options, enable USB Debugging.
Connect your phone to the PC with a USB cable/cord now. Allow “USB Debugging” permission by hitting Allow. Then, in the upper right corner of your FMXBuilder window, click the Reload button to load the list of devices, and then choose the first device using the “Load Devices” button. Click the Run button to execute Build, Deploy, and Launch. So your app will launch soon on your connected Android device.
Let’s go ahead and test this app. If everything is set up correctly, then you should click on the Convert button, and this will convert the given amount as per the exchange rate/ratio of the selected currency trading pair:
Wow! Now, currency conversions are at your fingertips.
Are you ready to create your own applications using PythonGUI?
Well done on reaching the end of this tutorial! Hopefully, this has been an eye-opener for you regarding how simple it is to build Python GUIs with the correct toolkit. We have seen how Python bindings for Delphi GUI libraries are essential for the Python GUI developer community.
Furthermore, Delphi Community Edition is a very important tool. It includes a streamlined IDE, code editor, integrated debugger, award-winning visual designers to speed development, powerful data access and binding technologies, hundreds of visual components, and a limited commercial use license.
What are the FAQs surrounding this topic?
What is Embarcadero?
Embarcadero is a subsidiary of Idera, Inc. Idera, Inc., the parent company of global B2B software productivity brands whose solutions enable technical users to do more with less and less time.
Embarcadero tools are designed for the world’s most elite developers who create and maintain the world’s most critical applications. Our customers choose Embarcadero because we are the developer champion, assisting them in developing more secure and scalable enterprise applications faster than any other tool on the market. For over 30 years, Embarcadero’s award-winning products have been relied on by ninety of the Fortune 100 and an active community of more than three million users worldwide.
What is APILayer?
APILayer is the leading provider of off-the-shelf, cloud-based API products designed to assist developers and businesses worldwide to operate efficiently and effectively. Organizations of all sizes struggle to support complex digital transformations and the increasing demand for connectivity and real-time data. APILayer does precisely that!
What is Delphi?
Delphi is a high-level programming language that supports an object-oriented paradigm. It is a Rapid Application Development (RAD) paradigm that can create applications ranging from database solutions to mobile applications. Delphi is now widely regarded as the quickest way to develop, compile, package, and deploy cross-platform native applications for Windows, macOS, iOS, Android, and Linux.
What features does PyScripter have?
PyScripter is an Integrated development environment (IDE) for Python that is free and open source. It was created using Delphi’s Object Pascal and Python.
It began as a lightweight IDE to provide a powerful scripting solution for Delphi applications. It evolved into a full-featured stand-alone Python IDE. It is written in Delphi using Python4Delphi (P4D) and can be extended with Python scripts. Because it is written in a compiled language, it is relatively light compared to other IDEs. PyScripter functions as a syntax highlighting editor, Python interpreter and debugger, file explorer, project manager, and many others.