1. Python Qt5 (Under progress)

1.1. Basics

1.1.1. Creating widget

# qt5_ex.py

import sys
from PyQt5.QtWidgets import QApplication, QWidget

def main():
    app = QApplication(sys.argv)
    w = QWidget()

    # title for widget
    w.setWindowTitle("PyQt5")

    # left margin, top margin, width, height
    # w.setGeometry(250, 250, 200, 150)
    # or use below two lines
    w.resize(200, 150)
    w.move(250, 250)
    w.show()

    # wait to exit
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

1.1.2. Hello World

# qt5_ex.py

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLabel

def main():
    app = QApplication(sys.argv)
    w = QWidget()

    # create label
    b = QLabel(w)
    b.setText("Hello World") # text value
    b.move(75, 75) # location of label

    # title for widget
    w.setWindowTitle("PyQt5")

    # left margin, top margin, width, height
    # w.setGeometry(250, 250, 200, 150)
    # or use below two lines
    w.resize(200, 150)
    w.move(250, 250)

    w.show()

    # wait to exit
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

1.1.3. Use classes for design

Codes are more manageable with classes. The above code can be rewritten as below.

# qt5_ex.py

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLabel

class MainPage(QWidget):
    def __init__(self, title=" "):
        super().__init__()  # inherit init of QWidget
        self.title = title
        self.left = 250
        self.top = 250
        self.width = 200
        self.height = 150
        self.widget()

    def widget(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)
        label1 = QLabel("Hello World", self)
        label1.move(75, 75)

        self.show()

def main():
    app = QApplication(sys.argv)
    w = MainPage(title="PyQt5")
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

1.2. Widgets

In this section, we will learn to add various widgets which are available in PyQt5.

1.2.1. Label

# qt5_ex.py

import sys
from PyQt5.QtWidgets import (
        QApplication, QWidget, QLabel
    )
from PyQt5.QtCore import QRect

class MainPage(QWidget):
    def __init__(self, title=" "):
        super().__init__()  # inherit init of QWidget
        self.title = title
        self.left = 250
        self.top = 250
        self.width = 200
        self.height = 150
        self.widget()

    def widget(self):
        # window setup
        self.setWindowTitle(self.title)
        # self.setGeometry(self.left, self.top, self.width, self.height)
        ## use above line or below
        self.resize(self.width, self.height)
        self.move(self.left, self.top)

        # add label
        self.label1 = QLabel(self, text="Hello World!\nWelcome to PyQt5 Tutorial")
        # margin: left, top; width, height
        self.label1.setGeometry(QRect(50, 5, 100, 50))
        self.label1.setWordWrap(True) # allow word-wrap

        self.show()


def main():
    app = QApplication(sys.argv)
    w = MainPage(title="PyQt5")
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

1.2.2. Push button

  • In the below code, the label will be changed after pressing the ‘submit’ button.
# qt5_ex.py

import sys
from PyQt5.QtWidgets import (
        QApplication, QWidget, QLabel, QPushButton
    )
from PyQt5.QtCore import pyqtSlot, QRect, QCoreApplication

class MainPage(QWidget):
    def __init__(self, title=" "):
        super().__init__()  # inherit init of QWidget
        self.title = title
        self.left = 250
        self.top = 250
        self.width = 200
        self.height = 150
        self.widget()

    def widget(self):
        # window setup
        self.setWindowTitle(self.title)
        # self.setGeometry(self.left, self.top, self.width, self.height)
        ## use above line or below
        self.resize(self.width, self.height)
        self.move(self.left, self.top)

        # add label
        self.label1 = QLabel(self, text="Hello World!\nWelcome to PyQt5 Tutorial")
        # margin: left, top; width, height
        self.label1.setGeometry(QRect(50, 5, 100, 50))
        self.label1.setWordWrap(True) # allow word-wrap

        # add button
        self.btn1 = QPushButton(self, text="Submit")
        self.btn1.setToolTip("Change value of label")
        self.btn1.move(5, 95)
        self.btn1.clicked.connect(self.change_label)

        self.btn2 = QPushButton(self, text="Close")
        self.btn2.setToolTip("Exit window")
        self.btn2.move(95, 95)
        self.btn2.clicked.connect(self.exit_window)

        self.show()

    @pyqtSlot()
    def change_label(self):
        self.label1.setText("Submit button is pressed ")

    @pyqtSlot()
    def exit_window(self):
        QCoreApplication.instance().quit()

def main():
    app = QApplication(sys.argv)
    w = MainPage(title="PyQt5")
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

1.2.3. Frame and Group box

We can create different frames and then arrange items inside it as below. Note that the location items inside the frame are relative to location of frame.

Note

  • To create a set of radio buttons or checkboxes, we need to define the radio buttons inside the Frame or groupBox.
  • Replace ‘QFrame’ with ‘QGroupBox’ to create a groupbox.
# qt5_ex.py

import sys
from PyQt5.QtWidgets import (
        QApplication, QWidget, QLabel, QPushButton, QCheckBox, QFrame
    )
from PyQt5.QtCore import pyqtSlot, QRect

class MainPage(QWidget):
    def __init__(self, title=" "):
        super().__init__()  # inherit init of QWidget
        self.title = title
        self.left = 250
        self.top = 250
        self.width = 400
        self.height = 300
        self.widget()

    def widget(self):
        # window setup
        self.setWindowTitle(self.title)
        # self.setGeometry(self.left, self.top, self.width, self.height)
        ## use above line or below
        self.resize(self.width, self.height)
        self.move(self.left, self.top)

        # create frame for a set of checkbox
        self.frame1 = QFrame(self)
        self.frame1.setGeometry(QRect(40, 40, 250, 80))
        # push button to display output on label
        self.btn1 = QPushButton(self.frame1, text="Submit")
        # location of btn relative to frame2 i.e. (40+0, 40+20)
        self.btn1.move(0, 50)
        self.btn1.clicked.connect(self.btn1_click)
        # selected value will be displayed on label
        self.label1 = QLabel(self.frame1)
        self.label1.setGeometry(QRect(0, 20, 500, 20))


        # create frame for a set of checkbox
        self.frame2 = QFrame(self)
        self.frame2.setGeometry(QRect(40, 150, 250, 80))
        # push button to display output on label
        self.btn2 = QPushButton(self.frame2, text="Submit")
        self.btn2.move(0, 50) # location of btn relative to frame2
        self.btn2.clicked.connect(self.btn2_click)
        # selected value will be displayed on label
        self.label2 = QLabel(self.frame2)
        self.label2.setGeometry(QRect(0, 20, 500, 20))

        self.show()

    @pyqtSlot()
    def btn1_click(self):
        self.label1.setText("Button is pressed in Frame 1")

    @pyqtSlot()
    def btn2_click(self):
        self.label2.setText("Button is pressed in Frame 2")


def main():
    app = QApplication(sys.argv)
    w = MainPage(title="PyQt5")
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

1.2.4. Radio button

  • In the below code, the value of selected ‘radio-button’ will be shown on Lable (after pressing the submit button)
# qt5_ex.py

import sys
from PyQt5.QtWidgets import (
        QApplication, QWidget, QLabel, QPushButton, QRadioButton, QFrame
    )
from PyQt5.QtCore import pyqtSlot, QRect

class MainPage(QWidget):
    def __init__(self, title=" "):
        super().__init__()  # inherit init of QWidget
        self.title = title
        self.left = 250
        self.top = 250
        self.width = 400
        self.height = 300
        self.widget()

    def widget(self):
        # window setup
        self.setWindowTitle(self.title)
        # self.setGeometry(self.left, self.top, self.width, self.height)
        ## use above line or below
        self.resize(self.width, self.height)
        self.move(self.left, self.top)

        # create frame for a set of radio button
        self.frame1 = QFrame(self)
        self.frame1.move(40, 40)

        self.radioBtn1 = QRadioButton("Yes", self.frame1)
        self.radioBtn1.setChecked(True)  # select by default
        self.radioBtn1.move(0, 0)
        self.radioBtn2 = QRadioButton("No", self.frame1)
        self.radioBtn2.move(0, 20)

        # push button to display output on label
        self.btn1 = QPushButton(self.frame1, text="Submit")
        self.btn1.move(60, 20)
        self.btn1.clicked.connect(self.btn1_click)

        # selected value will be displayed on label
        self.label1 = QLabel(self.frame1)
        self.label1.setGeometry(QRect(60, 0, 100, 20))
        # self.label1.move(60, 0)


        # create another frame for other set of radio button
        self.frame2 = QFrame(self)
        self.frame2.move(40, 100)
        self.radioBtn3 = QRadioButton("College", self.frame2)
        self.radioBtn3.move(0, 0)
        self.radioBtn4 = QRadioButton("School", self.frame2)
        self.radioBtn4.move(0, 20)

        self.show()

    @pyqtSlot()
    def btn1_click(self):
        if self.radioBtn1.isChecked():
            self.label1.setText("You pressed Yes")
        elif self.radioBtn2.isChecked():
            self.label1.setText("You pressed No")
        else:
            self.label1.setText("Choose Yes or No")



def main():
    app = QApplication(sys.argv)
    w = MainPage(title="PyQt5")
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

1.2.5. Checkbox

# qt5_ex.py

import sys
from PyQt5.QtWidgets import (
        QApplication, QWidget, QLabel, QPushButton, QCheckBox, QFrame
    )
from PyQt5.QtCore import pyqtSlot, QRect

class MainPage(QWidget):
    def __init__(self, title=" "):
        super().__init__()  # inherit init of QWidget
        self.title = title
        self.left = 250
        self.top = 250
        self.width = 400
        self.height = 300
        self.widget()

    def widget(self):
        # window setup
        self.setWindowTitle(self.title)
        # self.setGeometry(self.left, self.top, self.width, self.height)
        ## use above line or below
        self.resize(self.width, self.height)
        self.move(self.left, self.top)

        # create frame for a set of checkbox
        self.frame1 = QFrame(self)
        self.frame1.move(40, 40)

        self.checkbox1 = QCheckBox("C++", self.frame1)
        self.checkbox1.setChecked(True)  # select by default
        self.checkbox1.move(0, 0)
        self.checkbox2 = QCheckBox("Python", self.frame1)
        self.checkbox2.move(0, 20)

        # push button to display output on label
        self.btn1 = QPushButton(self.frame1, text="Submit")
        self.btn1.move(70, 20)
        self.btn1.clicked.connect(self.btn1_click)

        # selected value will be displayed on label
        self.label1 = QLabel(self.frame1)
        self.label1.setGeometry(QRect(60, 0, 500, 20))
        # self.label1.move(60, 0)


        # create another frame for other set of checkbox
        self.frame2 = QFrame(self)
        self.frame2.move(40, 100)
        self.checkbox3 = QCheckBox("College", self.frame2)
        self.checkbox3.move(0, 0)
        self.checkbox4 = QCheckBox("School", self.frame2)
        self.checkbox4.move(0, 20)

        self.show()

    @pyqtSlot()
    def btn1_click(self):
        selected_val = []
        if self.checkbox1.isChecked():
            selected_val.append(self.checkbox1.text())
        if self.checkbox2.isChecked():
            selected_val.append(self.checkbox2.text())

        val = "Preferred Languages: "
        for i in selected_val:
            val = val + i + ", "
        self.label1.setText(val)


def main():
    app = QApplication(sys.argv)
    w = MainPage(title="PyQt5")
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

1.2.6. Spin box

# qt5_ex.py

import sys
from PyQt5.QtWidgets import (
        QApplication, QWidget, QLabel, QPushButton, QSpinBox, QFrame
    )
from PyQt5.QtCore import pyqtSlot, QRect

class MainPage(QWidget):
    def __init__(self, title=" "):
        super().__init__()  # inherit init of QWidget
        self.title = title
        self.left = 250
        self.top = 250
        self.width = 400
        self.height = 300
        self.widget()

    def widget(self):
        # window setup
        self.setWindowTitle(self.title)
        # self.setGeometry(self.left, self.top, self.width, self.height)
        ## use above line or below
        self.resize(self.width, self.height)
        self.move(self.left, self.top)

        # create frame for a set of checkbox
        self.frame1 = QFrame(self)
        self.frame1.setGeometry(QRect(40, 40, 250, 80))
        # create spin box
        self.spinbox1 = QSpinBox(self.frame1)
        self.spinbox1.setValue(3) # default value
        self.spinbox1.setMinimum(0) # minimum value
        self.spinbox1.setMaximum(6) # maximum value
        self.spinbox1.move(0, 50)
        self.spinbox1.valueChanged.connect(self.spinbox1_changed)
        # spinbox value will be displayed on label
        self.label1 = QLabel(self.frame1, text="Value in spin box is " + str(self.spinbox1.value()))
        self.label1.setGeometry(QRect(0, 20, 500, 20))


        self.show()

    @pyqtSlot()
    def spinbox1_changed(self):
        self.label1.setText("Value in spin box is "+str(self.spinbox1.value()))


def main():
    app = QApplication(sys.argv)
    w = MainPage(title="PyQt5")
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

1.2.7. Slider

# qt5_ex.py

import sys
from PyQt5.QtWidgets import (
        QApplication, QWidget, QLabel, QPushButton, QSlider, QFrame
    )
from PyQt5.QtCore import pyqtSlot, QRect, Qt

class MainPage(QWidget):
    def __init__(self, title=" "):
        super().__init__()  # inherit init of QWidget
        self.title = title
        self.left = 250
        self.top = 250
        self.width = 400
        self.height = 300
        self.widget()

    def widget(self):
        # window setup
        self.setWindowTitle(self.title)
        # self.setGeometry(self.left, self.top, self.width, self.height)
        ## use above line or below
        self.resize(self.width, self.height)
        self.move(self.left, self.top)

        # create frame for a set of checkbox
        self.frame1 = QFrame(self)
        self.frame1.setGeometry(QRect(40, 40, 250, 180))
        # create spin box
        self.slider1 = QSlider(self.frame1)
        self.slider1.setOrientation(Qt.Horizontal) # Horizontal / Vertical
        self.slider1.setTickInterval(1)
        self.slider1.setTickPosition(QSlider.TicksBelow)
        self.slider1.setTickInterval(2)
        self.slider1.setValue(3) # default value
        self.slider1.setMinimum(0) # minimum value
        self.slider1.setMaximum(6) # maximum value
        self.slider1.move(0, 50)
        self.slider1.valueChanged.connect(self.slider1_changed)
        # slider value will be displayed on label
        self.label1 = QLabel(self.frame1, text="Slider is at " + str(self.slider1.value()))
        self.label1.setGeometry(QRect(0, 20, 500, 20))


        self.show()

    @pyqtSlot()
    def slider1_changed(self):
        self.label1.setText("Slider is at "+str(self.slider1.value()))


def main():
    app = QApplication(sys.argv)
    w = MainPage(title="PyQt5")
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

1.2.8. Line edit box

Single line can be written in Line edit box

# qt5_ex.py

import sys
from PyQt5.QtWidgets import (
        QApplication, QWidget, QLabel, QPushButton, QLineEdit, QFrame
    )
from PyQt5.QtCore import pyqtSlot, QRect, Qt

class MainPage(QWidget):
    def __init__(self, title=" "):
        super().__init__()  # inherit init of QWidget
        self.title = title
        self.left = 250
        self.top = 250
        self.width = 400
        self.height = 300
        self.widget()

    def widget(self):
        # window setup
        self.setWindowTitle(self.title)
        # self.setGeometry(self.left, self.top, self.width, self.height)
        ## use above line or below
        self.resize(self.width, self.height)
        self.move(self.left, self.top)

        # create frame for a set of checkbox
        self.frame1 = QFrame(self)
        self.frame1.setGeometry(QRect(40, 40, 250, 180))
        # create line edit box
        self.line_edit1 = QLineEdit(self.frame1)
        self.line_edit1.move(0, 0)
        self.line_edit1.textChanged.connect(self.line_edit1_changed)
        # line_edit value will be displayed on label
        self.label1 = QLabel(self.frame1)
        self.label1.setGeometry(QRect(0, 20, 500, 20))

        # Password field
        self.line_edit2 = QLineEdit(self.frame1)
        self.line_edit2.move(0, 50)
        self.line_edit2.setEchoMode(QLineEdit.Password)


        self.show()

    @pyqtSlot()
    def line_edit1_changed(self):
        self.label1.setText("Text in Line edit: "+str(self.line_edit1.text()))


def main():
    app = QApplication(sys.argv)
    w = MainPage(title="PyQt5")
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

1.2.9. Text edit box

Multiple lines can be written in ‘text edit box’

# qt5_ex.py

import sys
from PyQt5.QtWidgets import (
        QApplication, QWidget, QLabel, QPushButton, QTextEdit, QFrame
    )
from PyQt5.QtCore import pyqtSlot, QRect, Qt

class MainPage(QWidget):
    def __init__(self, title=" "):
        super().__init__()  # inherit init of QWidget
        self.title = title
        self.left = 250
        self.top = 250
        self.width = 400
        self.height = 300
        self.widget()

    def widget(self):
        # window setup
        self.setWindowTitle(self.title)
        # self.setGeometry(self.left, self.top, self.width, self.height)
        ## use above line or below
        self.resize(self.width, self.height)
        self.move(self.left, self.top)

        # create frame for a set of checkbox
        self.frame1 = QFrame(self)
        self.frame1.setGeometry(QRect(40, 40, 250, 180))
        # create text edit box
        self.text_edit1 = QTextEdit(self.frame1)
        self.text_edit1.move(0, 0)


        self.show()


def main():
    app = QApplication(sys.argv)
    w = MainPage(title="PyQt5")
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

1.2.10. Combobox

# qt5_ex.py

import sys
from PyQt5.QtWidgets import (
        QApplication, QWidget, QLabel, QPushButton, QComboBox, QFrame
    )
from PyQt5.QtCore import pyqtSlot, QRect, Qt

class MainPage(QWidget):
    def __init__(self, title=" "):
        super().__init__()  # inherit init of QWidget
        self.title = title
        self.left = 250
        self.top = 250
        self.width = 400
        self.height = 300
        self.widget()

    def widget(self):
        # window setup
        self.setWindowTitle(self.title)
        # self.setGeometry(self.left, self.top, self.width, self.height)
        ## use above line or below
        self.resize(self.width, self.height)
        self.move(self.left, self.top)

        # create frame for a set of checkbox
        self.frame1 = QFrame(self)
        self.frame1.setGeometry(QRect(40, 40, 250, 180))
        # create text edit box
        self.combo1 = QComboBox(self.frame1)
        self.combo1.move(0, 0)
        self.combo1.addItem("Python")
        self.combo1.addItems(["C", "C++", "VHDL", "Verilog"])

        self.show()


def main():
    app = QApplication(sys.argv)
    w = MainPage(title="PyQt5")
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

1.4. Qt designer

We can design the GUI using Qt-designer and then add functionality as shown in this section,

1.4.1. Installation

  • Install qt5

    (install qt5, if required)
    sudo apt-fast install qt5-default
    

Install any one of two,

  • qt4-designer is a part of IDE which creates only Form.
  • qtcreator is complete IDE.
sudo apt-fast install qt4-designer
(run below to start qt4-designer)
designer

or

sudo apt-fast install qtcreator
(run below to start qtcreator)
qtcreator

1.4.2. Create design

First create design mainwindow.ui using Qt-designer or qt-creator as shown in Fig. 1.1,

../_images/qtcreator.png

Fig. 1.1 Design using qtcreator

1.4.3. Convert code into python

The design file is saved as ‘mainwindow.ui’ file

pyuic5 -x mainwindow.ui -o qtdesign.py

Below is the code generated by above command,

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

# Form implementation generated from reading ui file 'mainwindow.ui'
#
# Created by: PyQt5 UI code generator 5.6
#
# 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.resize(400, 300)
        self.centralWidget = QtWidgets.QWidget(MainWindow)
        self.centralWidget.setObjectName("centralWidget")
        self.groupBox = QtWidgets.QGroupBox(self.centralWidget)
        self.groupBox.setGeometry(QtCore.QRect(20, 90, 251, 141))
        self.groupBox.setObjectName("groupBox")
        self.radioButton = QtWidgets.QRadioButton(self.groupBox)
        self.radioButton.setGeometry(QtCore.QRect(10, 60, 100, 20))
        self.radioButton.setObjectName("radioButton")
        self.radioButton_2 = QtWidgets.QRadioButton(self.groupBox)
        self.radioButton_2.setGeometry(QtCore.QRect(10, 80, 100, 20))
        self.radioButton_2.setObjectName("radioButton_2")
        self.radioButton_3 = QtWidgets.QRadioButton(self.groupBox)
        self.radioButton_3.setGeometry(QtCore.QRect(10, 100, 100, 20))
        self.radioButton_3.setObjectName("radioButton_3")
        self.pushButton = QtWidgets.QPushButton(self.groupBox)
        self.pushButton.setGeometry(QtCore.QRect(120, 100, 80, 22))
        self.pushButton.setObjectName("pushButton")
        self.checkBox = QtWidgets.QCheckBox(self.groupBox)
        self.checkBox.setGeometry(QtCore.QRect(10, 30, 85, 20))
        self.checkBox.setObjectName("checkBox")
        self.checkBox_2 = QtWidgets.QCheckBox(self.groupBox)
        self.checkBox_2.setGeometry(QtCore.QRect(120, 30, 85, 20))
        self.checkBox_2.setObjectName("checkBox_2")
        self.label = QtWidgets.QLabel(self.centralWidget)
        self.label.setGeometry(QtCore.QRect(50, 30, 241, 16))
        self.label.setObjectName("label")
        MainWindow.setCentralWidget(self.centralWidget)
        self.menuBar = QtWidgets.QMenuBar(MainWindow)
        self.menuBar.setGeometry(QtCore.QRect(0, 0, 400, 19))
        self.menuBar.setObjectName("menuBar")
        MainWindow.setMenuBar(self.menuBar)
        self.mainToolBar = QtWidgets.QToolBar(MainWindow)
        self.mainToolBar.setObjectName("mainToolBar")
        MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.mainToolBar)
        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", "MainWindow"))
        self.groupBox.setTitle(_translate("MainWindow", "GroupBox"))
        self.radioButton.setText(_translate("MainWindow", "Good"))
        self.radioButton_2.setText(_translate("MainWindow", "Bad"))
        self.radioButton_3.setText(_translate("MainWindow", "OK"))
        self.pushButton.setText(_translate("MainWindow", "Submit"))
        self.checkBox.setText(_translate("MainWindow", "Yes"))
        self.checkBox_2.setText(_translate("MainWindow", "No"))
        self.label.setText(_translate("MainWindow", "TextLabel"))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

Now, we can excute the python file as below, which will open the design as shown in Fig. 1.2

(run file)
python qtdesign.py
../_images/qtcreator2.png

Fig. 1.2 GUI after conversion

1.4.4. Add functionality to design

It is better to create a new file and import ‘qtdesign.py’ file to it as shown below,

Note

Since we did not modify the qtdesign.py file, therefore we can add more widgets to ‘mainwindow.ui’ without modifying the code in ‘myactions.py’ (as long as the name of the widgets are not changed).

# myactions.py

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import pyqtSlot, QRect

from qtdesign import Ui_MainWindow


class MyActions(Ui_MainWindow):
    def __init__(self, title=" "):
        self.title = title
        self.left = 250
        self.top = 250
        self.width = 200
        self.height = 150

    # update setupUi
    def setupUi(self, MainWindow):
        super().setupUi(MainWindow)
        # MainWindow.resize(400, 300) # do not modify it
        MainWindow.move(self.left, self.top)  # set location for window
        MainWindow.setWindowTitle(self.title) # change title

        self.myactions() # add actions for different buttons

    # define actions here
    def myactions(self):
        self.pushButton.clicked.connect(self.change_label)


    @pyqtSlot()
    def change_label(self):
        self.label.setText("Submit button is pressed ")

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = MyActions("PyQt5")
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())
../_images/qtcreator3.png

Fig. 1.3 Perform action on ‘submit’

1.5. Database

Note

See MySQL with python guide for more MySQL commands.

1.5.1. Connect to Database

# qt5_ex.py

import sys
from PyQt5.QtWidgets import (
        QApplication, QWidget, QLabel, QPushButton, QComboBox, QFrame, QMainWindow,
        QMessageBox

    )
from PyQt5.QtCore import pyqtSlot, QRect, Qt

import MySQLdb as mq

class MainPage(QMainWindow):
    def __init__(self, title=" "):
        super().__init__()  # inherit init of QWidget
        self.title = title
        self.left = 250
        self.top = 250
        self.width = 400
        self.height = 300
        self.widget()

    def widget(self):
        # window setup
        self.setWindowTitle(self.title)
        # self.setGeometry(self.left, self.top, self.width, self.height)
        ## use above line or below
        # self.resize(self.width, self.height) # resizable
        self.setFixedSize(self.width, self.height)  # fixed size
        self.move(self.left, self.top)

        # create frame for a set of checkbox
        self.frame1 = QFrame(self)
        self.frame1.setGeometry(QRect(40, 40, 250, 80))

        self.btn1 = QPushButton(self.frame1, text="Connect")
        self.btn1.move(50, 50)
        self.btn1.clicked.connect(self.connect_db)

        self.show()

    def connect_db(self):
        try:
            conn = mq.connect(host='localhost', user='root', password='root', db='qtdb')
            print("Connected")
        except mq.Error as err:
            print(err)
        else:
            print("Connection closed")
            conn.close()

def main():
    app = QApplication(sys.argv)
    w = MainPage(title="PyQt5")
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

1.5.2. Create table and insert data

# qt5_ex.py

import sys
from PyQt5.QtWidgets import (
        QApplication, QWidget, QLabel, QPushButton, QComboBox, QFrame, QMainWindow,
        QMessageBox, QLineEdit

    )
from PyQt5.QtCore import pyqtSlot, QRect, Qt

import MySQLdb as mq

class MainPage(QMainWindow):
    def __init__(self, title=" "):
        super().__init__()  # inherit init of QWidget
        self.title = title
        self.left = 250
        self.top = 50
        self.width = 400
        self.height = 250
        self.widget()

    def widget(self):
        # window setup
        self.setWindowTitle(self.title)
        # self.setGeometry(self.left, self.top, self.width, self.height)
        ## use above line or below
        # self.resize(self.width, self.height) # resizable
        self.setFixedSize(self.width, self.height)  # fixed size
        self.move(self.left, self.top)

        # create frame for a set of checkbox
        self.frame1 = QFrame(self)
        self.frame1.setGeometry(QRect(40, 40, 250, 250))

        # create table
        self.tbl_name = QLineEdit(self.frame1)
        self.tbl_name.setPlaceholderText("Table name")
        self.tbl_name.setGeometry(0, 0, 100, 30)

        self.btn1 = QPushButton(self.frame1, text="Create Table")
        self.btn1.move(0, 50)
        self.btn1.clicked.connect(self.create_table)

        # insert data
        self.tbl_name2 = QLineEdit(self.frame1)
        self.tbl_name2.setPlaceholderText("Table name")
        self.tbl_name2.setGeometry(150, 0, 100, 30)

        self.name = QLineEdit(self.frame1)
        self.name.setPlaceholderText("Name")
        self.name.setGeometry(150, 50, 100, 30)

        self.age = QLineEdit(self.frame1)
        self.age.setPlaceholderText("Age")
        self.age.setGeometry(150, 100, 100, 30)

        self.btn2 = QPushButton(self.frame1, text="Insert")
        self.btn2.move(150, 150)
        self.btn2.clicked.connect(self.insert_data)


        self.show()

    def connect_db(self):
        try:
            self.conn = mq.connect(host='localhost', user='root', password='root', db='qtdb')
            self.cursor = self.conn.cursor()
            print("Connected")
        except mq.Error as err:
            print(err)

    def disconnect_db(self):
        """ commit changes to database and close connection """
        self.conn.commit()
        self.cursor.close()
        self.conn.close()
        print("Disconnected")

    def insert_data(self):
        self.connect_db()
        self.cursor.execute("INSERT INTO %s (name, age) VALUES ('%s',%s)" % (
            self.tbl_name2.text(),
            self.name.text(),
            self.age.text()
            )
        )
        self.disconnect_db()
        QMessageBox.about(self, "Insert", "Data inserted successfully")

    def create_table(self):
        """ Create table in the database """

        self.connect_db()
        # optional: drop table if exists
        self.cursor.execute('DROP TABLE IF EXISTS %s' % self.tbl_name.text())
        self.cursor.execute('CREATE TABLE %s \
                (                   \
                  id    INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, \
                  name  VARCHAR(30) NOT NULL,  \
                  age   int \
                )' % self.tbl_name.text()
        )
        print("Table created")
        QMessageBox.about(self, "Create", "Table created successfully")
        self.disconnect_db()

def main():
    app = QApplication(sys.argv)
    w = MainPage(title="PyQt5")
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

1.5.3. View data

# qt5_ex.py

import sys
from PyQt5.QtWidgets import (
        QApplication, QWidget, QLabel, QPushButton, QComboBox, QFrame, QMainWindow,
        QMessageBox, QLineEdit, QTextEdit

    )
from PyQt5.QtCore import pyqtSlot, QRect, Qt
from PyQt5.QtGui import QTextCursor

import MySQLdb as mq

class MainPage(QMainWindow):
    def __init__(self, title=" "):
        super().__init__()  # inherit init of QWidget
        self.title = title
        self.left = 250
        self.top = 50
        self.width = 600
        self.height = 250
        self.widget()

    def widget(self):
        # window setup
        self.setWindowTitle(self.title)
        # self.setGeometry(self.left, self.top, self.width, self.height)
        ## use above line or below
        # self.resize(self.width, self.height) # resizable
        self.setFixedSize(self.width, self.height)  # fixed size
        self.move(self.left, self.top)

        # create frame for a set of checkbox
        self.frame1 = QFrame(self)
        self.frame1.setGeometry(QRect(40, 40, 250, 250))

        # create table
        self.tbl_name = QLineEdit(self.frame1)
        self.tbl_name.setPlaceholderText("Table name")
        self.tbl_name.setGeometry(0, 0, 100, 30)

        self.btn1 = QPushButton(self.frame1, text="Create Table")
        self.btn1.move(0, 50)
        self.btn1.clicked.connect(self.create_table)

        # insert data
        self.tbl_name2 = QLineEdit(self.frame1)
        self.tbl_name2.setPlaceholderText("Table name")
        self.tbl_name2.setGeometry(150, 0, 100, 30)

        self.name = QLineEdit(self.frame1)
        self.name.setPlaceholderText("Name")
        self.name.setGeometry(150, 50, 100, 30)

        self.age = QLineEdit(self.frame1)
        self.age.setPlaceholderText("Age")
        self.age.setGeometry(150, 100, 100, 30)

        self.btn2 = QPushButton(self.frame1, text="Insert")
        self.btn2.move(150, 150)
        self.btn2.clicked.connect(self.insert_data)


        self.frame2 = QFrame(self)
        self.frame2.setGeometry(QRect(350, 40, 250, 250))
        # show data
        self.txtbox1 = QTextEdit(self.frame2)
        self.txtbox1.setGeometry(0, 0, 200, 140)

        self.tbl_name3 = QLineEdit(self.frame2)
        self.tbl_name3.setText("writer")
        self.tbl_name3.setGeometry(0, 150, 100, 25)

        self.btn4 = QPushButton(self.frame2, text="Show data")
        self.btn4.move(110, 150)
        self.btn4.clicked.connect(self.show_data)
        self.show()

    def connect_db(self):
        try:
            self.conn = mq.connect(host='localhost', user='root', password='root', db='qtdb')
            self.cursor = self.conn.cursor()
            print("Connected")
        except mq.Error as err:
            print(err)

    def disconnect_db(self):
        """ commit changes to database and close connection """
        self.conn.commit()
        self.cursor.close()
        self.conn.close()
        print("Disconnected")

    def insert_data(self):
        self.connect_db()
        self.cursor.execute("INSERT INTO %s (name, age) VALUES ('%s',%s)" % (
            self.tbl_name2.text(),
            self.name.text(),
            self.age.text()
            )
        )
        self.disconnect_db()
        QMessageBox.about(self, "Insert", "Data inserted successfully")

    def create_table(self):
        """ Create table in the database """

        self.connect_db()
        # optional: drop table if exists
        self.cursor.execute('DROP TABLE IF EXISTS %s' % self.tbl_name.text())
        self.cursor.execute('CREATE TABLE %s \
                (                   \
                  id    INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, \
                  name  VARCHAR(30) NOT NULL,  \
                  age   int \
                )' % self.tbl_name.text()
        )
        print("Table created")
        QMessageBox.about(self, "Create", "Table created successfully")
        self.disconnect_db()

    def show_data(self):
        self.connect_db()
        self.cursor.execute("SELECT * FROM %s" % self.tbl_name3.text())
        data = self.cursor.fetchall()
        self.disconnect_db()

        self.txtcursor = QTextCursor(self.txtbox1.document())
        text = "{0:<2s} {1:<10s} {2:<3s}".format("Id", "Name", "Age")
        self.txtcursor.insertText(text + "\n")
        for d in data:
            text = "{0:<2d} {1:<10s} {2:<3d}".format(d[0], d[1], d[2])
            self.txtcursor.insertText(text + "\n")
            print(text)


def main():
    app = QApplication(sys.argv)
    w = MainPage(title="PyQt5")
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()