Bài 14: QCheckBox – Basic Widgets – PyQt6

QCheckBox là một trong các Widget thuộc nhóm cơ bản và nó được dùng thường xuyên trong hầu hết các phần mềm, QCheckBox cung cấp một số trạng thái cho người sử dụng lựa chọn như:

  • Checked
  • Unchecked
  • hoặc Partially checked

Ta thường dùng QCheckBox trong trường hợp cung cấp giao diện cho Khách hàng chọn nhiều lựa chọn. Ví dụ như cung cấp giao diện hỏi về Sở thích (có nhiều sở thích), Cung cấp giao diện cho người dùng chọn nhiều cấu hình, hay chức năng lưu mật khẩu đăng nhập, nói chung là cho nhiều lựa chọn…. Ví dụ:

Một số thuộc tính và phương thức chính thường dùng của QCheckBox:

Thuộc tính/Phương thức/signalÝ nghĩa/ Chức năng
objectNameTên QCheckBox dùng để truy suất
Qt.CheckStateThuộc tính kiểm tra trạng thái của QCheckBox là có checked, unchecked hay partially checked
setChecked(True/False)Hàm thiết lập Checked hoặc Unchecked cho QCheckBox
isChecked()Hàm trả về trạng thái của QCheckBox có được checked hay không
text()Hàm trả về chuỗi hiển thị trên QCheckBox
setTristate(True/False)Thiết lập trạng thái thứ 3 của QCheckBox (Partially checked)
stateChangedSignal để gửi tín hiệu xác nhận người dùng checked hay unchecked QCheckBox

Để sử dụng QCheckBox ta có thể thiết kế bằng Qt Designer hoặc làm tuần tự các bước sau:

Bước 1: Import QCheckBox từ module PyQt6.QtWidgets

from PyQt6.QtWidgets import QCheckBox

Bước 2: Khai báo biến và tạo đối tượng QCheckBox

checkbox = QCheckBox(text)

Bước 3: Lắng nghe thay đổi trạng thái của QCheckBox bằng stateChanged signal

Với checkbox ta cần biết khi nào người sử dụng checked hay unchecked.

checkbox.stateChanged.connect(self.on_checkbox_changed)

stateChanged signal sẽ gửi tín hiệu tới slot on_checkbox_changed (dĩ nhiên ta thích đặt tên slot nào cũng được) để ta biết được trạng thái của checkbox thông qua đối tượng Qt.CheckState:

def on_checkbox_changed(self, value):
    state = Qt.CheckState(value)
    if state == Qt.CheckState.Checked:
        print('You Checked')
    elif state == Qt.CheckState.Unchecked:
        print('You Unchecked')

Qt.CheckState có 3 trạng thái chính như sau:

StateÝ nghĩa
Qt.CheckState.CheckedCheckbox được checked
Qt.CheckState.UncheckedCheckbox được unchecked
Qt.CheckState.PartiallyCheckedHiểu nôm na là Không xác định dạng thái checked hay là unchecked.

Trong bài học này, Tui sẽ minh họa 2 ví dụ về cách sử dụng QCheckBox. Trường hợp thứ nhất là trên giao diện co các QCheckBox, người sử dụng checked/unchecked tùy thích sau đó có QPushButton nhấn để xử lý xem các QCheckBox nào đang được checked. Trường hợp thứ 2 là trên giao diện người dùng lúc checked/unchecked thì ngay lập tức ta xử lý trạng thái của QCheckBox mà không cần thêm một thao tác nhấn QPushButton. Cả 2 trường hợp này ta đều gặp thường xuyên trong quá trình xử lý các trường hợp sử dụng của khách hàng.

Bây giờ ta vào trường hợp 1. Ta sẽ thiết kế và xử lý sự kiện cho bài sau:

Khi người dùng nhập Full Name, Email. Và checked chọn các Khóa học rồi nhấn Submit thì ra cửa sổ thông báo sau:

Ta tạo dự án “LearnCheckbox”, cấu trúc:

Ta dùng Qt Designer để thiết kế giao diện đặt tên file là “MainWindow.ui”:

Thiết kế giao diện và đặt tên các Widget như hình sau đó lưu lại tên “MainWindow.ui” vào dự án Pycharm, sau đó dùng tool để Generate python code thành “MainWindow.py”:

# Form implementation generated from reading ui file 'MainWindow.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(441, 334)
        self.centralwidget = QtWidgets.QWidget(parent=MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.label = QtWidgets.QLabel(parent=self.centralwidget)
        self.label.setGeometry(QtCore.QRect(120, 10, 301, 41))
        font = QtGui.QFont()
        font.setPointSize(15)
        font.setBold(True)
        font.setItalic(True)
        font.setWeight(75)
        self.label.setFont(font)
        self.label.setStyleSheet("color: rgb(0, 0, 255);")
        self.label.setObjectName("label")
        self.label_2 = QtWidgets.QLabel(parent=self.centralwidget)
        self.label_2.setGeometry(QtCore.QRect(20, 60, 101, 21))
        font = QtGui.QFont()
        font.setPointSize(12)
        self.label_2.setFont(font)
        self.label_2.setObjectName("label_2")
        self.lineEditFullName = QtWidgets.QLineEdit(parent=self.centralwidget)
        self.lineEditFullName.setGeometry(QtCore.QRect(130, 60, 251, 20))
        self.lineEditFullName.setObjectName("lineEditFullName")
        self.lineEditEmail = QtWidgets.QLineEdit(parent=self.centralwidget)
        self.lineEditEmail.setGeometry(QtCore.QRect(130, 90, 251, 20))
        self.lineEditEmail.setObjectName("lineEditEmail")
        self.label_3 = QtWidgets.QLabel(parent=self.centralwidget)
        self.label_3.setGeometry(QtCore.QRect(20, 90, 81, 21))
        font = QtGui.QFont()
        font.setPointSize(12)
        self.label_3.setFont(font)
        self.label_3.setObjectName("label_3")
        self.label_4 = QtWidgets.QLabel(parent=self.centralwidget)
        self.label_4.setGeometry(QtCore.QRect(130, 120, 251, 21))
        font = QtGui.QFont()
        font.setPointSize(12)
        self.label_4.setFont(font)
        self.label_4.setStyleSheet("background-color: rgb(255, 255, 0);")
        self.label_4.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
        self.label_4.setObjectName("label_4")
        self.chkMachineLearning = QtWidgets.QCheckBox(parent=self.centralwidget)
        self.chkMachineLearning.setGeometry(QtCore.QRect(130, 150, 241, 18))
        font = QtGui.QFont()
        font.setPointSize(12)
        self.chkMachineLearning.setFont(font)
        self.chkMachineLearning.setObjectName("chkMachineLearning")
        self.chkDeepLearning = QtWidgets.QCheckBox(parent=self.centralwidget)
        self.chkDeepLearning.setGeometry(QtCore.QRect(130, 180, 241, 18))
        font = QtGui.QFont()
        font.setPointSize(12)
        self.chkDeepLearning.setFont(font)
        self.chkDeepLearning.setObjectName("chkDeepLearning")
        self.chkSmartContract = QtWidgets.QCheckBox(parent=self.centralwidget)
        self.chkSmartContract.setGeometry(QtCore.QRect(130, 210, 241, 18))
        font = QtGui.QFont()
        font.setPointSize(12)
        self.chkSmartContract.setFont(font)
        self.chkSmartContract.setObjectName("chkSmartContract")
        self.pushButtonSubmit = QtWidgets.QPushButton(parent=self.centralwidget)
        self.pushButtonSubmit.setGeometry(QtCore.QRect(170, 240, 121, 41))
        font = QtGui.QFont()
        font.setPointSize(12)
        self.pushButtonSubmit.setFont(font)
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap("images/ic_send.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off)
        self.pushButtonSubmit.setIcon(icon)
        self.pushButtonSubmit.setIconSize(QtCore.QSize(32, 32))
        self.pushButtonSubmit.setObjectName("pushButtonSubmit")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(parent=MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 441, 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)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "Trần Duy Thanh"))
        self.label.setText(_translate("MainWindow", "Courses Registration"))
        self.label_2.setText(_translate("MainWindow", "Full Name:"))
        self.label_3.setText(_translate("MainWindow", "Email:"))
        self.label_4.setText(_translate("MainWindow", "Courses Selection:"))
        self.chkMachineLearning.setText(_translate("MainWindow", "Machine Learning"))
        self.chkDeepLearning.setText(_translate("MainWindow", "Deep Learning"))
        self.chkSmartContract.setText(_translate("MainWindow", "Smart Contract"))
        self.pushButtonSubmit.setText(_translate("MainWindow", "Submit"))

Tiếp tục tạo “MainWindowEx.py” kế thừa từ lớp Generate Python code để xử lý các sự kiện:

from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import QMessageBox

from MainWindow import Ui_MainWindow


class MainWindowEx(Ui_MainWindow):
    def __init__(self):
        pass
    def setupUi(self, MainWindow):
        super().setupUi(MainWindow)
        self.MainWindow=MainWindow
        self.pushButtonSubmit.clicked.connect(self.processSubmit)
    def show(self):
        self.MainWindow.show()
    def processSubmit(self):
        str=[]
        if self.chkMachineLearning.isChecked()==True:
            str.append(self.chkMachineLearning.text())
        if self.chkDeepLearning.isChecked()==True:
            str.append(self.chkDeepLearning.text())
        if self.chkSmartContract.isChecked()==True:
            str.append(self.chkSmartContract.text())
        separator=','
        infor="Full Name = "+self.lineEditFullName.text()+"\n"
        infor+="Email = "+self.lineEditEmail.text()+"\n"
        infor+="Selected courses:"+"\n"
        infor+=separator.join(str)
        self.msg=QMessageBox()
        self.msg.setWindowTitle("Selected Courses")
        self.msg.setText(infor)

        self.msg.show()

Hàm processsSubmit ở trên xử lý cho nút lệnh “Submit”, chương trình sẽ kiểm tra các QCheckBox nào được checked, sau đó tổng hợp các dữ liệu như Full Name, Email và các lựa chọn rồi hiển thị lên QMessageBox.

Cuối cùng ta tạo “MyApp.py” để thực thi 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 chương trình lên ta có kết quả như mong muốn.

Mã lệnh của trường hợp này các bạn tải ở đây:

https://www.mediafire.com/file/l0z5tf7oatmg0no/LearnCheckBox.rar/file

Trong ví dụ thứ 2 dưới đây, Tui sẽ minh họa khi người dùng Checked trên QCheckBox thì ngay lập tức xử lý theo các trạng thái của Checkbox, tạo dự án trong Pycharm “LearnCheckBoxDirectly”:

Thiết kế giao diện như hình dưới đặt với tên “MainWindow.ui”, đặt tên widget như hình:

Dùng công cụ để Generate Python code MainWindow.py:

# Form implementation generated from reading ui file 'MainWindow.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(442, 521)
        self.centralwidget = QtWidgets.QWidget(parent=MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.chkShowHide = QtWidgets.QCheckBox(parent=self.centralwidget)
        self.chkShowHide.setGeometry(QtCore.QRect(60, 30, 291, 21))
        font = QtGui.QFont()
        font.setPointSize(12)
        self.chkShowHide.setFont(font)
        self.chkShowHide.setObjectName("chkShowHide")
        self.lblImage = QtWidgets.QLabel(parent=self.centralwidget)
        self.lblImage.setGeometry(QtCore.QRect(60, 60, 301, 371))
        self.lblImage.setText("")
        self.lblImage.setPixmap(QtGui.QPixmap("images/daughter.jpg"))
        self.lblImage.setScaledContents(True)
        self.lblImage.setObjectName("lblImage")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(parent=MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 442, 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)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "Trần Duy Thanh"))
        self.chkShowHide.setText(_translate("MainWindow", "Show/Hide Image"))

Tạo thêm “MainWindowEx.py” kế thừa từ class generate ở trên để xử lý sự kiện:

from PyQt6.QtCore import Qt

from MainWindow import Ui_MainWindow


class MainWindowEx(Ui_MainWindow):
    def __init__(self):
        pass
    def setupUi(self, MainWindow):
        super().setupUi(MainWindow)
        self.MainWindow=MainWindow
        self.chkShowHide.setChecked(True)
        self.chkShowHide.stateChanged.connect(self.processChecked)
    def show(self):
        self.MainWindow.show()
    def processChecked(self,value):
        state=Qt.CheckState(value)
        if state==Qt.CheckState.Checked:
            self.lblImage.show()
        elif state==Qt.CheckState.Unchecked:
            self.lblImage.hide()

Hàm self.chkShowHide.setChecked(True) ở trên mặc định sẽ checked QCheckBox.

Hàm processChecked để lắng nghe xem khi nào QCheckBox được checked hay unchecked.

Lệnh self.lblImage.show() để hiển thị hình khi QCheckBox được checked

Lệnh self.lblImage.hide() để hiển thị hình khi QCheckBox được unchecked

Cuối cùng ta tạo “MyApp.py” để thực thi 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 chương trình lên ta có kết quả.

Khi checked vào QCheckBox:

Khi Unchecked vào QCheckBox:

Mã lệnh của bài trong case 2 này các bạn tải ở đây:

https://www.mediafire.com/file/7so7gruuzxlzpxj/LearnCheckBoxDirectly.rar/file

Như vậy tới đây Tui đã trình bày xong widget QCheckBox một cách khá kỹ lưỡng, với phần trình bày lý thuyết các thành phần và chức năng của QCheckBox. Cũng như có 2 ví dụ minh họa cụ thể để các bạn có thể review lại, các bạn chú ý thực hành lại nhiều lần để hiểu rõ hơn về nó.

Bài học tiếp theo Tui sẽ trình bày về QRadioButton, các bạn chú ý theo dõi

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

One thought on “Bài 14: QCheckBox – Basic Widgets – PyQt6”

Leave a Reply