Python is one of the most popular programming languages today, with uses ranging from data analysis to web development. It’s understandable why many programmers prefer Python due to its simple syntax and robust libraries. While there are many resources for learning Python scripting, quizzes are occasionally the greatest way to evaluate your understanding. In this post, we’ll look at how to use DelphiFMX, a powerful cross-platform application development framework, to build a Python quiz application.
Table of Contents
Why Should You Build a Python Quiz Android App?
Constructing a Python quiz enables you to combine your understanding of Python with mobile app development and is a terrific way to improve your programming abilities. To construct a quiz app installed on Android smartphones, you can utilize several tools, including DelphiFMX and PythonFMXBuilder.
By creating a quiz app, you can give users a fun and instructive experience while simultaneously showcasing your programming skills to potential employers or clients. To keep users interested, you may personalize the app to include many categories and levels of difficulty. Developing an Android quiz app in Python can be a fulfilling undertaking that can advance your programming abilities and benefit users.
What Tools do Python Developers Prefer For Building Python GUIs?
Several tools support the ability to create GUIs in Python. PyScripter is a free and open-source IDE for Python on Windows and is one of the most popular options. It was first created as a straightforward IDE to offer a potent scripting option for Delphi applications. It has since developed into a powerful IDE for Python development, nevertheless.
Another well-liked tool for creating GUIs among Python developers is Delphi Community Edition. Because of its open-source nature, the DelphiFMX module gives Python programmers access to the FireMonkey GUI framework. The library makes it possible to create GUIs for various operating systems, including Windows, macOS, Linux, and Android.
A strong Python and Delphi ecosystem depends on the Delphi4PythonExporter. Python programmers can write design code more quickly by utilizing Delphi’s UI design capabilities. As they may design programs using their Delphi skills and subsequently give Python analogs of those apps, this tool can also be helpful for Delphi developers.
PythonFMXBuilder is a DelphiFMX-based Python application builder for Android applications. It enables programmers to install a specific Python script on their phone and incorporate it into an Android application.
How Can You Create A Python Quiz App For Windows Desktop?
Let’s create a basic quiz application for desktop devices! A good approach would be to use the Delphi tools mentioned above. So let’s get started!
What Are the Requirements to Create this App?
Python, PythonFMXBuilder, Delphi4PythonExporter, Delphi, and any text editor or IDE (PyScripter is recommended) that supports Python are required for this tutorial.
We’ve got you covered if you don’t have these installed on your device. We recommend checking out this article, “Powerful Python GUI Project Setup” which will help you get started.
You can grab the code for this tutorial from our Git repository at: https://github.com/Embarcadero/PythonBlogExamples/tree/main/Python_Quiz_App
How to Start a Basic Form For the App in Delphi?
Open Delphi CE and create a blank application by navigating to File > New > Multi-Device Application > Blank Application > Ok
. Here we have named our project PythonQuizApp
.
To understand what each section of the above Delphi IDE means/represents, please go through the free eBook bundle we have developed. This eBook explains the ideology around Delphi Python EcoSystem, all Python GUI offerings, and much more.
Let’s start by giving our form a name. Right-click on the form and click on QuickEdit
. Here we will name our form MainForm
and display the title as PythonQuizApp
.
Next, let’s resize our form. Head to the object inspector, and in the properties tab, search for ClientHeight
and ClientWidth
. We will set them as 550
and 350
, respectively.
We will also rename the source file of our main form to Main.pas
to make it easy to keep track of.
As you may have guessed, this is the main form of our quiz app. It will serve as the main screen where users will start their Python quiz. To make it more like a quiz app, let us add a label that will greet us with the title of our app. Head over to the standard palette and search for the TLabel
component. Next, drag and drop the component into the form.
Now, let’s change the text style to display the title. We will do this using TextSettings
. Head over to the Object Inspector and search for TextSettings
. Select Font
under it and click on the ...
to see options allowing you to change the label font, size, and style according to your needs.
Now rename the text of each label by right-clicking on that label and selecting Quick Edit
. It is important to follow an intuitive naming convention to name the labels so that it is easier to track them. Here, we named our TLabel
component as Title with the text “Ultimate Python Quiz
.”
We can change the form’s background color by navigating to the Object Inspector
and selecting the form’s fill
property.
Finally, we need a way to navigate to the next form, where we will start our quiz questions. So, go to the Palette
and add a button using the TButton
component.
As you can see, we have named our button Start
. You should even change the font size and style of this button text (as we did for the TLabels
above) to make the “START” text on the button more prominent. Here we have to use the font style as Segoe UI. We have also aligned the text to the Center
, the same as the Title
label above, so that the text appears symmetric.
After these changes, our form will look much more visually attractive:
Now that we are done with the Main form of our app, let’s create a new form that will display our questions. So right-click on PythonQuizApp.exe
and select Add New > Multi-Device Form
.
This will create a new form that we have named as QuizForm
and the source file as Quiz.pas
.
Next, we will populate our form with labels, text boxes, and buttons to help users log in to our application. We will give them intuitive names as we add elements to the form. Here is what our final QuizForm looks like:
As you can see, we have added 3 labels. The label on the top named QuestionNumberLabel
will display the number of attempted questions, whereas the Question
label will display the question. Finally, the AnswerStatus
label will help us displays a Correct
or Incorrect
message if the user chooses the answer to the question. If the user does not answer a question, the AnswerStatus
will show an error.
We have also added 4 option buttons that will display the choices for each question, and the Next
button will help display the next questions only when the user has attempted the current question. After the user has attempted all questions, the button will open the final form that will display the score for the quiz.
We may also see how our app appears on desktop and Android phones. Switch the Style from Windows
to Android
to verify this. This will alter how our form appears.
Finally, we can make our final form that will help display the user’s level and the quiz’s score. We named our form ResultsForm
and the source file Results.pas
. Here is what our ResultsForm
looks like:
Now that we have our forms ready, we must add procedures to each button. Open up each form and double-click on each button. The form’s buttons can be clicked twice to construct Click
methods in the .pas
file corresponding to our .fmx
for each button. This makes it easier to add an on-click function to each button.
To ensure that the method is preserved when we save the Python file, add at least one comment (//
) after each button Click
method. Since we don’t export the run-time implementation using the Delphi4PythonExporter, there is no need to write any run-time implementation code.
How to Export this Form as a Python Script?
You can save your project as a Python script by selecting Tools > Export To Python > Export Current Entire Project
.
Now give your application a title, select the Application Main Form as the MainForm, and, finally, select the directory of choice. Click on Export to generate your files.
Delphi will generate four Python scripts, Main.py
, Quiz.py
, Results.py
, and PythonQuizApp.py
, in your chosen directory. The Main
, Quiz
, and Results
python files contain the classes for the individual forms, and the PythonQuizApp
is used to launch our Delphi app.
Along with the Python files, .pyfmx
files are saved in that directory containing all the form’s visual information.
Let’s take a look at the exported PythonQuizApp.py
file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
from delphifmx import * from Main import MainForm def main(): Application.Initialize() Application.Title = 'PythonQuizApp' Application.MainForm = MainForm(Application) Application.MainForm.Show() Application.Run() Application.MainForm.Destroy() if __name__ == '__main__': main() |
Next, let’s take a look at the contents of Main.py
that will show our start screen:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
import os from delphifmx import * class MainForm(Form): def __init__(self, owner): self.Title = None self.Start = None self.LoadProps(os.path.join(os.path.dirname(os.path.abspath(__file__)), "Main.pyfmx")) def StartClick(self, Sender): pass |
Here are the contents of Quiz.py
where we will be adding code to show and change questions:
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 |
import os from delphifmx import * class QuizForm(Form): def __init__(self, owner): self.QuestionNumberLabel = None self.Question = None self.OptionA = None self.OptionB = None self.OptionC = None self.OptionD = None self.NextQuestion = None self.AnswerStatus = None self.LoadProps(os.path.join(os.path.dirname(os.path.abspath(__file__)), "Quiz.pyfmx")) def OptionAClick(self, Sender): pass def OptionBClick(self, Sender): pass def OptionCClick(self, Sender): pass def OptionDClick(self, Sender): pass def NextQuestionClick(self, Sender): pass |
Notice that the QuizForm
constructor does not take in any values. We will get to that later in the tutorial.
Finally, let’s take a look at Results.py
, which we will use to display our results:
1 2 3 4 5 6 7 8 9 10 11 |
import os from delphifmx import * class ResultsForm(Form): def __init__(self, owner): self.Score = None self.Level = None self.ResultLabel = None self.LoadProps(os.path.join(os.path.dirname(os.path.abspath(__file__)), "Results.pyfmx")) |
How to Add Functionality To the Quiz App?
Now that our app is ready, we can add logic to our game.
What Initializations and Imports Have to be Made?
Go to your project folder and open up Main.py
.
For our MainForm
the only thing we need to do is open up the QuizForm
that will display our questions. To do this, first, import the QuizForm
class from Quiz.py
.
1 2 |
from Quiz import QuizForm |
Next, navigate to the StartClick
function and create a new variable named self.QuestionWindow
will create a new instance of the QuizForm
. We then display the new form using the show()
method. Our final Main.py
looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
import os from delphifmx import * from Quiz import QuizForm class MainForm(Form): def __init__(self, owner): self.Title = None self.Start = None self.LoadProps(os.path.join(os.path.dirname(os.path.abspath(__file__)), "Main.pyfmx")) def StartClick(self, Sender): self.QuestionWindow = QuizForm(self) # Create question 1 window self.QuestionWindow.show() |
How to Add Main Functionality to All the Buttons in Main Question Form?
Now let’s take a look at our QuizForm
that will display our questions. Let’s start by initializing two variables self.Score
and self.QuestionNumber
that initializes the score and question number of our quiz.
Let’s store these values inside two instance variables in the class constructor:
1 2 3 |
self.QuestionNumber = 1 self.Score = 0 |
Next, let’s define a nested dictionary that contains our questions:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# Dictionary with all of the quiz data self.QuizQuestions = { 1:{"Question":"Which operator has higher precedence:","Answer":"** (Exponent)", "Options":["> (Comparison)", "** (Exponent)", "& (BitWise AND)", "% (Modulus)"]}, 2:{"Question":"What is a correct syntax to output 'Hello World' in Python?","Answer":"print('Hello World')", "Options":["print('Hello World')", "print 'Hellow World'", "p('Hello World')", "echo 'Hello World'"]}, 3:{"Question":"How do you insert comments in Python code?","Answer":"#Comment", "Options":["#Comment", "//Comment", "!Comment", "/*Comment*/"]}, 4:{"Question":"Which of the following is not a legal variable name","Answer":"python-GUI", "Options":["_pythonGUI", "python_GUI", "pythonGUI", "python-GUI"]}, 5:{"Question":"What is the correct syntax to output the type of a variable or object in Python?","Answer":"print(type(x))", "Options":["print(type x)", "print(typeOf(x))", "print(type(x))", "print(typeof(x))"]}, 6:{"Question":"What is the correct way to create a function in Python?","Answer":"def myfunc():", "Options":["create myfunc():", "function myfunc():", "def myfunc():", "func myfunc():"]}, 7:{"Question":"What is a correct syntax to return the first character in a string?","Answer":"'PythonGUI'[0]", "Options":["'PythonGUI'[0]", "'PythonGUI'[1]", "'PythonGUI'.sub(0,1)", "sub('PythonGUI',0,1)"]}, 8:{"Question":"Which method can be used to remove any whitespace from both the beginning and the end of a string?","Answer":"strip()", "Options":["len()", "strip()", "split()", "ptrim()"]}, 9:{"Question":"Which collection is ordered, changeable, and allows duplicate members?","Answer":"List", "Options":["List", "Dictionary", "Set", "Tuple"]}, 10:{"Question":"Which statement is used to stop a loop?","Answer":"break", "Options":["break", "exit", "return", "stop"]} } |
The dictionary contains the QuestionNumber
as its key and another dictionary with the question, answer options as a list, and correct answer. We will finally call an __UpdateLabels()
function that populates the labels in our form based on the question number. Here is what our __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 |
def __init__(self, owner): self.QuestionNumberLabel = None self.Question = None self.OptionA = None self.OptionB = None self.OptionC = None self.OptionD = None self.NextQuestion = None self.AnswerStatus = None self.LoadProps(os.path.join(os.path.dirname( os.path.abspath(__file__)), "Quiz.pyfmx")) self.Score = 0 # Initialize quiz score self.QuestionNumber = 1 # Initialize question number # Dictionary with all of the quiz data self.QuizQuestions = { 1: {"Question": "Which operator has higher precedence:", "Answer": "** (Exponent)", "Options": ["> (Comparison)", "** (Exponent)", "& (BitWise AND)", "% (Modulus)"]}, 2: {"Question": "What is a correct syntax to output 'Hello World' in Python?", "Answer": "print('Hello World')", "Options": ["print('Hello World')", "print 'Hellow World'", "p('Hello World')", "echo 'Hello World'"]}, 3: {"Question": "How do you insert comments in Python code?", "Answer": "#Comment", "Options": ["#Comment", "//Comment", "!Comment", "/*Comment*/"]}, 4: {"Question": "Which of the following is not a legal variable name", "Answer": "python-GUI", "Options": ["_pythonGUI", "python_GUI", "pythonGUI", "python-GUI"]}, 5: {"Question": "What is the correct syntax to output the type of a variable or object in Python?", "Answer": "print(type(x))", "Options": ["print(type x)", "print(typeOf(x))", "print(type(x))", "print(typeof(x))"]}, 6: {"Question": "What is the correct way to create a function in Python?", "Answer": "def myfunc():", "Options": ["create myfunc():", "function myfunc():", "def myfunc():", "func myfunc():"]}, 7: {"Question": "What is a correct syntax to return the first character in a string?", "Answer": "'PythonGUI'[0]", "Options": ["'PythonGUI'[0]", "'PythonGUI'[1]", "'PythonGUI'.sub(0,1)", "sub('PythonGUI',0,1)"]}, 8: {"Question": "Which method can be used to remove any whitespace from both the beginning and the end of a string?", "Answer": "strip()", "Options": ["len()", "strip()", "split()", "ptrim()"]}, 9: {"Question": "Which collection is ordered, changeable, and allows duplicate members?", "Answer": "List", "Options": ["List", "Dictionary", "Set", "Tuple"]}, 10: {"Question": "Which statement is used to stop a loop?", "Answer": "break", "Options": ["break", "exit", "return", "stop"]} } self.__UpdateLabels() |
Next, we need to create a __UpdateLabels()
function that will help us display our question in the Question
label and its corresponding answers in the buttons. We access each value of the dictionary using the self.QuestionNumber
variable. We then display each value using the .Text
property of each object. In addition, we also update the QuestionNumberLabel
to display the current question number.
Here is what our final __UpdateLabels()
function looks like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
def __UpdateLabels(self): # Display options of the current question self.OptionA.Text = self.QuizQuestions[self.QuestionNumber]["Options"][0] self.OptionB.Text = self.QuizQuestions[self.QuestionNumber]["Options"][1] self.OptionC.Text = self.QuizQuestions[self.QuestionNumber]["Options"][2] self.OptionD.Text = self.QuizQuestions[self.QuestionNumber]["Options"][3] # Display question number self.QuestionNumberLabel.Text = str(self.QuestionNumber) + " of 10" # Display question text self.Question.Text = self.QuizQuestions[self.QuestionNumber]["Question"] # Resetting Status self.AnswerStatus.Text = "" |
Now that we have displayed our questions, we need to check whether the option a user selects is correct. To do this, we can use the click functions. Let’s implement this functionality for OptionA
.
Navigate to OptionAClick
, and start by checking if a button has already been selected. We will use the AnswerStatus
label to check whether there is an option that has already been selected. If an option has already been selected, we will allow no changes:
1 2 3 4 |
# Ensure some button not already clicked if self.AnswerStatus.Text == "Correct" or self.AnswerStatus.Text == "Incorrect": pass |
Next, we can check whether the text in the button corresponds to the correct answer to the question. If the correct answer has been selected, we will increment the score and update the AnswerStatus
. Otherwise, we will display an Incorrect error message.
1 2 3 4 5 6 7 8 |
# If correct answer chosen then increase score and print correct elif self.OptionA.Text == self.QuizQuestions[self.QuestionNumber]["Answer"]: self.Score += 1 self.AnswerStatus.Text = "Correct" # If incorrect answer chosen then print incorrect else: self.AnswerStatus.Text = "Incorrect" |
Here is what our final OptionAClick
function looks like:
1 2 3 4 5 6 7 8 9 10 11 12 |
def OptionAClick(self, Sender): # Ensure some button not already clicked if self.AnswerStatus.Text == "Correct" or self.AnswerStatus.Text == "Incorrect": pass # If correct answer chosen then increase score and print correct elif self.OptionA.Text == self.QuizQuestions[self.QuestionNumber]["Answer"]: self.Score += 1 self.AnswerStatus.Text = "Correct" # If incorrect answer chosen then print incorrect else: self.AnswerStatus.Text = "Incorrect" |
We can replicate this step for the other option click functions.
Finally, we need a way to display the next question or to open up the ResultsForm
. To do this, we start by importing the ResultsForm
from Results.py
.
1 2 |
from Results import ResultsForm # import result form to create window |
Next, navigate to the NextQuestionClick
function. For our app, we will only allow the next question to appear only if the user has answered the current question. To do this, we check the AnswerStatus
to see if it has been updated. If the AnswerStatus
is empty or shows an error message, we display an error:
1 2 3 4 5 |
# Checking if user has answered a question. # User can only proceed to next question if an answer has been selected if self.AnswerStatus.Text == "" or self.AnswerStatus.Text == "Select an answer before proceeding!": self.AnswerStatus.Text = "Select an answer before proceeding!" |
If the user has answered the current question, we increment the self.QuestionNumber
by 1
. Next, we check whether all ten questions have been answered. If the user has answered all ten questions, we will display the ResultsForm
, we will update the questions by calling the __UpdateLabels
function.. Here is what our final NextQuestionClick
function looks like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
def NextQuestionClick(self, Sender): # Checking if user has answered a question. # User can only proceed to next question if an answer has been selected if self.AnswerStatus.Text == "" or self.AnswerStatus.Text == "Select an answer before proceeding!": self.AnswerStatus.Text = "Select an answer before proceeding!" else: self.QuestionNumber += 1 # Update question number to display the next one if self.QuestionNumber <= 10: # If the ten questions have not been asked self.__UpdateLabels() else: # It the ten questions have been asked, show the result form self.ResultsWindow = ResultsForm(self, Score=self.Score) self.ResultsWindow.show() |
Here are the final contents of Quiz.py
.
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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
import os from delphifmx import * from Results import ResultsForm # import result form to create window class QuizForm(Form): def __init__(self, owner): self.QuestionNumberLabel = None self.Question = None self.OptionA = None self.OptionB = None self.OptionC = None self.OptionD = None self.NextQuestion = None self.AnswerStatus = None self.LoadProps(os.path.join(os.path.dirname( os.path.abspath(__file__)), "Quiz.pyfmx")) self.Score = 0 # Initialize quiz score self.QuestionNumber = 1 # Initialize question number # Dictionary with all of the quiz data self.QuizQuestions = { 1: {"Question": "Which operator has higher precedence:", "Answer": "** (Exponent)", "Options": ["> (Comparison)", "** (Exponent)", "& (BitWise AND)", "% (Modulus)"]}, 2: {"Question": "What is a correct syntax to output 'Hello World' in Python?", "Answer": "print('Hello World')", "Options": ["print('Hello World')", "print 'Hellow World'", "p('Hello World')", "echo 'Hello World'"]}, 3: {"Question": "How do you insert comments in Python code?", "Answer": "#Comment", "Options": ["#Comment", "//Comment", "!Comment", "/*Comment*/"]}, 4: {"Question": "Which of the following is not a legal variable name", "Answer": "python-GUI", "Options": ["_pythonGUI", "python_GUI", "pythonGUI", "python-GUI"]}, 5: {"Question": "What is the correct syntax to output the type of a variable or object in Python?", "Answer": "print(type(x))", "Options": ["print(type x)", "print(typeOf(x))", "print(type(x))", "print(typeof(x))"]}, 6: {"Question": "What is the correct way to create a function in Python?", "Answer": "def myfunc():", "Options": ["create myfunc():", "function myfunc():", "def myfunc():", "func myfunc():"]}, 7: {"Question": "What is a correct syntax to return the first character in a string?", "Answer": "'PythonGUI'[0]", "Options": ["'PythonGUI'[0]", "'PythonGUI'[1]", "'PythonGUI'.sub(0,1)", "sub('PythonGUI',0,1)"]}, 8: {"Question": "Which method can be used to remove any whitespace from both the beginning and the end of a string?", "Answer": "strip()", "Options": ["len()", "strip()", "split()", "ptrim()"]}, 9: {"Question": "Which collection is ordered, changeable, and allows duplicate members?", "Answer": "List", "Options": ["List", "Dictionary", "Set", "Tuple"]}, 10: {"Question": "Which statement is used to stop a loop?", "Answer": "break", "Options": ["break", "exit", "return", "stop"]} } self.__UpdateLabels() def OptionAClick(self, Sender): # Ensure some button not already clicked if self.AnswerStatus.Text == "Correct" or self.AnswerStatus.Text == "Incorrect": pass # If correct answer chosen then increase score and print correct elif self.OptionA.Text == self.QuizQuestions[self.QuestionNumber]["Answer"]: self.Score += 1 self.AnswerStatus.Text = "Correct" # If incorrect answer chosen then print incorrect else: self.AnswerStatus.Text = "Incorrect" def OptionBClick(self, Sender): # Ensure some button not already clicked if self.AnswerStatus.Text == "Correct" or self.AnswerStatus.Text == "Incorrect": pass # If correct answer chosen then increase score and print correct elif self.OptionB.Text == self.QuizQuestions[self.QuestionNumber]["Answer"]: self.Score += 1 self.AnswerStatus.Text = "Correct" # If incorrect answer chosen then print incorrect else: self.AnswerStatus.Text = "Incorrect" def OptionCClick(self, Sender): # Ensure some button not already clicked if self.AnswerStatus.Text == "Correct" or self.AnswerStatus.Text == "Incorrect": pass # If correct answer chosen then increase score and print correct elif self.OptionC.Text == self.QuizQuestions[self.QuestionNumber]["Answer"]: self.Score += 1 self.AnswerStatus.Text = "Correct" # If incorrect answer chosen then print incorrect else: self.AnswerStatus.Text = "Incorrect" def OptionDClick(self, Sender): # Ensure some button not already clicked if self.AnswerStatus.Text == "Correct" or self.AnswerStatus.Text == "Incorrect": pass # If correct answer chosen then increase score and print correct elif self.OptionD.Text == self.QuizQuestions[self.QuestionNumber]["Answer"]: self.Score += 1 self.AnswerStatus.Text = "Correct" # If incorrect answer chosen then print incorrect else: self.AnswerStatus.Text = "Incorrect" def NextQuestionClick(self, Sender): # Checking if user has answered a question. # User can only proceed to next question if an answer has been selected if self.AnswerStatus.Text == "" or self.AnswerStatus.Text == "Select an answer before proceeding!": self.AnswerStatus.Text = "Select an answer before proceeding!" else: self.QuestionNumber += 1 # Update question number to display the next one if self.QuestionNumber <= 10: # If the ten questions have not been asked self.__UpdateLabels() else: # It the ten questions have been asked, show the result form self.ResultsWindow = ResultsForm(self, Score=self.Score) self.ResultsWindow.show() def __UpdateLabels(self): # Display options of the current question self.OptionA.Text = self.QuizQuestions[self.QuestionNumber]["Options"][0] self.OptionB.Text = self.QuizQuestions[self.QuestionNumber]["Options"][1] self.OptionC.Text = self.QuizQuestions[self.QuestionNumber]["Options"][2] self.OptionD.Text = self.QuizQuestions[self.QuestionNumber]["Options"][3] # Display question number self.QuestionNumberLabel.Text = str(self.QuestionNumber) + " of 10" # Display question text self.Question.Text = self.QuizQuestions[self.QuestionNumber]["Question"] # Resetting Status self.AnswerStatus.Text = "" |
How to Display all Relevant Information on the Results Form?
Now let’s display our final quiz results in the ResultsForm
.
Similarly to the QuizForm
, our ResultsForm
does not take in any additional parameters. Therefore, we will update the __init__
function to take in the final Score
:
1 2 |
def __init__(self, owner, Score): |
Next, we can display the score by simply using the .Text
property of the self.Score
label. We also display the level of the user based on their score on the quiz. Here is what our final Results.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 os from delphifmx import * class ResultsForm(Form): def __init__(self, owner, Score): self.Score = None self.Level = None self.ResultLabel = None self.LoadProps(os.path.join(os.path.dirname(os.path.abspath(__file__)), "Results.pyfmx")) self.Score.Text = "Score: " + str(Score) # Display score out of ten # Display level, based on score if Score < 6: self.Level.Text += " Novice" elif Score < 9: self.Level.Text += " Intermediate" else: self.Level.Text += " Expert" |
Now that code is ready, we can run our app by running PythonQuizApp.py
. Here is what our app looks like:
How to Build this Quiz App As An Android Application Using Delphi?
Now that we have our PythonQuizApp ready let’s convert this into an Android application.
The Delphi4Python Exporter exports PythonQuizApp with initialization logic for a desktop-based application. Therefore, we will use the PythonFMXBuilder to convert it to an Android app.
So, open up FMXBuilder and click on Project > New project
on the toolbar. Enter the name of the project that you want to build here. Here we define our project as PythonQuizApp
.
Before we can add our Python files we need to change some code that will allow us to run our project in Android. Let’s create a new file named PythonQuizApp_Android.py
and paste the contents of PythonQuizApp.py
.
Next, add your Python files as well as any other supporting project files you used to build your application. Here we will not be adding PythonQuizApp.py
as it will only be used to run our desktop application:
Now, right-click on PythonQuizApp_Android.py
file and set it to the main file. But before we can build an .apk
, let’s make some important changes to our code.
First off, Android applications are initialized automatically by Delphi applications. Because the program will be initialized automatically, we don’t need to initialize it or set a title manually. The Application.MainForm
doesn’t need to be initialized either but just needs a variable. Lastly, like initialization, we don’t need to launch or destroy the program because Android handles both tasks.
Here is what our PythonQuizApp_Android.py
looks like:
1 2 3 4 5 6 7 8 9 10 |
from delphifmx import * from Main import MainForm def main(): Application.MainForm = MainForm(Application) Application.MainForm.Show() if __name__ == '__main__': main() |
Save the file with the code changes you’ve just made.
You can easily install the app on your mobile device thanks to PythonFMXBuilder by clicking on the Run
Project button. We can alternatively also create an .apk
file to create an Android application. Click the Build
Project button on the toolbar to create your file.
You will be prompted with a “Build process done
” notification in the Messages box once the .apk
has been entirely generated.
Your generated file will be in the pathtoPythonFMXBuilderGUIexeFolderappsPythonQuizAppbin
folder.
Just copy and paste this .apk
file into your phone’s storage. If you access this file from your phone and click on it, you will be prompted with an installation message, which you should proceed with. Then, your PythonQuizApp will be ready for use.
Does the App Work on Your Android Device?
Here is what our Python quiz app looks like on an Android device:
When we press the start button, we are taken to the next form or the first question.
Now, if we select the Next button without selecting any answer, we will not proceed and will get an error prompt.
As soon as we select a question, we get to know whether our answer is correct or not.
Then we can even click Next to move forward.
After attempting the entire quiz, we get an updated score and a level based on the score.
What Are the Key Takeaways From this Tutorial?
Congratulations on completing this tutorial. We hope it has helped you realize how easy Python GUI development is when using the correct tools.
Developing a Python quiz application with DelphiFMX is a fantastic method to demonstrate your programming prowess and evaluate your language proficiency. DelphiFMX makes it simple to construct cross-platform programs that can operate on various devices thanks to its user-friendly interface and robust functionality. This project is a fun approach to developing your abilities and broadening your knowledge, regardless of whether you are an experienced programmer or just getting started with Python.
What Are the FAQs Regarding This Topic?
What is DelphiFMX?
Using the Delphi programming language, developers can construct cross-platform apps utilizing the DelphiFMX software development environment. In addition to a library of pre-built components for typical programming tasks, it offers a visual designer for developing user interfaces. You can use it to create several applications such as ToDo Apps, TicTacToe Apps, or Currency Converters.
Which programming language was employed in developing the quiz application in this article?
Python was used to develop the article’s quiz application. The popular high-level programming language Python is praised for being straightforward and readable. It is employed in various applications, including artificial intelligence, data analysis, and web building.
What is the purpose of creating a quiz application with DelphiFMX?
The goal of using DelphiFMX to construct a quiz application is to produce a cross-platform quiz application that can be used on both Windows and Android. DelphiFMX is the perfect option for building cross-platform apps since it offers a straightforward method for creating user interfaces that function across several platforms.
What are the features of the quiz application created in this article?
The quiz application created in this article allows users to take quizzes, view their scores, and review their answers. They can reset the quiz if they want to retake it.
Why is PyScripter a popular IDE?
When PyScripter was launched, it was a simple IDE that provided a reliable scripting solution for Delphi programs. It evolved into a complete standalone Python IDE over time. Delphi was used to develop it. Python4Delphi, however, enables the addition of Python programs (P4D). It is lighter than other IDEs because it was created in a compiled language. You can use PyScripter’s project management, file explorer, Python interpreter, and debugger, among other things.