Bài 10: QFormLayout-Layout Management

Như vậy chúng ta đã thao tác được với các Layout: QVBoxLayout để sắp xếp widgets theo phương thẳng đứng, QHBoxLayout để sắp xếp Widgets theo phương ngang, QGridLayout để sắp xếp Widgets theo dạng dòng và cột. Trong bài này ta sẽ vào layout cuối cùng đó là QFormLayout để sắp xếp các Widget theo dạng Data- Entry, nghĩa là khi thiết kế giao diện ta muốn vừa có label vừa có nhập liệu ví dụ như thiết kế màn hình đăng nhập, thiết kế màn hình đăng ký….Thì mỗi một dòng tạo ra nó tự động có 2 cột, cột 1 là label, cột 2 là ô nhập liệu.

Bước 1: Trong Pycharm, tạo một dự án tên “LearnQFormLayout“, sử dụng Qt Designer để thiết kế, kéo FormLayout ra giao diện:

Bước 2: Để thêm các row layout, ví dụ trong bài này ta thiết kế màn hình đăng ký: Bấm chuột phải vào QFormLayout -> Chọn Add form layout row…

Thêm nhãn Full Name và QLineEdit nhập full name

Label text: Nhập tiêu đề

Label name: Đặt tên cho Label (dùng cho lập trình truy suất widget)

Field type: Chọn QLineEdit là ô nhập liệu

Field name: Đặt tên cho QLineEdit (dùng cho lập trình truy suất widget)

Sau đó nhấn OK để tạo widget.

Lưu ý tùy vào mục đích sử dụng mà ta có thể chọn các Field type khác nhau:

Bước 3: Tương tự, ta lần lượt tạo thêm User Name, Password và Confirm Password:

Bước 4: Ta bổ sung thêm QPushButton và cấu hình như bên dưới:

Kéo PushButton vào ô thứ 2, chỉnh width và height trong Property Editor như hình.

Ngoài ra các ô Password và Confirm Password, ta chỉnh echoMode qua Password:

Lưu lại giao diện với tên “MainWindow.ui

Bước 5: Generate Python code cho giao diện “MainWindow.ui” trong file “MainWindow.py”:

# Form implementation generated from reading ui file 'MainWindow.ui'
#
# Created by: PyQt6 UI code generator 6.5.2
#
# WARNING: Any manual changes made to this file will be lost when pyuic6 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt6 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(423, 285)
        self.centralwidget = QtWidgets.QWidget(parent=MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setObjectName("verticalLayout")
        self.formLayout = QtWidgets.QFormLayout()
        self.formLayout.setObjectName("formLayout")
        self.fullNameLabel = QtWidgets.QLabel(parent=self.centralwidget)
        self.fullNameLabel.setObjectName("fullNameLabel")
        self.formLayout.setWidget(0, QtWidgets.QFormLayout.ItemRole.LabelRole, self.fullNameLabel)
        self.fullNameLineEdit = QtWidgets.QLineEdit(parent=self.centralwidget)
        self.fullNameLineEdit.setObjectName("fullNameLineEdit")
        self.formLayout.setWidget(0, QtWidgets.QFormLayout.ItemRole.FieldRole, self.fullNameLineEdit)
        self.userNameLabel = QtWidgets.QLabel(parent=self.centralwidget)
        self.userNameLabel.setObjectName("userNameLabel")
        self.formLayout.setWidget(1, QtWidgets.QFormLayout.ItemRole.LabelRole, self.userNameLabel)
        self.userNameLineEdit = QtWidgets.QLineEdit(parent=self.centralwidget)
        self.userNameLineEdit.setObjectName("userNameLineEdit")
        self.formLayout.setWidget(1, QtWidgets.QFormLayout.ItemRole.FieldRole, self.userNameLineEdit)
        self.passwordLabel = QtWidgets.QLabel(parent=self.centralwidget)
        self.passwordLabel.setObjectName("passwordLabel")
        self.formLayout.setWidget(2, QtWidgets.QFormLayout.ItemRole.LabelRole, self.passwordLabel)
        self.passwordLineEdit = QtWidgets.QLineEdit(parent=self.centralwidget)
        self.passwordLineEdit.setEchoMode(QtWidgets.QLineEdit.EchoMode.Password)
        self.passwordLineEdit.setObjectName("passwordLineEdit")
        self.formLayout.setWidget(2, QtWidgets.QFormLayout.ItemRole.FieldRole, self.passwordLineEdit)
        self.confirmPasswordLabel = QtWidgets.QLabel(parent=self.centralwidget)
        self.confirmPasswordLabel.setObjectName("confirmPasswordLabel")
        self.formLayout.setWidget(3, QtWidgets.QFormLayout.ItemRole.LabelRole, self.confirmPasswordLabel)
        self.confirmPasswordLineEdit = QtWidgets.QLineEdit(parent=self.centralwidget)
        self.confirmPasswordLineEdit.setEchoMode(QtWidgets.QLineEdit.EchoMode.Password)
        self.confirmPasswordLineEdit.setObjectName("confirmPasswordLineEdit")
        self.formLayout.setWidget(3, QtWidgets.QFormLayout.ItemRole.FieldRole, self.confirmPasswordLineEdit)
        self.pushButton = QtWidgets.QPushButton(parent=self.centralwidget)
        self.pushButton.setMinimumSize(QtCore.QSize(100, 30))
        self.pushButton.setMaximumSize(QtCore.QSize(100, 30))
        self.pushButton.setObjectName("pushButton")
        self.formLayout.setWidget(4, QtWidgets.QFormLayout.ItemRole.FieldRole, self.pushButton)
        self.verticalLayout.addLayout(self.formLayout)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(parent=MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 423, 22))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(parent=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", "Tran Duy Thanh"))
        self.fullNameLabel.setText(_translate("MainWindow", "Full Name:"))
        self.userNameLabel.setText(_translate("MainWindow", "User Name:"))
        self.passwordLabel.setText(_translate("MainWindow", "Password:"))
        self.confirmPasswordLabel.setText(_translate("MainWindow", "Confirm Password:"))
        self.pushButton.setToolTip(_translate("MainWindow", "<html><head/><body><p><span style=\" font-size:11pt; font-weight:600; color:#ff0000;\">Click here to Signup</span></p></body></html>"))
        self.pushButton.setText(_translate("MainWindow", "Sign Up"))

Bước 6: Tạo lớp Python kế thừa “MainWindowEx.py” từ “MainWindow.py” để xử lý các sự kiện

from MainWindow import Ui_MainWindow


class MainWindowEx(Ui_MainWindow):
    def __init__(self):
        pass
    def setupUi(self, MainWindow):
        super().setupUi(MainWindow)
        self.MainWindow=MainWindow
    def show(self):
        self.MainWindow.show()

Bước 7: Tạo “MyApp.py” để chạy chương trình

from PyQt6.QtWidgets import QApplication, QMainWindow

from MainWindowEx import MainWindowEx

app=QApplication([])
myWindow= MainWindowEx()
myWindow.setupUi(QMainWindow())
myWindow.show()
app.exec()

Chạy phần mềm lên ta có kết quả:

Các bạn có thể tải mã nguồn của bài QFormLayout ở đây:

https://www.mediafire.com/file/u3553qa1fxit4q8/LearnQFormLayout.rar/file

Như vậy tới đây Tui đã trình bày xong các Layout quan trọng và thường sử dụng trong Qt Designer/ PyQt6. Các bạn có thể phối hợp các layout lại để thiết kế các bố cục giao diện theo yêu cầu của khách hàng.

Các bài học sau Tui sẽ trình bày chi tiết về các Widgets cơ bản trong PyQt6, thiết kế trong Qt Designer cũng như cách thức lập trình xử lý sự kiện tương tác người dùng. Mỗi bài Tui sẽ cố gắng cung cấp các ví dụ sát với thực tế để các bạn dễ hiểu bài, vững lý thuyết chắc tay nghề.

Chúc các bạn thành công

Leave a Reply