Today, We’ll be discussing one more graphical package in Python, which is also known as PyQt. To faster design the GUI, we’ll be exploring another tool called Qt Designer, which is available for multiple OS platforms.
Please find the QT Designer here.
This is similar to any other GUI based IDE like Microsoft Visual Studio, where you can quickly generate your GUI template.
The majority of the internet post talks about using PyQt5 or PyQt4 packages. But, when speaking about using the .ui file inside your Python code – they either demonstrate fundamental options without any event or, they convert & generate the .ui file into .py file & then they use it. This certainly not making it very useful for many of the developers who are trying to use it for the first time. Hence, My main goal is to use the .ui file inside my Python script as it is & use all the components out of it & assign various working events.
In this post, we’ll discuss only with one script & then we’ll showcase the output in the form of video (No audio). You can verify the output for both MAC & Windows.
Before we start, let us check the directory structure between Windows & MAC –
Let us explore how the GUI should look like ->
So, as you can see that this tool is like any other GUI based tool, basically you can create anything by simply drag & drop method.
Before we start discussing our code, here is the sample basicAdv.ui file for your reference.
You need to install the following framework –
pip install PyQt5
1. GUIPyQt5.py (This script contains all the GUI details & it will invoke the instance along with the logic.)
Let us explore a few key lines from this script. Rests are almost identical.
# Loading the Graphical Design without # converting it to any kind of Python code uic.loadUi('basicAdv.ui', self)
Loading the GUI created using Qt Designer into the Python environment.
# Adding all the essential buttons self.prtBtn = self.findChild(QtWidgets.QPushButton, 'prtBtn') # Find the button self.prtBtn.clicked.connect(self.printButtonClick) # Remember to pass the definition/method, not the return value!
In this case, we’re dynamically binding the component from the GUI by using the findChild method & then on the next line, we’re invoking the appropriate event associated with that. In this case, it is – self.printButtonClick.
The printButtonClick as mentioned earlier is a method & that contains the following snippet –
def printButtonClick(self): # This is executed when the button is pressed print('Input text:' + self.input.text())
As you can see, this event will capture the text from the input textbox & print it on our terminal.
Here is the snippet for those widgets, which is part of only input/output & they generally don’t have an event of their own. But, we need to bind them with our Python application.
# Adding other static input/output elements self.input = self.findChild(QtWidgets.QLineEdit, 'input') self.qlabel = self.findChild(QtWidgets.QLabel, 'qlabel') self.lineEdit = self.findChild(QtWidgets.QLineEdit, 'lineEdit') self.listWidget = self.findChild(QtWidgets.QListWidget, 'listWidget')
This application has drop-down list & hence, we’ve added some static value during our load of this application & that can be seen here –
# Adding list Box self.listwidget2 = self.findChild(QtWidgets.QListWidget, 'listwidget2') # Find the List # Adding static element to it self.listwidget2.insertItem(0, "Aamir Khan") self.listwidget2.insertItem(1, "Shahruk Khan") self.listwidget2.insertItem(2, "Salman Khan") self.listwidget2.insertItem(3, "Hrittik Roshon") self.listwidget2.insertItem(4, "Amitabh Bachhan")
Once, the user will select a specific value from this list, the app will execute the following event as shown below –
# Click Event self.listwidget2.clicked.connect(self.showIndividualElement)
Again, to explore the method, you need to view the given logic –
def showIndividualElement(self, qmodelindex): item = self.listwidget2.currentItem() print(item.text())
Group Box, along with the radio button, works slightly different than our drop-down list.
For each radio button, we’ll have a dedicated text value that represents a different country in this context.
And, our application will bind all the radio button & then they will use one standard method for all of these four options as shown below –
# Adding Individual Radio Button self.rdButton1 = self.findChild(QtWidgets.QRadioButton, 'rdButton1') # Find the button self.rdButton1.setChecked(True) self.rdButton1.toggled.connect(lambda: self.printRadioButtonClick(self.rdButton1)) # Remember to pass the definition/method, not the return value! self.rdButton2 = self.findChild(QtWidgets.QRadioButton, 'rdButton2') # Find the button self.rdButton2.toggled.connect(lambda: self.printRadioButtonClick(self.rdButton2)) # Remember to pass the definition/method, not the return value! self.rdButton3 = self.findChild(QtWidgets.QRadioButton, 'rdButton3') # Find the button self.rdButton3.toggled.connect(lambda: self.printRadioButtonClick(self.rdButton3)) # Remember to pass the definition/method, not the return value! self.rdButton4 = self.findChild(QtWidgets.QRadioButton, 'rdButton4') # Find the button self.rdButton4.toggled.connect(lambda: self.printRadioButtonClick(self.rdButton4)) # Remember to pass the definition/method, not the return value!
Also, note that, by default, rdButton1 is set to True i.e., it will be selected when the form load initially.
Let’s explore the printRadioButtonClick event.
def printRadioButtonClick(self, radioOption): if radioOption.text() == 'China': if radioOption.isChecked() == True: print(radioOption.text() + ' is selected') else: print(radioOption.text() + ' is deselected') if radioOption.text() == 'India': if radioOption.isChecked() == True: print(radioOption.text() + ' is selected') else: print(radioOption.text() + ' is deselected') if radioOption.text() == 'Japan': if radioOption.isChecked() == True: print(radioOption.text() + ' is selected') else: print(radioOption.text() + ' is deselected') if radioOption.text() == 'France': if radioOption.isChecked() == True: print(radioOption.text() + ' is selected') else: print(radioOption.text() + ' is deselected')
This will capture the radio button option & based on the currently clicked button, it will fetch the text out of it. Finally, that will match with the logic here & based on that, our application will display the output.
Finally, the Image process is slightly different.
Initially, our application will load the component from the .ui file & bind them with the Python environment –
self.imageLbl = self.findChild(QtWidgets.QLabel, 'imageLbl')
Image load option will only work when the user clicks the button that triggers the following sets of actions –
self.selectImgBtn = self.findChild(QtWidgets.QPushButton, 'selectImgBtn') # Find the button self.selectImgBtn.clicked.connect(self.setImage) # Remember to pass the definition/method, not the return value!
Let’s explore the setImage method –
def setImage(self): fileName, _ = QtWidgets.QFileDialog.getOpenFileName(None, "Select Image", "", "Image Files (*.png *.jpg *jpeg *.bmp);;All Files (*)") # Ask for file if fileName: # If the user gives a file pixmap = QtGui.QPixmap(fileName) # Setup pixmap with the provided image pixmap = pixmap.scaled(self.imageLbl.width(), self.imageLbl.height(), QtCore.Qt.KeepAspectRatio) # Scale pixmap self.imageLbl.setPixmap(pixmap) # Set the pixmap onto the label self.imageLbl.setAlignment(QtCore.Qt.AlignCenter) # Align the label to center
This will prompt the corresponding dialogue box for choosing the right images out of the respective O/S.
Last but not least, the use of MsgBox, which can be extremely useful for many GUI based programming.
This msgbox doesn’t exist in the form. However, we’re creating it on the event of the “Confirm Button” as shown below –
self.cnfBtn = self.findChild(QtWidgets.QPushButton, 'cnfBtn') # Find the button self.cnfBtn.clicked.connect(self.showDialog) # Remember to pass the definition/method, not the return value!
This will prompt the showDialog method to trigger –
def showDialog(self): msgBox = QMessageBox() msgBox.setIcon(QMessageBox.Information) msgBox.setText("Message box pop up window") msgBox.setWindowTitle("MessageBox Example") msgBox.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel) msgBox.buttonClicked.connect(self.msgButtonClick) returnValue = msgBox.exec() if returnValue == QMessageBox.Ok: print('OK clicked')
And, based on your options (“OK”/”Cancel”), it will prompt the final captured message in your console.
Let’s explore the videos of output from Windows O/S –
Let’s explore the video output from MAC VM –
For more information on this package – please check the following link.
So, as you can see, finally we’ve achieved it. We’ve demonstrated cross-platform GUI applications using native Python. And, here we didn’t even convert the ui design file to python script either.
Please share your feedback.
I’ll be posting another new post in the coming days. Till then, Happy Avenging! 😀
Note: All the data posted here are representational data & available over the internet & for educational purpose only.