6626070
2997924

PL03-Topic02, PyQt, Qt Designer

Back to the previous pageAPI for pythonAPI for C++page managementNotepad LectureCalculator Lecture
List of posts to read before reading this article


Contents


Installation

For windows

$ pip install pyqt5-tools
path = C:\Users\%USERNAME%\AppData\Local\Programs\Python\Python37\Lib\site-packages\pyqt5_tools\designer.exe





Convert ui-file to py-file

tutorial

$ pyuic5 [ui_file.ui] -o [python_file.py]

main.py

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow
import sys
import python_file

class MyApp(QMainWindow, python_file.Ui_MainWindow):
    def __init__(self, parent=None):
        super(MyApp, self).__init__(parent)
        self.setupUi(self)

def main():
    app = QApplication(sys.argv)
    form = MyApp()
    form.show()
    app.exec_()

if __name__ == '__main__':
    main()
$ pyinstaller main.py 





Execute the ui-file by python

ctrl + r : form-preview on Qt-designer

load MainWindow from qtdesigner

basic form without qtdesigner

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow

app = QApplication(sys.argv)
mainwindow = QMainWindow()
mainwindow.show()
app.exec_()




basic form with qtdesigner

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5 import uic

app = QApplication(sys.argv)
mainwindow = QMainWindow()
mainwindow = uic.loadUi("mainwindow.ui")
mainwindow.show()
app.exec()
FILE PATH

그림1

when there exist the ui-file in parent folder,

mainwindow = uic.loadUi("../test.ui")

when there exist the ui-file in same folder,

mainwindow = uic.loadUi("test.ui")

when there exist the ui-file in sub-folder,

mainwindow = uic.loadUi("sub-folder/test.ui")





advanced form with qtdesigner

import sys
from PyQt5.QtWidgets import *
from PyQt5 import uic

form_class = uic.loadUiType("mainwindow.ui")[0]
class WindowClass(QMainWindow, form_class):
    def __init__(self):
        super().__init__()
        self.setupUi(self)

app = QApplication(sys.argv)
mainwindow = WindowClass()
mainwindow.show()
app.exec_()




load Dialog from qtdesigner

basic form without qtdesigner

import sys
from PyQt5.QtWidgets import QApplication, QDialog

app = QApplication(sys.argv)
maindialog = QDialog()
maindialog.show()
app.exec_()




basic form with qtdesigner

import sys
from PyQt5.QtWidgets import QApplication, QDialog
from PyQt5 import uic

app = QApplication(sys.argv)
maindialog = QDialog()
uic.loadUi('dialog.ui',maindialog)
maindialog.show()
app.exec_()




advanced form with qtdesigner

import sys
from PyQt5.QtWidgets import *
from PyQt5 import uic

class MainDialog(QDialog):
    def __init__(self):
        super().__init__()
        uic.loadUi('dialog.ui', self)

app = QApplication(sys.argv)
maindialog = MainDialog()
maindialog.show()
app.exec_()





Qt-designer API

Layouts

(m) |(m) |



Spacers

(m) |(m) |



Buttons

QPushButton(m) |QToolButton(m) |QRadioButton(m) |QCheckBox(m) |QCommandLinkButton(m) |QDialogButtonBox(m) |



item views(model-based)

(m) |(m) |



item widgets(item-based)

(m) |(m) |



containers

(m) |(m) |



Input widgets

QComboBox(m) |QFontComboBox(m) |QLineEdit(m) |QTextEdit(m) |QPlainTextEdit(m) |QSpinBox(m) |QDoubleSpinBox(m) |QTimeEdit(m) |QDateEdit(m) |QDateTimeEdit(m) |QDial(m) |QAbstractScrollArea(m) |QScrollBar(m) |QAbstractSlider(m) |QSlider(m) |QKeySequenceEdit(m) |

QPlainTextEdit is an advanced viewer/editor supporting plain text than QTextEdit.



Display widgets

QLabel(m) |QTextBrowser(m) |QGraphicsView(m) |QCalendarWidget(m) |QLCDNumber(m) |QProgressBar(m) |QLine(m) |QOpenGLWidget(m) |QQuickWidget(m) |QWebEngineView(m)|



Notepad

(1) Hello

image

Code

import sys
from PyQt5.QtWidgets import *
from PyQt5 import uic

form_class = uic.loadUiType("notepad.ui")[0]
class WindowClass(QMainWindow, form_class):
    def __init__(self):
        super().__init__()
        self.setupUi(self)

app = QApplication(sys.argv)
mainWindow = WindowClass()
mainWindow.show()
app.exec_()
API





(2) Layout

image Code

import sys
from PyQt5.QtWidgets import *
from PyQt5 import uic

form_class = uic.loadUiType("notepad.ui")[0]
class WindowClass(QMainWindow, form_class):
    def __init__(self):
        super().__init__()
        self.setupUi(self)

app = QApplication(sys.argv)
mainWindow = WindowClass()
mainWindow.show()
app.exec_()
API





(3) Menubar

image

Code

import sys
from PyQt5.QtWidgets import *
from PyQt5 import uic

form_class = uic.loadUiType("notepad.ui")[0]
class WindowClass(QMainWindow, form_class):
    def __init__(self):
        super().__init__()
        self.setupUi(self)

        self.action_open.triggered.connect(self.openFunction)
        self.action_save.triggered.connect(self.saveFunction)

    def openFunction(self):
        print("open")

    def saveFunction(self):
        print("save")

app = QApplication(sys.argv)
mainWindow = WindowClass()
mainWindow.show()
app.exec_()
API

SUPPLEMENT

image






(4) Open/SaveAs

image

Code

import sys
from PyQt5.QtWidgets import *
from PyQt5 import uic

form_class = uic.loadUiType("notepad.ui")[0]
class WindowClass(QMainWindow, form_class):
    def __init__(self):
        super().__init__()
        self.setupUi(self)

        self.action_open.triggered.connect(self.openFunction)
        self.action_saveas.triggered.connect(self.saveasFunction)

    def openFunction(self):
        fname = QFileDialog.getOpenFileName(self)
        if fname[0]:
            with open(fname[0], encoding='UTF8') as f:
                data = f.read()
            self.plainTextEdit.setPlainText(data)
            print("open, {}".format(fname[0]))

    def saveasFunction(self):
        fname = QFileDialog.getSaveFileName(self)
        if fname[0]:
            data = self.plainTextEdit.toPlainText()
            with open(fname[0], 'w', encoding='UTF8') as f:
                f.write(data)
            print("save, {}".format(fname[0]))

app = QApplication(sys.argv)
mainWindow = WindowClass()
mainWindow.show()
app.exec_()
API

SUPPLEMENT

image






(5) Open/SaveAs/Save

image

Code

import sys
from PyQt5.QtWidgets import *
from PyQt5 import uic

form_class = uic.loadUiType("notepad.ui")[0]
class WindowClass(QMainWindow, form_class):
    def __init__(self):
        super().__init__()
        self.setupUi(self)

        self.action_open.triggered.connect(self.openFunction)
        self.action_save.triggered.connect(self.saveFunction)
        self.action_saveas.triggered.connect(self.saveasFunction)

        self.opened = False
        self.opened_file_path = ''

    def openFunction(self):
        fname = QFileDialog.getOpenFileName(self)
        if fname[0]:
            with open(fname[0], encoding='UTF8') as f:
                data = f.read()
            self.plainTextEdit.setPlainText(data)
            self.opened = True
            self.opened_file_path = fname
            print("open, {}".format(fname))

    def saveasFunction(self):
        fname = QFileDialog.getSaveFileName(self)
        if fname[0]:
            data = self.plainTextEdit.toPlainText()
            with open(fname[0], 'w', encoding='UTF8') as f:
                f.write(data)
            self.opened = True
            self.opened_file_path = fname
            print("saveas, {}".format(fname))

    def saveFunction(self):
        if self.opened:
            fname = self.opened_file_path
            data = self.plainTextEdit.toPlainText()
            with open(fname[0], 'w', encoding='UTF8') as f:
                f.write(data)
            self.opened = True
            self.opened_file_path = fname
            print("save, {}".format(fname))
        else:
            self.saveasFunction()


app = QApplication(sys.argv)
mainWindow = WindowClass()
mainWindow.show()
app.exec_()
API





(6) CloseEvent with MessageBox

image

Code

import sys
from PyQt5.QtWidgets import *
from PyQt5 import uic

form_class = uic.loadUiType("notepad.ui")[0]
class WindowClass(QMainWindow, form_class):
    def __init__(self):
        super().__init__()
        self.setupUi(self)

        self.action_open.triggered.connect(self.openFunction)
        self.action_save.triggered.connect(self.saveFunction)
        self.action_saveas.triggered.connect(self.saveasFunction)
        self.action_close.triggered.connect(self.close)  # self.close is called with self.closeEvent

        self.opened = False
        self.opened_file_path = ''

    def openFunction(self):
        fname = QFileDialog.getOpenFileName(self)
        if fname[0]:
            with open(fname[0], encoding='UTF8') as f:
                data = f.read()
            self.plainTextEdit.setPlainText(data)
            self.opened = True
            self.opened_file_path = fname
            print("open, {}".format(fname))

    def saveasFunction(self):
        fname = QFileDialog.getSaveFileName(self)
        if fname[0]:
            data = self.plainTextEdit.toPlainText()
            with open(fname[0], 'w', encoding='UTF8') as f:
                f.write(data)
            self.opened = True
            self.opened_file_path = fname
            print("saveas, {}".format(fname))

    def saveFunction(self):
        if self.opened:
            fname = self.opened_file_path
            data = self.plainTextEdit.toPlainText()
            with open(fname[0], 'w', encoding='UTF8') as f:
                f.write(data)
            self.opened = True
            self.opened_file_path = fname
            print("save, {}".format(fname))
        else:
            self.saveasFunction()

    def closeEvent(self, event):
        current_data = ''
        def ischanged():
            nonlocal current_data
            if not self.opened:
                print('This file was not loaded')
                if self.plainTextEdit.toPlainText().strip():
                    return True
                return False

            current_data = self.plainTextEdit.toPlainText()
            with open(self.opened_file_path[0], encoding='UTF8') as f:
                file_data = f.read()
            if current_data == file_data:
                return False
            else:
                return True

        def save_changed_data():
            msgBox = QMessageBox()
            msgBox.setText('Do you want to changes to {}'.format(self.opened_file_path))
            msgBox.addButton('Save(S)', QMessageBox.YesRole) #0
            msgBox.addButton('Don\'t Save(N)', QMessageBox.NoRole) #1
            msgBox.addButton('Cancel', QMessageBox.RejectRole) #2
            ret = msgBox.exec_()
            if ret == 0:
                self.saveFunction()
                event.ignore()
            else:
                return ret

        if ischanged():
            ret = save_changed_data()
            if ret == 2:
                event.ignore()

app = QApplication(sys.argv)
mainWindow = WindowClass()
mainWindow.show()
app.exec_()
API





(8) PlainTextEdit

Code


API





(9) Find

Code


API





(10) KeyboardEvent

Code


API





(11) SetCursor

Code


API





(12) FindText

Code


API





(13) IgnoreFlag

Code


API





(14) Radiobutton

Code


API





(15) SearchDirection

Code


API





(16) reverseSearchDirection

Code


API





Calculator

(1) One-button signal





(2) Many-button signal





(3) Arithmetic operation





(4) with Matplotlib

image

import sys
from PyQt5.QtWidgets import *
from PyQt5 import uic

import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas

class MainDialog(QDialog):
    def __init__(self):
        super().__init__()

        fig = plt.figure()
        ax = fig.add_subplot(111)
        ax.plot([1,2,3,4],[3,2,4,1])

        canvas = FigureCanvas(fig)
        canvas.draw()

        lay = QHBoxLayout()
        self.setLayout(lay)
        lay.addWidget(canvas)
        canvas.show()

app = QApplication(sys.argv)
mainDialog = MainDialog()
mainDialog.show()
app.exec_()




appendix - Convert 1

ui file 캡처


python-code

from PyQt5 import QtWidgets, uic

def Convert():
    dlg.lineEdit_2.setText(str(float(dlg.lineEdit.text())*1.23))

app = QtWidgets.QApplication([])
dlg = uic.loadUi("test.ui")

dlg.pushButton.clicked.connect(Convert)

dlg.show()
app.exec()
OUTPUT

캡처






appendix - Convert 2

from PyQt5 import QtWidgets, uic

def Convert():
    dlg.lineEdit_2.setText(str(float(dlg.lineEdit.text())*1.23))

app = QtWidgets.QApplication([])
dlg = uic.loadUi("test.ui")

dlg.lineEdit.setFocus()
dlg.lineEdit.setPlaceholderText("Insert")
dlg.pushButton.clicked.connect(Convert)

dlg.lineEdit.returnPressed.connect(Convert)
dlg.lineEdit_2.setReadOnly(True)

dlg.show()
app.exec()
OUTPUT

그림1






Building .exe file

pyuic5 -x main.ui -o main.py
pip install pyinstaller
pyinstaller main.py

image

After executing pyinstaller, 'build', 'dist' folder is created. For finding .exe file, you sould enter 'dist' folder. And then find .exe file inside the folder





List of posts followed by this article


Reference


SUPPLEMENT

API