PyQt cross platform application development PyQt beginners example

When someone says cross platform application development, always take this with a pinch of salt. Whenever an application is written and you are trying to run it on different platforms, do not assume there is some magic tool and at the press of a button you will get various executables targeting different platforms. That is a panacea that does not exist in the mortal world. You still have to do some porting, at the least compiling it using different platform compiler. This said cross platform development has taken rapid strides, write once – deploy everywhere has become an adage.

In this introduction to PyQt our target is to understand how PyQt works, the process of development and we will look at a trivial application put together with PyQt. [Mind you the application is trivial so do not expect an enterprise application, but nevertheless it will get you started]

What is PyQt ?
To understand PyQt and why it is an important innovation, you need to know what is Qt. Well, Qt [Pronounced “cute”] is a cross platform application framework [mind you it is not merely a widget toolkit, it is an assortment of various pieces of software library written to provide real fast and peace-of-mind development ability [read agile]. Yes Mozilla Firefox, VLC player, Nokia Symbian phones, Samsung, Walt Disney and many more leading & popular companies use Qt. Read more here. So you get the idea Qt provides an easy way to make GUI [Graphical User Interface which look native on each platform] and gives us lots many libraries to code easily.

So the next point is what is and why PyQt. Well Qt is written in C++ originally by a company called Trolltech [Funny 😛 ] . Then Nokia purchased it and released an open source edition. The popularity of Qt grew in Europe and slowly all over the globe. The power of C++ and cross-platform flexibility of Qt made it an indispensable tool in the arsenal of countless programmers. It was but natural that different language bindings started to come for Qt. We have bindings for so many programming languages. Something which is used heavily in Europe got to have Python binding right. Do not we all love Python anyway. PyQt is the Python binding for Qt, with the ease of Python language PyQt feels more natural & convenient to use, specially if we are developing application targeting the “Internet-of-Things”.


Current Scenario:

The latest version of PyQt is PyQt5 which uses Qt framework 5.3 which has support for

  • Android
  • iOs
  • Windows
  • Windows RT / Windows Phone 8
  • Mac
  • Linux
  • Sailfish OS
  • Tizen
  • Blackberry 10 / QNX
  • The people behind PyQt are a company called river bank software. To download the latest version and all other versions of PyQt you can go ahead and click on the following link :
  • PyQt 5 Download

For this to work first we need a Python 3.4 interpreter the latest being 3.4.1, go ahead and download it here:

Another thing you need is SIP which can be downloaded and installed from here:

Assuming you have downloaded and installed all the above software and if you have chosen the Binary package for windows then you will have a PyQt Designer also available to you & trust me this is the fastest way to build the User Interface [UI] and the result is always very standardized modular Python code. So go ahead and use this tool.


Now we will dive into our example application, its code and will try to understand what is going on here.

  • As I said earlier the application we are discussing here is to provide the understanding of PyQt
  • The application under consideration is a Wikipedia search tool
  • We provide the user with an input textbox and he can type in his query
  • There is a submit button which will then load the searched content in a web-view underneath

This is how the user interface looks:

ui

See I have used the PyQt designer to design this using a MainWindow as the main entry point for the application and laid out the following widgets on top of it:

  • A text input [QLineEdit]
  • A button [QPushButton]
  • A web – view [QWebView]

Then I have saved the file as wikepedia.ui

Once the file is saved, we can fire a command prompt window and write down the following command to generate a Python class file which will create this user interface. Let me tell you here we are this way implementing our M-V-C architecture sans model and this trivial application does not have any domain models as such. But we are going to keep the UI in a separate file [UI] and the logic on a separate file [Main app].

The command to run is:

pyuic5 wikipedia.ui -o wikipedia.py

The above line of code simply means Python UI converter version 5 please take my input of wikipedia.ui file and kindly convert it into a Python file giving me the output [-o] of wikipedia.py file. Sure enough you being the master the Pyuic slave of yours will convert your created design in the PyQt designer into a Python file [yes object oriented python file]. Let us have a look at the code that what generated in my application’s case :

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'wikipedia.ui'
#
# Created: Mon Aug  4 08:14:27 2014
#      by: PyQt5 UI code generator 5.3.1
#
# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.setEnabled(True)
        MainWindow.resize(800, 600)
        MainWindow.setMinimumSize(QtCore.QSize(800, 600))
        MainWindow.setMaximumSize(QtCore.QSize(800, 600))
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(10, 10, 391, 21))
        font = QtGui.QFont()
        font.setFamily("Georgia")
        font.setPointSize(12)
        font.setItalic(True)
        self.label.setFont(font)
        self.label.setObjectName("label")
        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.setGeometry(QtCore.QRect(10, 40, 381, 31))
        font = QtGui.QFont()
        font.setFamily("Calibri")
        font.setPointSize(12)
        self.lineEdit.setFont(font)
        self.lineEdit.setAutoFillBackground(False)
        self.lineEdit.setObjectName("lineEdit")
        self.webView = QtWebKitWidgets.QWebView(self.centralwidget)
        self.webView.setEnabled(True)
        self.webView.setGeometry(QtCore.QRect(10, 90, 780, 520))
        self.webView.setUrl(QtCore.QUrl("http://en.wikipedia.com"))
        self.webView.setObjectName("webView")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setEnabled(True)
        self.pushButton.setGeometry(QtCore.QRect(410, 40, 81, 31))
        font = QtGui.QFont()
        font.setFamily("Georgia")
        font.setPointSize(11)
        self.pushButton.setFont(font)
        self.pushButton.setFlat(False)
        self.pushButton.setObjectName("pushButton")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 640, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "Desktop Wikipedia by SO"))
        self.label.setText(_translate("MainWindow", "Enter the item you want information from wikipedia"))
        self.pushButton.setText(_translate("MainWindow", "Search"))

from PyQt5 import QtWebKitWidgets

 

Let us understand this bit of code [although it is very intuitive] :

  • It imports the required libraries by looking at the widgets used in the ui file
  • It creates a class UI_MainWindow as Main_Window [QMainWindow] was our primary widget
  • In the UI designer I had set the minimum and maximum size so that no one can resize our application window and surely enough the converter has kept that in the code too
  • Pay attention to how the converter has created the setObjectName property for each widget as that is what we can use to call the signals and do the manipulation during our application run-time.
  • If I would have specified custom object names it would insert them since I did not for this trivial application with three controls it has given automatic names to the objects.
  • It has laid out the sizes and the fonts etc.

That is pretty much all we have in this file.


Now let’s create the main application logic. We can create another Python file and start writing the code. I have called my file app.py and the code on this is as follows:

  • from PyQt5 import QtCore, QtGui, QtWidgets
    from PyQt5.QtWidgets import QApplication, QMainWindow
    from wikipedia import Ui_MainWindow
    
    class Operation(QMainWindow):
        def __init__(self, parent=None):
            QMainWindow.__init__(self, parent)
            self.ui = Ui_MainWindow()
            self.ui.setupUi(self)
            self.ui.pushButton.clicked.connect(self.calldata)
    
        def calldata(self):
            qrstr = self.ui.lineEdit.text()
            self.ui.webView.setUrl(QtCore.QUrl('http://en.wikipedia.org/w/index.php?search='+qrstr+''))
            
    if __name__ == '__main__':
    
        import sys
        app = QApplication(sys.argv)
        window = Operation()
        window.show()
        sys.exit(app.exec_())
    
    

    Let us understand what we are doing here [trust me very basic stuff]:

  • first as usual all the import statements.
  • Then I define a class called operation [can be named anything ] and it is derived from the QMainWindow class so all the goodies of QMainWindow is available to it.
  • Then we have initialized it do not get intimidated by __init__ [that’s just the way python writes it and it means just initialize the method]
  • the most important point here is self.ui = Ui_Mainwindow() , this is where we are setting up this particular window as an instance of our UI class, thus it will have everything the UI has and will look like that [ smart hmmm 😀 ]
  • Now we are calling the pushButton’s clicked method [signal : all Qt widget’s emit signal]  to hook with the calldata function [SLOT : signals can connect with slots]
  • calldata method is very trivial it gets activated on the QPushButton press and reads the value in the QLineEdit and stores it in a variable “qrstr
  • then the QWebView url is set to the Wikipedia search URL along with the querystring thus we get our desired result in the web view which is a webkit browser

All in all the final working example looks like this

appscreen


Conclusion :

  • I hope this demonstration will make a novice trying to jump into PyQt 5 development a tad bit easier. Trust me there is hardly any complete help on the web to get started except for some examples which unfortunately trolltech site has taken down. Nothing available in the Digia site specific to PyQt
  • Anyone who knows Python and has an idea about its ease and power then really PyQt is a charm to develop with.
  • Qt framework again is really a leading toolkit and very robust as well as thorough compared to GTK, wxWidget and all others. They have a long way to go before they reach Qt’s robustness
  • The best part I can take the source code and without making any changes can compile it on any Qt supporting platforms and the app would run in the same manner with a native look
  • Hope you enjoyed this tutorial 🙂

Thanks

Shakeel