Bài 11: QLabel – Basic Widgets – PyQt6

Các bài học trước chúng ta đã được học chi tiết về cách tạo dự án trong Pycharm và tích hợp giao diện PyQt6-Qt Designer, các bạn đã biết cách thiết kế giao diện, sử dụng các Layout management để bố cục giao diện theo từng yêu cầu riêng, cũng như cách sử dụng Signals/Slots để xử lý sự kiện, đặc biệt là biết cách viết các lớp kế thừa để xử lý sự kiện mà không bị ảnh hưởng khi trong tương lai giao diện bị thay đổi. Các chuỗi bài học tiếp theo đây Tui sẽ hướng dẫn chi tiết từng Widget trong giao diện, từ cơ bản tới nâng cao, cũng như cách xử lý đa tiến trình, Styles, Chart…. để các bạn có thể dễ dàng thiết kế mọi giao diện đáp ứng được hầu hết các yêu cầu của khách hàng. Chuỗi các bài học Tui có tổng hợp trong link này để các bạn dễ dàng truy suất: https://tranduythanh.com/pyqt6-qt-designer/. Sau khi học xong các phần xử lý giao diện, Tui sẽ hướng dẫn các bạn cách build mô hình máy học và tích hợp mô hình máy học vào các dự án phần mềm tương tác người dùng, chẳng hạn như các mô hình dự báo kinh doanh, các mô hình gợi ý sản phẩm, phân tích cảm xúc khách hàng, thị giác máy tính…. Do đó để có thể vững lý thuyết chắc tay nghề thì các Bạn cần kiên trì, chăm chỉ, đọc kỹ lý thuyết và thực hành từng bước các bài hướng dẫn nhiều lần. Các bạn không nên nhảy cóc mà hãy học lần lượt từ bài số 1 cho tới bài cuối cùng, vì hầu hết các bài học này Tui hướng dẫn từ cơ bản tới nâng cao và có tính kế thừa, vận dụng lại các bài học trước đó.

Trong bài này Tui sẽ hướng dẫn các Bạn cách thức sử dụng QLabel, QLabel là Widget dùng để hiển thị dữ liệu dạng text, hình ảnh (nhiều định dạng như bmp, gif, jpg, jpeg, png, svg, …), Một số ví dụ minh họa Chúng ta sẽ thực hiện bao gồm:

  • Hiển thị dữ liệu dạng text thông thường
  • Hiện thị dữ liệu dạng text kết hợp căn lề, font chữ
  • Hiển thị dữ liệu dạng text có định dạng HTML
  • Hiển thị dữ liệu dạng hình ảnh dạng .bmp, .jpg, .jpeg, .png, .svg (QPixmap)
  • Hiển thị dữ liệu dạng hình ảnh dạng .gif (QMovie)

Chúng ta có thể viết code để sử dụng QLable lúc runtime hoặc sử dụng Qt Designer để sử dụng QLable lúc design time, tùy vào tình huống cụ thể mà ta lựa chọn tạo QLabel theo runtime hay design time.

Để sử dụng QLabel và hiển thị dữ liệu dạng text thông thườngta làm theo các bước sau:

Bước 1: Ta import widget QLabel trong gói module PyQt6.QtWidgets

from PyQt6.QtWidgets import QLabel

Bước 2: Tạo đối tượng từ lớp QLabel

label = QLabel('Hello, I am QLabel widget')

Mã lệnh ở trên tạo một đối tượng QLabel đồng thời khởi tạo chuỗi hiển thị mặc định. Ngoài ra ta có thể tạo đối tượng QLabel sau đó mới gán chuỗi hiển thị cho Label bằng cách sau:

label = QLabel()
label.setText('Hello, I am QLabel widget')

Bước 3: Truy suất và xóa dữ liệu hiển thị trong QLabel

Để truy suất tới nhãn hiển thị của QLabel ta gọi phương thức text():

label.text()

Để xóa dữ liệu hiển thị của QLabel ta gọi phương thức clear():

label.clear()

Để thay đổi font chữ cho QLabel ta dùng phương thức setFont như sau:

font = label.font()
font.setPointSize(30)
label.setFont(font)

Để căn lề cho chuỗi hiển thị trên QLabel ta gọi phương thức setAlignment: Ví dụ thiết lập căn lề nằm giữa theo chiều ngang:

label.setAlignment(Qt.AlignmentFlag.AlignHCenter)

Một số thuộc tính căn lề cần quan tâm:

Loại căn lềMô tả
Qt.AlignmentFlag.AlignLeftCăn chuỗi hiển thị bên trái QLabel
Qt.AlignmentFlag.AlignRightCăn chuỗi hiển thị bên phải QLabel
Qt.AlignmentFlag.AlignHCenterCăn chuỗi hiển thị nằm ở giữa QLabel theo phương ngang
Qt.AlignmentFlag.AlignJustifyCăn chuỗi hiển thị điều 2 bên của QLabel
Qt.AlignmentFlag.AlignTopCăn chuỗi hiển thị nằm ở phía bên trên Top QLabel
Qt.AlignmentFlag.AlignBottomCăn chuỗi hiển thị nằm ở phía bên dưới Bottom QLabel
Qt.AlignmentFlag.AlignVCenterCăn chuỗi hiển thị nằm ở giữa QLabel theo phương đứng

Chúng ta có thể dùng ký tự | để kết hợp nhiều loại căn lề, ví dụ căn lề phía bên trên góc trái:

align_top_left = Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignTop
label.setAlignment(align_top_left)

Để hiển thị chuỗi có định dạng HTML cho QLabel ta viết như sau:

label.setText("<html><head/><body><p><span style=\" font-weight:600; color:#ff0000;\">Hello, I am QLable Widget</span></p></body></html>")

Để hiển thị dữ liệu hình ảnh định dạng .bmp, .jpg, .jpeg, .png, .svg cho QLabel ta dùng đối tượng QPixmap như dưới đây:

label = QLabel()
pixmap = QPixmap('myavatar.png')
label.setPixmap(pixmap)

Để hiển thị dữ liệu hình ảnh định dạng .gif cho QLabel ta dùng đối tượng QMovie như dưới đây:

from PyQt6.QtGui import QMovie
movie = QMovie('mygif.gif')
label = QLabel()
label.setMovie(movie)
movie.start()

Như vậy với các trình bày lý thuyết ở trên về cơ bản các bạn đã biết cách sử dụng QLabel, cách thức thao tác trên QLabel như tạo dữ liệu hiển thị, căn lề, hiển thị hình ảnh với nhiều định dạng khác nhau. Các bạn cần hiểu rõ các kiến thức này để áp dụng vào bài thiết kế thực tế.

Tiếp theo đây, chúng ta sẽ tiến hành tạo dự án tên “LearnQLabel” trong Pycharm, sử dụng Qt Designer để thiết kế cũng như thao tác với QLabel.

Sau khi tạo xong dự án “LearnQLabel“, ta tạo thêm một thư mục để lưu trữ hình ảnh .png cũng như .gif: Bấm chuột phải vào dự án chọn New/ Chọn Directory

Sau đó tạo thư mục tên là “images“:

Bạn chép 2 hình ảnh có định dạng png gif vào thư mục “images”, vì các hình ảnh bmp, jpg, jpeg, svg xử lý giống như png nên Tui chỉ minh họa png.

Tiếp theo ta sử dụng Qt Designer để thiết kế giao diện như dưới đây: Bấm chuột phải vào dự án/ chọn External Tools/ Chọn Create New Qt Designer:

Sau đó chọn QMainWindow để tạo giao diện: Trong công cụ Widget Box, ta kéo Label ra màn hình MainWindow:

Ta có thể hiệu chỉnh các thuộc tính của QLabel bằng cách bấm chuột phải vào QLabel rồi chọn “Change plain text…” để đổi nhãn hiển thị mà không có định dạng, hoặc chọn “Change rich text…” để đổi nhãn hiển thị cùng với định dạng HTML, hay đổi tên của QLabel bằng cách chọn “Change objectName…”, ngoài ra nếu muốn hiệu chỉnh nhiều thuộc tính khác của QLabel thì sau khi nhấn chuột vào QLabel, ta nhìn vào công cụ “Property Editor“, các thuộc tính của QLabel sẽ hiển thị chi tiết như text, texFormat, pixmap, alignment, margin…. tùy vào nhu cầu sử dụng mà ta thay đổi giá trị của các thuộc tính này cho nó hợp lý.

Ví dụ giả sử Tui chọn “Change rich text…” để hiệu chỉnh nhãn hiển thị có định dạng HTML:

Trong công cụ Edit Text ở trên, để thay đổi định dạng của chuỗi hiện thị, trước tiên ta bôi đen chuỗi hiển thị, sau đó chọn thay đổi size font chữ (to nhỏ), kiểu chữ (In đậm, in nghiêng, gạch chân), căn lề (trái, giữa, phải, đều 2 bên), hay hiệu chỉnh hình nền, màu nền màu chữ bằng các biểu tượng ở góc phải bên trên của cửa sổ Edit Text. Nhập dữ liệu và định dạng xong thì nhấn nút OK, ta có giao diện:

Bây giờ ta bổ sung thêm các Widgets như hình dưới đây:

Bạn cần kéo thả các Widgets và đặt tên giống như hình trên.

Ngoài ra bạn cũng có thể thêm hình vào lúc đang thiết kế, ví dụ Tui để mặc định hình hiển thị là mydaugther.PNG: Chọn QLabel, sau đó chọn pixmap-> Rồi chọn Choose File...

Sau đó chọn hình mà mình muốn hiển thị lên QLabel:

Chọn hình xong bấm Open, kết quả:

Ta checked cho thuộc tính “scaledContents” để thấy hình được stretch trong QLabel.

Lưu file giao diện với tên MainWindow.ui, nó tự động cập nhật trong dự án Pycharm:

Tiếp theo ta dùng chức năng Generate Python code cho giao diện “MainWindow.ui” lúc này file mã lệnh “MainWindow.py” được generate:

# 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(542, 450)
        self.centralwidget = QtWidgets.QWidget(parent=MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.Titlelabel = QtWidgets.QLabel(parent=self.centralwidget)
        self.Titlelabel.setGeometry(QtCore.QRect(40, 10, 381, 41))
        self.Titlelabel.setTextFormat(QtCore.Qt.TextFormat.AutoText)
        self.Titlelabel.setObjectName("Titlelabel")
        self.ShowPNGpushButton = QtWidgets.QPushButton(parent=self.centralwidget)
        self.ShowPNGpushButton.setGeometry(QtCore.QRect(140, 100, 121, 31))
        self.ShowPNGpushButton.setObjectName("ShowPNGpushButton")
        self.showGIFpushButton = QtWidgets.QPushButton(parent=self.centralwidget)
        self.showGIFpushButton.setGeometry(QtCore.QRect(270, 100, 121, 31))
        self.showGIFpushButton.setObjectName("showGIFpushButton")
        self.imageLabel = QtWidgets.QLabel(parent=self.centralwidget)
        self.imageLabel.setGeometry(QtCore.QRect(120, 140, 271, 231))
        self.imageLabel.setText("")
        self.imageLabel.setPixmap(QtGui.QPixmap("images/mydaughter.PNG"))
        self.imageLabel.setScaledContents(True)
        self.imageLabel.setObjectName("imageLabel")
        self.changeTextpushButton = QtWidgets.QPushButton(parent=self.centralwidget)
        self.changeTextpushButton.setGeometry(QtCore.QRect(30, 60, 75, 23))
        self.changeTextpushButton.setObjectName("changeTextpushButton")
        self.alignLeftpushButton = QtWidgets.QPushButton(parent=self.centralwidget)
        self.alignLeftpushButton.setGeometry(QtCore.QRect(240, 60, 75, 23))
        self.alignLeftpushButton.setObjectName("alignLeftpushButton")
        self.alignCenterpushButton = QtWidgets.QPushButton(parent=self.centralwidget)
        self.alignCenterpushButton.setGeometry(QtCore.QRect(330, 60, 75, 23))
        self.alignCenterpushButton.setObjectName("alignCenterpushButton")
        self.alignRightpushButton = QtWidgets.QPushButton(parent=self.centralwidget)
        self.alignRightpushButton.setGeometry(QtCore.QRect(410, 60, 75, 23))
        self.alignRightpushButton.setObjectName("alignRightpushButton")
        self.fontSizepushButton = QtWidgets.QPushButton(parent=self.centralwidget)
        self.fontSizepushButton.setGeometry(QtCore.QRect(120, 60, 75, 23))
        self.fontSizepushButton.setObjectName("fontSizepushButton")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(parent=MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 542, 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", "MainWindow"))
        self.Titlelabel.setText(_translate("MainWindow", "<html><head/><body><p><span style=\" font-size:12pt; font-weight:600; color:#ff0000;\">Trần Duy Thanh</span></p></body></html>"))
        self.ShowPNGpushButton.setText(_translate("MainWindow", "Show .PNG Format"))
        self.showGIFpushButton.setText(_translate("MainWindow", "Show .GIF Format"))
        self.changeTextpushButton.setText(_translate("MainWindow", "Change Text"))
        self.alignLeftpushButton.setText(_translate("MainWindow", "Align Left"))
        self.alignCenterpushButton.setText(_translate("MainWindow", "Align Center"))
        self.alignRightpushButton.setText(_translate("MainWindow", "Align Right"))
        self.fontSizepushButton.setText(_translate("MainWindow", "Font Size ++"))

Tiếp theo ta tạo một lớp “MainWindowEx” kế thừa từ lớp Generate Python code ở trên, mục đích để xử lý sự kiện người dùng mà không bị ảnh hưởng giao diện khi trong tương lai nó thay đổi.

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()

Tiếp theo ta tạo lớp/file “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 “MyApp.py” ta có kết quả:

Phần mềm trên có 7 chức năng mà ta cần lập trình: Đổi text, thay đổi font chữ, căn lề trái, căn giữa, căn lề phải, đổi 2 hình. Ta tiếp tục hiệu chỉnh mã lệnh cho lớp “MainWindowEx.py” để xử lý đủ 7 chức năng này:

  • Đổi Text: Gọi Signal và gán Slots cho Button đổi text, nhấn vào thì thay nhãn bằng “https://tranduythanh.com”
from MainWindow import Ui_MainWindow


class MainWindowEx(Ui_MainWindow):
    def __init__(self):
        pass
    def setupUi(self, MainWindow):
        super().setupUi(MainWindow)
        self.MainWindow=MainWindow
        #change text
        self.changeTextpushButton.clicked.connect(self.processChangeText)
    def show(self):
        self.MainWindow.show()
    def processChangeText(self):
        self.Titlelabel.setText("https://tranduythanh.com")

Chạy phần lên, nhấn nút “Change Text” ta có kết quả:

  • Đổi font size: Tiếp tục gán sự kiện cho nút đổi font size
from MainWindow import Ui_MainWindow


class MainWindowEx(Ui_MainWindow):
    def __init__(self):
        pass
    def setupUi(self, MainWindow):
        super().setupUi(MainWindow)
        self.MainWindow=MainWindow
        #change text
        self.changeTextpushButton.clicked.connect(self.processChangeText)
        #change font
        self.fontSizepushButton.clicked.connect(self.processChangeFontSize)
    def show(self):
        self.MainWindow.show()
    def processChangeText(self):
        self.Titlelabel.setText("https://tranduythanh.com")
    def processChangeFontSize(self):
        #get font object
        font=self.Titlelabel.font()
        #change font size
        font.setPointSize(20)
        #set italic
        font.setItalic(True)
        #set bold
        font.setBold(True)
        #set font name
        font.setFamily("cambria")
        #re-assign font
        self.Titlelabel.setFont(font)

Hàm/Slot processChangeFontSize ở trên dùng để thay đổi font.

  • Tiếp tục ta bổ sung mã lệnh để căn trái, phải, giữa cho text nằm trong QLable:
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
        #change text
        self.changeTextpushButton.clicked.connect(self.processChangeText)
        #change font
        self.fontSizepushButton.clicked.connect(self.processChangeFontSize)
        #set align text
        self.alignLeftpushButton.clicked.connect(self.processAlignLeft)
        self.alignCenterpushButton.clicked.connect(self.processAlignCenter)
        self.alignRightpushButton.clicked.connect(self.processAlignRight)
    def show(self):
        self.MainWindow.show()
    def processChangeText(self):
        self.Titlelabel.setText("https://tranduythanh.com")
    def processChangeFontSize(self):
        #get font object
        font=self.Titlelabel.font()
        #change font size
        font.setPointSize(20)
        #set italic
        font.setItalic(True)
        #set bold
        font.setBold(True)
        #set font name
        font.setFamily("cambria")
        #re-assign font
        self.Titlelabel.setFont(font)
    def processAlignLeft(self):
        self.Titlelabel.setAlignment(Qt.AlignmentFlag.AlignLeft)
    def processAlignCenter(self):
        self.Titlelabel.setAlignment(Qt.AlignmentFlag.AlignCenter)
    def processAlignRight(self):
        self.Titlelabel.setAlignment(Qt.AlignmentFlag.AlignRight)
  • Cuối cùng ta viết sự kiện để thay đổi 2 hình ảnh cho các Button:
from PyQt6.QtCore import Qt
from PyQt6.QtGui import QPixmap, QMovie

from MainWindow import Ui_MainWindow


class MainWindowEx(Ui_MainWindow):
    def __init__(self):
        pass
    def setupUi(self, MainWindow):
        super().setupUi(MainWindow)
        self.MainWindow=MainWindow
        #change text
        self.changeTextpushButton.clicked.connect(self.processChangeText)
        #change font
        self.fontSizepushButton.clicked.connect(self.processChangeFontSize)
        #set align text
        self.alignLeftpushButton.clicked.connect(self.processAlignLeft)
        self.alignCenterpushButton.clicked.connect(self.processAlignCenter)
        self.alignRightpushButton.clicked.connect(self.processAlignRight)
        #change image with PNG format
        self.ShowPNGpushButton.clicked.connect(self.processChangePNG)
        #change image with gif format
        self.showGIFpushButton.clicked.connect(self.processChangeGIF)
    def show(self):
        self.MainWindow.show()
    def processChangeText(self):
        self.Titlelabel.setText("https://tranduythanh.com")
    def processChangeFontSize(self):
        #get font object
        font=self.Titlelabel.font()
        #change font size
        font.setPointSize(20)
        #set italic
        font.setItalic(True)
        #set bold
        font.setBold(True)
        #set font name
        font.setFamily("cambria")
        #re-assign font
        self.Titlelabel.setFont(font)
    def processAlignLeft(self):
        self.Titlelabel.setAlignment(Qt.AlignmentFlag.AlignLeft)
    def processAlignCenter(self):
        self.Titlelabel.setAlignment(Qt.AlignmentFlag.AlignCenter)
    def processAlignRight(self):
        self.Titlelabel.setAlignment(Qt.AlignmentFlag.AlignRight)
    def processChangePNG(self):
        #create QPixmap instance
        pixmap=QPixmap("images/mydaughter.PNG")
        #set pixmap for label
        self.imageLabel.setPixmap(pixmap)
    def processChangeGIF(self):
        #create QMovie instance
        movie=QMovie("images/PyQt-Grid-AlignmentFlag.gif")
        #set movie object for label
        self.imageLabel.setMovie(movie)
        #call start method
        movie.start()

Như vậy ta đã có đầy đủ mã lệnh, chạy phần mềm lên ta được:

Như vậy Tui đã trình bày khá chi tiết cách sử dụng QLabel, và các bạn đã biết cách ứng dụng QLabel với các trường hợp khác nhau trong triển khai phần mềm. Bạn có thể kết hợp nhiều cách sử dụng QLabel vào từng trường hợp cụ thể.

Dưới đây là mã lệnh đầy đủ của bài học này:

https://www.mediafire.com/file/4a6e3xelgpmemns/LearnQLabel.rar/file

Các bạn cố gắng học phần lý thuyết và thực hành lại nhiều lần các bài hướng dẫn ở trên.

Các bài học tiếp theo Tui sẽ trình bày về QLineEdit và QPushButton. Các bạn chú ý theo dõi.

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

Leave a Reply