Bài 4: Xử lý Signals và Slots trong PyQt6 và Qt Designer

Hầu hết mọi giao diện đều cung cấp các chức năng cho người sử dụng tương tác trên giao diện. Các ngôn ngữ như C#, Java chúng ta thường nghe tới thuật ngữ “Event”. Tuy nhiên đối với Python, cụ thể là PyQt6 & Qt Designer thì chúng ta sẽ nghe thêm thuật ngữ Signals Slots.

Signals hiểu nôm na là các hành động được phát đi (truyền đi) bởi các đối tượng trên giao diện (gọi chung là các Widget) khi có cái gì đó xảy ra. Ví dụ như dữ liệu thay đổi trong Input Box, hay thao tác nhấn trên Button… Các Signals này thường được phát sinh bởi các hành động của người sử dụng. Các Signals này khi phát đi nó có thể đính kèm cả dữ liệu mà nó muốn phát. 1 Sender (đối tượng) sẽ có nhiều Signals.

Slots hiểu nôm na là các đối tượng nhận Signals (trong Python thì Hàm/Function cũng có thể được dùng làm Slots, ví dụ như khi nhấn vào Nút Thoát thì ta truyền Signals tới hàm XuLyThoat (hàm này gọi là Slots) thì phần mềm sẽ thoát.). 1 Receiver(đối tượng) sẽ có nhiều Slot.

Các Signals Slots ta có thể cấu hình ngay trên Qt Designer hoặc ta tự lập trình trong code Python.

Các đối tượng trong PyQt6 được xây dựng nhiều Slots có sẵn (gọi là built-in Slots), do đó ta có thể sử dụng trực tiếp các Slot này.

Phần mềm dưới đây Tui sẽ minh họa một số ví dụ của Signals và Slots:

  • Nhập dữ liệu trong QLineEdit thì phát tín hiệu (signals) tới QLabel là QLineEdit đang thay đổi dữ liệu đồng thời truyền dữ liệu từ QLineEdit qua cho QLabel (Như vậy bên QLabel gọi là Slots).
  • Tạo Signals khi nhấn vào 1 QPushButton thì màu nền của MainWindow đổi qua màu đỏ
  • Tạo Signals khi nhấn vào 1 QPushButton thì thoát phần mềm.

Các Signals và Slots ở trên có thể dụng built-in hoặc ta tự viết thêm các hàm để làm Slots.

Tạo một dự án tên “LearnSignalsAndSlots” trong Pycharm (cách tạo dự án và giao diện Qt Designer xem lại bài 2bài 3).

Chọn và Thiết kế giao diện MainWindow như hình dưới đây (lưu với tên file “MyMainWindow.ui” vào dự án “LearnSignalsAndSlots” trong Pycharm). Lưu ý màu nền, màu chữ ta tìm thuộc tính styleSheet để cấu hình:

Trong bài này, các Bạn cứ kéo thả control ra và đặt tên như trong Object Inspector. Chi tiết các controls này sẽ được hướng dẫn ở các bài học tiếp theo. Trong bài này chúng ta chỉ focus vào Signals Slots.

Bước 1: Tạo Signal cho QLineEdit (lineEditName) và Slot cho QLabel (labelName):

  • Nhấn biểu tượng dấu + màu xanh trong mục Signal/Slot Editor:

Lúc này một dòng <sender> <signal> <Receiver> <slot> xuất hiện. Ta chọn như sau:

  • Mục <sender>: Chọn lineEditName
  • Mục <Signal> là gán tín hiêu nào sẽ được truyền đi đối với lineEditName. Ta chọn textChanged(QString):
  • Mục <Receiver> là chọn control labelName nào để nhận Signal.
  • Mục <slot> chọn setText(QString)

Bước 2: Tạo Signal cho pushButtonExit, Slot cho MainWindow. Cách nào tương tự như cho QLineEdit và QLabel nên trong bước này chỉ hiển thị kết quả cuối cùng, còn thao tác các bạn lặp lại như hướng dẫn ở trên.

  • Mục <Sender>: Chọn pushButtonExit
  • Mục <Signal>: Chọn clicked()
  • Mục <Receiver>: Chọn MainWindow
  • Mục <Slot>: Chọn close()

Bước 3: Tạo Signal cho pushButtonChangeColor, Slot cho MainWindow (vì ta muốn khi nhấn vào nút Change Color thì đổi màu nền của MainWindow)

Lưu ý rằng, đối với pushButtonChangeColor thì mục <slot> ta chọn đại một slot nào đó (ví dụ chọn repaint()) vì MainWindow không có sẵn slot đổi màu nền (không có built-in slot đổi màu nền). Vì thế ta sẽ lập trình thêm slot bằng cách viết hàm đổi màu nền cho MainWindow, tức là trong trường hợp này Slot của MainWindow là một hàm mới do ta định nghĩa. Nó sẽ được viết sau khi chúng ta Generate Python code cho giao diện này (sau khi viết xong ta thay thế cho hàm repaint()). Tại sao ta lại lấy đại 1 hàm nào đó làm Slot? bởi vì nếu không lấy hàm nào đó ra làm Slot thì lúc generate code nó không tạo ra lệnh Signal clicked() cho pushButtonChangeColor, mất công ta phải viết bổ sung, do đó đây chỉ là Tips để ta lập trình tạo Slot mới nhanh chóng.

Chúng ta tiến hành lưu giao diện “MyMainWindow.ui” lại để Generate code Python nó ra giao diện cuối cùng.

Sau khi Generate Python Code with PyUIC, ta có mã lệnh “MyMainWindow.py“:

Chi tiết mã lệnh của “MyMainWindow.py“:

# Form implementation generated from reading ui file 'MyMainWindow.ui'
#
# Created by: PyQt6 UI code generator 6.4.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(487, 245)
        self.centralwidget = QtWidgets.QWidget(parent=MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.lineEditName = QtWidgets.QLineEdit(parent=self.centralwidget)
        self.lineEditName.setGeometry(QtCore.QRect(50, 60, 411, 31))
        font = QtGui.QFont()
        font.setPointSize(15)
        self.lineEditName.setFont(font)
        self.lineEditName.setObjectName("lineEditName")
        self.labelName = QtWidgets.QLabel(parent=self.centralwidget)
        self.labelName.setGeometry(QtCore.QRect(50, 110, 411, 31))
        palette = QtGui.QPalette()
        brush = QtGui.QBrush(QtGui.QColor(170, 0, 255))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Active, QtGui.QPalette.ColorRole.WindowText, brush)
        brush = QtGui.QBrush(QtGui.QColor(255, 255, 0))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Active, QtGui.QPalette.ColorRole.Button, brush)
        brush = QtGui.QBrush(QtGui.QColor(170, 0, 255))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Active, QtGui.QPalette.ColorRole.Text, brush)
        brush = QtGui.QBrush(QtGui.QColor(170, 0, 255))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Active, QtGui.QPalette.ColorRole.ButtonText, brush)
        brush = QtGui.QBrush(QtGui.QColor(255, 255, 0))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Active, QtGui.QPalette.ColorRole.Base, brush)
        brush = QtGui.QBrush(QtGui.QColor(255, 255, 0))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Active, QtGui.QPalette.ColorRole.Window, brush)
        brush = QtGui.QBrush(QtGui.QColor(170, 0, 255))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Inactive, QtGui.QPalette.ColorRole.WindowText, brush)
        brush = QtGui.QBrush(QtGui.QColor(255, 255, 0))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Inactive, QtGui.QPalette.ColorRole.Button, brush)
        brush = QtGui.QBrush(QtGui.QColor(170, 0, 255))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Inactive, QtGui.QPalette.ColorRole.Text, brush)
        brush = QtGui.QBrush(QtGui.QColor(170, 0, 255))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Inactive, QtGui.QPalette.ColorRole.ButtonText, brush)
        brush = QtGui.QBrush(QtGui.QColor(255, 255, 0))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Inactive, QtGui.QPalette.ColorRole.Base, brush)
        brush = QtGui.QBrush(QtGui.QColor(255, 255, 0))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Inactive, QtGui.QPalette.ColorRole.Window, brush)
        brush = QtGui.QBrush(QtGui.QColor(170, 0, 255))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Disabled, QtGui.QPalette.ColorRole.WindowText, brush)
        brush = QtGui.QBrush(QtGui.QColor(255, 255, 0))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Disabled, QtGui.QPalette.ColorRole.Button, brush)
        brush = QtGui.QBrush(QtGui.QColor(170, 0, 255))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Disabled, QtGui.QPalette.ColorRole.Text, brush)
        brush = QtGui.QBrush(QtGui.QColor(170, 0, 255))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Disabled, QtGui.QPalette.ColorRole.ButtonText, brush)
        brush = QtGui.QBrush(QtGui.QColor(255, 255, 0))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Disabled, QtGui.QPalette.ColorRole.Base, brush)
        brush = QtGui.QBrush(QtGui.QColor(255, 255, 0))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Disabled, QtGui.QPalette.ColorRole.Window, brush)
        self.labelName.setPalette(palette)
        font = QtGui.QFont()
        font.setPointSize(15)
        self.labelName.setFont(font)
        self.labelName.setAutoFillBackground(False)
        self.labelName.setStyleSheet("background-color: rgb(255, 255, 0);\n"
"color: rgb(170, 0, 255);")
        self.labelName.setText("")
        self.labelName.setObjectName("labelName")
        self.pushButtonChangeColor = QtWidgets.QPushButton(parent=self.centralwidget)
        self.pushButtonChangeColor.setGeometry(QtCore.QRect(50, 150, 181, 41))
        font = QtGui.QFont()
        font.setPointSize(15)
        self.pushButtonChangeColor.setFont(font)
        self.pushButtonChangeColor.setObjectName("pushButtonChangeColor")
        self.pushButtonExit = QtWidgets.QPushButton(parent=self.centralwidget)
        self.pushButtonExit.setGeometry(QtCore.QRect(350, 150, 111, 41))
        font = QtGui.QFont()
        font.setPointSize(15)
        self.pushButtonExit.setFont(font)
        self.pushButtonExit.setObjectName("pushButtonExit")
        self.label_2 = QtWidgets.QLabel(parent=self.centralwidget)
        self.label_2.setGeometry(QtCore.QRect(120, 10, 241, 31))
        font = QtGui.QFont()
        font.setPointSize(15)
        self.label_2.setFont(font)
        self.label_2.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
        self.label_2.setObjectName("label_2")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(parent=MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 487, 26))
        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)
        self.lineEditName.textChanged['QString'].connect(self.labelName.setText) # type: ignore
        self.pushButtonExit.clicked.connect(MainWindow.close) # type: ignore
        self.pushButtonChangeColor.clicked.connect(MainWindow.repaint) # type: ignore
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
        MainWindow.setTabOrder(self.lineEditName, self.pushButtonChangeColor)
        MainWindow.setTabOrder(self.pushButtonChangeColor, self.pushButtonExit)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "Trần Duy Thanh - Signals & Slots"))
        self.pushButtonChangeColor.setText(_translate("MainWindow", "Change Color"))
        self.pushButtonExit.setText(_translate("MainWindow", "Exit"))
        self.label_2.setText(_translate("MainWindow", "Signals & Slots"))

Rõ ràng ta thấy dòng 121 ở trên có:

self.pushButtonChangeColor.clicked.connect(MainWindow.repaint) # type: ignore

Ta sửa thành:

self.pushButtonChangeColor.clicked.connect(self.changeBackground) # type: ignore

Bổ sung dòng lệnh dưới cùng của hàm setupUi:

self.MainWindow=MainWindow

Sau đó Ta viết thêm một hàm để làm Slot, Slot này sẽ đổi màu nền của MainWindow qua màu đỏ:

def changeBackground(self):
self.MainWindow.setStyleSheet("background-color: red;")

Chi tiết mã lệnh cuối cùng của “MyMainWindow.py“:

# Form implementation generated from reading ui file 'MyMainWindow.ui'
#
# Created by: PyQt6 UI code generator 6.4.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(487, 245)
        self.centralwidget = QtWidgets.QWidget(parent=MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.lineEditName = QtWidgets.QLineEdit(parent=self.centralwidget)
        self.lineEditName.setGeometry(QtCore.QRect(50, 60, 411, 31))
        font = QtGui.QFont()
        font.setPointSize(15)
        self.lineEditName.setFont(font)
        self.lineEditName.setObjectName("lineEditName")
        self.labelName = QtWidgets.QLabel(parent=self.centralwidget)
        self.labelName.setGeometry(QtCore.QRect(50, 110, 411, 31))
        palette = QtGui.QPalette()
        brush = QtGui.QBrush(QtGui.QColor(170, 0, 255))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Active, QtGui.QPalette.ColorRole.WindowText, brush)
        brush = QtGui.QBrush(QtGui.QColor(255, 255, 0))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Active, QtGui.QPalette.ColorRole.Button, brush)
        brush = QtGui.QBrush(QtGui.QColor(170, 0, 255))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Active, QtGui.QPalette.ColorRole.Text, brush)
        brush = QtGui.QBrush(QtGui.QColor(170, 0, 255))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Active, QtGui.QPalette.ColorRole.ButtonText, brush)
        brush = QtGui.QBrush(QtGui.QColor(255, 255, 0))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Active, QtGui.QPalette.ColorRole.Base, brush)
        brush = QtGui.QBrush(QtGui.QColor(255, 255, 0))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Active, QtGui.QPalette.ColorRole.Window, brush)
        brush = QtGui.QBrush(QtGui.QColor(170, 0, 255))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Inactive, QtGui.QPalette.ColorRole.WindowText, brush)
        brush = QtGui.QBrush(QtGui.QColor(255, 255, 0))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Inactive, QtGui.QPalette.ColorRole.Button, brush)
        brush = QtGui.QBrush(QtGui.QColor(170, 0, 255))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Inactive, QtGui.QPalette.ColorRole.Text, brush)
        brush = QtGui.QBrush(QtGui.QColor(170, 0, 255))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Inactive, QtGui.QPalette.ColorRole.ButtonText, brush)
        brush = QtGui.QBrush(QtGui.QColor(255, 255, 0))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Inactive, QtGui.QPalette.ColorRole.Base, brush)
        brush = QtGui.QBrush(QtGui.QColor(255, 255, 0))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Inactive, QtGui.QPalette.ColorRole.Window, brush)
        brush = QtGui.QBrush(QtGui.QColor(170, 0, 255))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Disabled, QtGui.QPalette.ColorRole.WindowText, brush)
        brush = QtGui.QBrush(QtGui.QColor(255, 255, 0))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Disabled, QtGui.QPalette.ColorRole.Button, brush)
        brush = QtGui.QBrush(QtGui.QColor(170, 0, 255))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Disabled, QtGui.QPalette.ColorRole.Text, brush)
        brush = QtGui.QBrush(QtGui.QColor(170, 0, 255))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Disabled, QtGui.QPalette.ColorRole.ButtonText, brush)
        brush = QtGui.QBrush(QtGui.QColor(255, 255, 0))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Disabled, QtGui.QPalette.ColorRole.Base, brush)
        brush = QtGui.QBrush(QtGui.QColor(255, 255, 0))
        brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
        palette.setBrush(QtGui.QPalette.ColorGroup.Disabled, QtGui.QPalette.ColorRole.Window, brush)
        self.labelName.setPalette(palette)
        font = QtGui.QFont()
        font.setPointSize(15)
        self.labelName.setFont(font)
        self.labelName.setAutoFillBackground(False)
        self.labelName.setStyleSheet("background-color: rgb(255, 255, 0);\n"
"color: rgb(170, 0, 255);")
        self.labelName.setText("")
        self.labelName.setObjectName("labelName")
        self.pushButtonChangeColor = QtWidgets.QPushButton(parent=self.centralwidget)
        self.pushButtonChangeColor.setGeometry(QtCore.QRect(50, 150, 181, 41))
        font = QtGui.QFont()
        font.setPointSize(15)
        self.pushButtonChangeColor.setFont(font)
        self.pushButtonChangeColor.setObjectName("pushButtonChangeColor")
        self.pushButtonExit = QtWidgets.QPushButton(parent=self.centralwidget)
        self.pushButtonExit.setGeometry(QtCore.QRect(350, 150, 111, 41))
        font = QtGui.QFont()
        font.setPointSize(15)
        self.pushButtonExit.setFont(font)
        self.pushButtonExit.setObjectName("pushButtonExit")
        self.label_2 = QtWidgets.QLabel(parent=self.centralwidget)
        self.label_2.setGeometry(QtCore.QRect(120, 10, 241, 31))
        font = QtGui.QFont()
        font.setPointSize(15)
        self.label_2.setFont(font)
        self.label_2.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
        self.label_2.setObjectName("label_2")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(parent=MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 487, 26))
        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)
        self.lineEditName.textChanged['QString'].connect(self.labelName.setText) # type: ignore
        self.pushButtonExit.clicked.connect(MainWindow.close) # type: ignore
        self.pushButtonChangeColor.clicked.connect(self.changeBackground) # type: ignore
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
        MainWindow.setTabOrder(self.lineEditName, self.pushButtonChangeColor)
        MainWindow.setTabOrder(self.pushButtonChangeColor, self.pushButtonExit)
        self.MainWindow=MainWindow
    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "Trần Duy Thanh - Signals & Slots"))
        self.pushButtonChangeColor.setText(_translate("MainWindow", "Change Color"))
        self.pushButtonExit.setText(_translate("MainWindow", "Exit"))
        self.label_2.setText(_translate("MainWindow", "Signals & Slots"))
    def changeBackground(self):
        self.MainWindow.setStyleSheet("background-color: red;")

Cuối cùng ta tạo một file Python “MyApp.py” trong dự án Pycharm để gọi các lệnh chạy giao diện phần mềm:

Mã lệnh của “MyApp.py” tương tự như các bài học trước, ta có chi tiết:

from PyQt6.QtWidgets import QApplication, QMainWindow

from MyMainWindow import Ui_MainWindow

app=QApplication([])

qMainWindow=QMainWindow()

myWindow=Ui_MainWindow()

myWindow.setupUi(qMainWindow)

qMainWindow.show()

app.exec()

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

Ta gõ dữ liệu trong ô QLineEdit tới đâu thì QLabel sẽ tự động cập nhật dữ liệu tới đó. Như vậy QLineEdit (Sender) đã truyền Signal “textChanged” cho QLabel (Receiver), và QLabel dùng Slot setText để nhận dữ liệu.

Tương tự như vậy ta thử nghiệm nhất vào nút QPushButton “Change Color”, lúc này màu nền của MainWindow sẽ chuyển qua màu đỏ:

Cuối cùng là khi người sử dụng nhấn vào nút QPushButton (Sender) “Exit” thì nó sẽ truyền Signal “clicked” tới MainWindow (Receiver) và MainWindow dùng Slot close để nhận tín hiệu, tức là nó thoát phần mềm.

Như vậy Tui đã hướng dẫn xong phần Signals và Slot rất chi tiết, các bạn cố gắng đọc thật kỹ lý thuyết, cũng như cơ chế hoạt động của chúng. Phân biệt đâu là Sender, đâu là Receiver, đâu là Signals, đâu là Slot. Đồng thời phải biết cách dùng Qt Designer để cấu hình các Signals và Slot, ngoài ra phải biết cách định nghĩa hàm trong Python để làm Slot.

Đây là coding đầy đủ của bài này:

https://www.mediafire.com/file/w2xr6oaxkoqud6o/LearnSignalsAndSlots.rar/file

Các bài học sau Tui sẽ trình bày chi tiết về MainWindow cũng như các thuộc tính, Signal, Slot và event của nó. Sau khi nắm chắc MainWindow thì chúng ta sẽ học về Layout để biết cách bố cục giao diện, biết được bố cục giao diện thì ta mới đi chi tiết vào từng Widgets cụ thể được.

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

One thought on “Bài 4: Xử lý Signals và Slots trong PyQt6 và Qt Designer”

Leave a Reply