Python: Python và PyQt: Tạo Menu, Toolbar, Status Bar

Các khóa học qua video:
Python SQL Server PHP C# Lập trình C Java HTML5-CSS3-JavaScript
Học trên YouTube <76K/tháng. Đăng ký Hội viên
Viết nhanh hơn - Học tốt hơn
Giải phóng thời gian, khai phóng năng lực
Python và PyQt: Tạo Menu, Toolbar, Status Bar

Mục lục bài viết:


Nhấn vào ĐÂY để xem source code của bài viết.

Khi nói đến việc phát triển các ứng dụng giao diện người dùng đồ họa (GUI) với Python và PyQt, một số phần tử đồ họa hữu ích và linh hoạt nhất mà bạn sẽ sử dụng là menuthanh công cụ và thanh trạng thái.

Các menu và thanh công cụ có thể làm cho các ứng dụng của bạn trông bóng bẩy và chuyên nghiệp, cung cấp cho người dùng một bộ tùy chọn có thể truy cập được, trong khi các thanh trạng thái cho phép bạn hiển thị thông tin liên quan về trạng thái của ứng dụng.

Trong hướng dẫn này, bạn sẽ học:

  • menu, thanh công cụ, thanh trạng thái là gì
  • Cách lập trình tạo menu, thanh công cụ và thanh trạng thái
  • Cách điền menu Python và thanh công cụ bằng các hành động PyQt
  • Cách sử dụng thanh trạng thái để hiển thị thông tin trạng thái

Ngoài ra, bạn sẽ học một số phương pháp lập trình hay nhất mà bạn có thể áp dụng khi tạo menu, thanh công cụ và thanh trạng thái bằng Python và PyQt. Nếu bạn chưa quen với lập trình GUI với PyQt, thì bạn có thể xem Python và PyQt: Xây dựng Máy tính để bàn GUI.

Xây dựng thanh menu, menu và thanh công cụ Python trong PyQt

Một thanh menu là một khu vực của một ứng dụng GUI của cửa sổ chính chứa các menu. Menu là danh sách các tùy chọn kéo xuống cung cấp khả năng truy cập thuận tiện vào các tùy chọn của ứng dụng của bạn. Ví dụ: nếu bạn đang tạo một trình soạn thảo văn bản, thì bạn có thể có một số menu sau trong thanh menu của mình:

  • Một menu File trình đơn cung cấp một số tùy chọn menu bên dưới:
    • New để tạo một tài liệu mới
    • Open để mở một tài liệu hiện có
    • Open Recent để mở các tài liệu gần đây
    • Save để lưu tài liệu
    • Exit để thoát khỏi ứng dụng
  • Một menu Edit trình đơn cung cấp một số tùy chọn menu bên dưới:
    • Copy để sao chép một số văn bản
    • Paste để dán một số văn bản
    • Cut để cắt một số văn bản
  • Một menu Help cung cấp một số tùy chọn menu bên dưới:
    • Help Content để khởi chạy đến nội dung trợ giúp và hướng dẫn sử dụng
    • About để khởi chạy hộp thoại About

Bạn cũng có thể thêm một số tùy chọn này vào thanh công cụ. Thanh công cụ là một bảng gồm các nút với các biểu tượng có ý nghĩa giúp truy cập nhanh vào các tùy chọn thường được sử dụng nhất trong một ứng dụng. Trong ví dụ về trình soạn thảo văn bản của bạn, bạn có thể thêm các tùy chọn như NewOpenSaveCopy và Paste vào thanh công cụ.

Lưu ý: Trong hướng dẫn này, bạn sẽ phát triển một ứng dụng mẫu triển khai tất cả các menu và tùy chọn ở trên. Bạn có thể sử dụng ứng dụng mẫu này như một điểm khởi đầu để tạo một dự án soạn thảo văn bản.

Trong phần này, bạn sẽ tìm hiểu những kiến ​​thức cơ bản về cách thêm thanh menu, menu và thanh công cụ vào các ứng dụng GUI của bạn với Python và PyQt.

Trước khi tiếp tục, bạn sẽ tạo một ứng dụng PyQt mẫu mà bạn sẽ sử dụng trong suốt hướng dẫn này. Trong mỗi phần, bạn sẽ thêm các tính năng và chức năng mới vào ứng dụng mẫu này. Ứng dụng này sẽ là một ứng dụng kiểu cửa sổ chính. Điều này có nghĩa là nó sẽ có thanh menu, thanh công cụ, thanh trạng thái và tiện ích trung tâm.

Mở trình soạn thảo mã hoặc IDE yêu thích của bạn và tạo một tệp Python có tên sample_app.py. Sau đó, thêm mã sau vào:

import sys

from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QLabel, QMainWindow

class Window(QMainWindow):
    """Main Window."""
    def __init__(self, parent=None):
        """Initializer."""
        super().__init__(parent)
        self.setWindowTitle("Python Menus & Toolbars")
        self.resize(400, 200)
        self.centralWidget = QLabel("Hello, World")
        self.centralWidget.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
        self.setCentralWidget(self.centralWidget)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    win = Window()
    win.show()
    sys.exit(app.exec_())

Bây giờ sample_app.py chứa tất cả mã mà bạn cần để tạo ứng dụng PyQt mẫu của mình. Trong trường hợp này, Window kế thừa từ QMainWindow. Như vậy, bạn đang xây dựng một ứng dụng kiểu cửa sổ chính.

Lưu ý: Thật không may, tài liệu chính thức của PyQt5 có một số phần chưa hoàn chỉnh. Để giải quyết vấn đề này, bạn có thể xem tài liệu PyQt4 hoặc tài liệu Qt gốc.

Trong trình khởi tạo lớp .__init__(), trước tiên bạn gọi trình khởi tạo của lớp cha bằng cách sử dụng super(). Sau đó, bạn đặt tiêu đề của cửa sổ bằng cách sử dụng .setWindowTitle() và thay đổi kích thước cửa sổ bằng cách sử dụng .resize().

Lưu ý: Nếu bạn không quen thuộc với các ứng dụng PyQt và cách tạo chúng, thì bạn có thể xem Python và PyQt: Xây dựng Máy tính bỏ túi GUI.

Tiện ích trung tâm của cửa sổ là một đối tượng QLabel mà bạn sẽ sử dụng để hiển thị thông báo phản hồi lại các hành động nhất định của người dùng. Các thông báo này sẽ hiển thị ở giữa cửa sổ. Để làm điều này, bạn gọi .setAlignment() trên đối tượng QLabel với một vài cờ liên kết.

Nếu bạn chạy ứng dụng từ dòng lệnh của mình, thì bạn sẽ thấy cửa sổ sau trên màn hình của bạn:

Ứng dụng mẫu PyQt

Như vậy bạn đã tạo được một ứng dụng kiểu cửa sổ chính với Python và PyQt. Bạn sẽ sử dụng ứng dụng mẫu này cho tất cả các ví dụ dưới đây trong bài viết này.

Tạo thanh menu

Trong ứng dụng kiểu cửa sổ chính PyQt, QMainWindow cung cấp một đối tượng QMenuBar trống theo mặc định. Để có quyền truy cập vào thanh menu này, bạn cần gọi .menuBar() của  đối tượng QMainWindow. Phương thức này sẽ trả về một thanh menu trống. Phần cha của thanh menu này sẽ là đối tượng cửa sổ chính của bạn.

Bây giờ quay lại ứng dụng mẫu của bạn và thêm phương thức sau vào định nghĩa của Window:

class Window(QMainWindow):
    # Snip...
    def _createMenuBar(self):
        menuBar = self.menuBar()

Đây là cách ưa thích để tạo thanh menu trong PyQt. Tại đây, biên menuBar sẽ giữ một thanh menu trống, thanh menu này sẽ là thanh menu của cửa sổ chính của bạn.

Lưu ý: Một thực tế phổ biến trong lập trình PyQt là sử dụng các biến cục bộ cho các đối tượng mà bạn sẽ không sử dụng hoặc không cần từ bên ngoài phương thức định nghĩa của chúng. Python thu thập tất cả các đối tượng nằm ngoài phạm vi, vì vậy bạn có thể nghĩ rằng menuBar trong ví dụ trên sẽ biến mất sau khi ._createMenuBar() trả về.

Sự thật là PyQt giữ một tham chiếu đến các đối tượng cục bộ chẳng hạn như menuBar sử dụng quyền sở hữu của chúng hoặc mối quan hệ cha-con. Nói cách khác, vì menuBar được sở hữu bởi đối tượng cửa sổ chính của bạn, nên Python sẽ không thể thu thập nó.

Một cách khác để thêm thanh menu vào các ứng dụng PyQt của bạn là tạo một đối tượng QMenuBar và sau đó đặt nó làm thanh menu của cửa sổ chính bằng cách sử dụng .setMenuBar(). Với ý nghĩ này, bạn cũng có thể viết ._createMenuBar() theo cách sau:

from PyQt5.QtWidgets import QMenuBar
# Snip...

class Window(QMainWindow):
    # Snip...
    def _createMenuBar(self):
        menuBar = QMenuBar(self)
        self.setMenuBar(menuBar)

Trong ví dụ trên, menuBar giữ một đối tượng QMenuBar và với cha được thiết lập là self thì điều này có nghĩa nó là cửa sổ chính của ứng dụng. Khi bạn có đối tượng thanh menu, bạn có thể sử dụng .setMenuBar() để thêm nó vào cửa sổ chính của mình. Cuối cùng, lưu ý rằng để ví dụ này hoạt động, trước tiên bạn cần import QMenuBar từ PyQt5.QWidgets.

Trong ứng dụng GUI, thanh menu sẽ được hiển thị ở các vị trí khác nhau tùy thuộc vào hệ điều hành cơ bản:

  • Windows: Ở đầu cửa sổ chính của ứng dụng, dưới thanh tiêu đề
  • macOS: Ở đầu màn hình
  • Linux: Ở đầu cửa sổ chính hoặc ở đầu màn hình, tùy thuộc vào môi trường máy tính của bạn

Bước cuối cùng để tạo thanh menu cho ứng dụng của bạn là gọi ._createMenuBar() từ trình khởi tạo của cửa sổ chính .__init__():

class Window(QMainWindow):
    """Main Window."""
    def __init__(self, parent=None):
        # Snip...
        self._createMenuBar()

Nếu bạn chạy ứng dụng mẫu của mình với những thay đổi mới này, thì bạn sẽ không thấy thanh menu hiển thị trên cửa sổ chính của ứng dụng. Đó là bởi vì thanh menu của bạn vẫn còn trống. Để xem thanh menu trên cửa sổ chính của ứng dụng, bạn cần tạo một số menu. Đó là những gì bạn sẽ học ở phần tiếp sau.

Thêm menu vào thanh menu

Menu là danh sách kéo xuống các tùy chọn menu mà bạn có thể kích hoạt bằng cách nhấp vào chúng hoặc bằng cách nhấn phím tắt. Có ít nhất ba cách để thêm menu vào đối tượng thanh menu trong PyQt:

  1. QMenuBar.addMenu(menu): thêm một đối tượng QMenu ( menu) vào một đối tượng trên thanh menu. Nó trả về hành động được liên kết với menu này.
  2. QMenuBar.addMenu(title): tạo và thêm một đối tượng QMenu mới với chuỗi (title) làm tiêu đề của nó vào thanh menu. Thanh menu có quyền sở hữu menu và phương thức trả về đối tượng QMenu mới.
  3. QMenuBar.addMenu(icon, title): tạo và thêm một đối tượng QMenu mới với một icon và một title vào một đối tượng thanh menu. Thanh menu có quyền sở hữu menu và phương thức trả về đối tượng QMenu mới.

Nếu bạn sử dụng tùy chọn đầu tiên, thì trước tiên bạn cần tạo các đối tượng QMenu tùy chỉnh của mình. Để làm điều đó, bạn có thể sử dụng một trong các hàm tạo sau:

  1. QMenu(parent)
  2. QMenu(title, parent)

Trong cả hai trường hợp, parent đều là QWidget và nó sẽ giữ quyền sở hữu của đối tượng QMenu. Thông thường, bạn sẽ đặt parent thành cửa sổ mà bạn sẽ sử dụng menu. Trong hàm tạo thứ hai, title sẽ giữ một chuỗi có văn bản mô tả tùy chọn menu.

Đây là cách bạn có thể thêm các menu FileEdit và Help vào thanh menu của ứng dụng mẫu của mình:

from PyQt5.QtWidgets import QMenu
# Snip...

class Window(QMainWindow):
    # Snip...
    def _createMenuBar(self):
        menuBar = self.menuBar()
        # Creating menus using a QMenu object
        fileMenu = QMenu("&File", self)
        menuBar.addMenu(fileMenu)
        # Creating menus using a title
        editMenu = menuBar.addMenu("&Edit")
        helpMenu = menuBar.addMenu("&Help")

Trong đoạn code trên, đầu tiên bạn import QMenu từ PyQt5.QtWidgets. Sau đó trong ._createMenuBar(), bạn thêm ba menu vào thanh menu của mình bằng cách sử dụng hai biến thể đầu tiên của .addMenu(). Biến thể thứ ba yêu cầu một đối tượng icon, nhưng bạn vẫn chưa học cách tạo và sử dụng các icon. Bạn sẽ tìm hiểu về cách sử dụng các biểu tượng trong phần Sử dụng các Icon và Tài nguyên trong PyQt.

Kết quả là bạn sẽ thấy rằng bây giờ bạn có một thanh menu như sau:

Thanh menu PyQt

Thanh menu của ứng dụng có các menu FileEdit và Help. Khi bạn nhấp vào các menu này, chúng không hiển thị danh sách tùy chọn menu kéo xuống. Đó là bởi vì bạn chưa thêm các tùy chọn menu. Bạn sẽ học cách thêm các tùy chọn menu vào menu trong phần Tạo menu bằng hành động.

Cuối cùng, hãy lưu ý rằng ký tự dấu và (&) mà bạn đưa vào tiêu đề của mỗi menu sẽ tạo ra các chữ cái được gạch chân trong màn hình thanh menu. Điều này sẽ được thảo luận chi tiết hơn trong phần Định nghĩa Phím tắt cho Tùy chọn Menu và Thanh công cụ.

Tạo thanh công cụ

Một thanh công cụ là một bảng điều khiển di chuyển giữ các nút và các widget khác để cung cấp các tùy chọn phổ biến nhất của một ứng dụng GUI truy cập nhanh. Các nút trên thanh công cụ có thể hiển thị các biểu tượng, văn bản hoặc cả hai để thể hiện tác vụ mà chúng thực hiện. Lớp cơ sở cho các thanh công cụ trong PyQt là QToolBar. Lớp này sẽ cho phép bạn tạo các thanh công cụ tùy chỉnh cho các ứng dụng GUI của mình.

Khi bạn thêm thanh công cụ vào ứng dụng kiểu cửa sổ chính, vị trí mặc định là ở đầu cửa sổ. Tuy nhiên, bạn có thể đặt thanh công cụ vào bất kỳ một trong bốn khu vực thanh công cụ sau:

Khu vực thanh công cụ Vị trí trong cửa sổ chính
Qt.LeftToolBarArea Bên trái
Qt.RightToolBarArea Bên phải
Qt.TopToolBarArea Bên trên
Qt.BottomToolBarArea Bên dưới

Các vùng trên thanh công cụ được định nghĩa là các hằng số trong PyQt. Nếu bạn cần sử dụng chúng, thì bạn phải import Qt từ PyQt5.QtCore và sau đó sử dụng các tên đủ điều kiện giống như trong Qt.LeftToolBarArea.

Có ba cách để thêm thanh công cụ vào ứng dụng cửa sổ chính của bạn trong PyQt:

  1. QMainWindow.addToolBar(title): tạo một đối tượng QToolBar mới và trống và đặt tiêu đề cửa sổ của nó thành title. Phương thức này chèn thanh công cụ vào vùng trên cùng của thanh công cụ và trả về thanh công cụ mới được tạo.
  2. QMainWindow.addToolBar(toolbar): chèn một đối tượng QToolBar (toolbar) vào vùng trên cùng của thanh công cụ.
  3. QMainWindow.addToolBar(area, toolbar): chèn một đối tượng QToolBar (toolbar) vào vùng thanh công cụ đã chỉ định (area). Nếu cửa sổ chính đã có các thanh công cụ, thì  toolbar sẽ được đặt sau thanh công cụ hiện có cuối cùng. Nếu toolbar đã tồn tại trong cửa sổ chính, thì nó sẽ chỉ được chuyển đến area.

Nếu bạn sử dụng một trong hai tùy chọn cuối cùng, thì bạn cần tự tạo thanh công cụ. Để thực hiện việc này, bạn có thể sử dụng một trong các hàm tạo sau:

  1. QToolBar(parent)
  2. QToolBar(title, parent)

Trong cả hai trường hợp, parent đều đại diện cho đối tượng QWidget sẽ giữ quyền sở hữu thanh công cụ. Thông thường, bạn sẽ đặt quyền sở hữu thanh công cụ cho cửa sổ mà bạn sẽ sử dụng thanh công cụ. Trong hàm tạo thứ hai, title sẽ là một chuỗi với tiêu đề cửa sổ của thanh công cụ. PyQt sử dụng tiêu đề cửa sổ này để xây dựng menu ngữ cảnh mặc định cho phép bạn ẩn và hiển thị các thanh công cụ của mình.

Bây giờ bạn có thể quay lại ứng dụng mẫu của mình và thêm phương thức sau vào Window:

from PyQt5.QtWidgets import QToolBar
# Snip...

class Window(QMainWindow):
    # Snip...
    def _createToolBars(self):
        # Using a title
        fileToolBar = self.addToolBar("File")
        # Using a QToolBar object
        editToolBar = QToolBar("Edit", self)
        self.addToolBar(editToolBar)
        # Using a QToolBar object and a toolbar area
        helpToolBar = QToolBar("Help", self)
        self.addToolBar(Qt.LeftToolBarArea, helpToolBar)

Đầu tiên, bạn import QToolBar từ PyQt5.QtWidgets. Sau đó, trong ._createToolBars() thì trước tiên bạn tạo thanh công cụ File bằng cách sử dụng .addToolBar() với tiêu đề. Tiếp theo, bạn tạo một đối tượng QToolBar với tiêu đề "Edit" và thêm nó vào thanh công cụ bằng cách sử dụng .addToolBar() mà không cần vượt qua vùng thanh công cụ. Trong trường hợp này, thanh công cụ Edit được đặt ở khu vực thanh công cụ trên cùng. Cuối cùng, bạn tạo thanh công cụ Help và đặt nó vào khu vực thanh công cụ bên trái bằng cách sử dụng Qt.LeftToolBarArea.

Bước cuối cùng để thực hiện công việc này là gọi ._createToolBars() từ trình khởi tạo của Window:

class Window(QMainWindow):
    """Main Window."""
    def __init__(self, parent=None):
        # Snip...
        self._createToolBars()

Lệnh gọi ._createToolBars() bên trong trình khởi tạo của Window sẽ tạo ra ba thanh công cụ và thêm chúng vào cửa sổ chính của bạn. Đây là giao diện ứng dụng của bạn bây giờ:

Thanh công cụ PyQt

Bây giờ bạn có hai thanh công cụ ngay bên dưới thanh menu và một thanh công cụ dọc theo bên trái của cửa sổ. Mỗi thanh công cụ có một đường chấm kép. Khi bạn di chuyển chuột qua các đường chấm, con trỏ sẽ chuyển thành bàn tay. Nếu bạn nhấp và giữ trên đường chấm chấm, thì bạn có thể di chuyển thanh công cụ đến bất kỳ vị trí hoặc khu vực thanh công cụ nào khác trên cửa sổ.

Nếu bạn nhấp chuột phải vào thanh công cụ, thì PyQt sẽ hiển thị menu ngữ cảnh cho phép bạn ẩn và hiển thị các thanh công cụ hiện có theo nhu cầu của bạn.

Như vậy là bạn có ba thanh công cụ trên cửa sổ ứng dụng của mình. Các thanh công cụ này vẫn trống — bạn sẽ cần thêm một số nút trên thanh công cụ để làm cho chúng hoạt động. Để làm điều đó, bạn có thể sử dụng các hành động PyQt, là các trường hợp của QAction. Bạn sẽ học cách tạo các hành động trong PyQt trong phần sau. Hiện tại, bạn sẽ học cách sử dụng các biểu tượng và các tài nguyên khác trong các ứng dụng PyQt của mình.

Sử dụng các Icon và tài nguyên trong PyQt

Các thư viện Qt bao gồm các hệ thống tài nguyên Qt, đây là một cách thuận tiện để thêm các tập tin nhị phân như biểu tượng, hình ảnh, tệp dịch thuật và các nguồn khác cho các ứng dụng của bạn.

Để sử dụng hệ thống tài nguyên, bạn cần liệt kê các tài nguyên của mình trong một tệp thu thập tài nguyên hoặc một tệp .qrc.qrc là một file XML có chứa các vị trí, hoặc đường dẫn, của mỗi tài nguyên trong hệ thống tập tin của bạn.

Giả sử rằng ứng dụng mẫu của bạn có một thư mục resources chứa các biểu tượng mà bạn muốn sử dụng trong GUI của ứng dụng. Bạn có các biểu tượng cho các tùy chọn như NewMOpen, v.v. Bạn có thể tạo một file .qrc chứa đường dẫn đến mỗi icon:

<!DOCTYPE RCC><RCC version="1.0">
<qresource>
    <file alias="file-new.svg">resources/file-new.svg</file>
    <file alias="file-open.svg">resources/file-open.svg</file>
    <file alias="file-save.svg">resources/file-save.svg</file>
    <file alias="file-exit.svg">resources/file-exit.svg</file>
    <file alias="edit-copy.svg">resources/edit-copy.svg</file>
    <file alias="edit-cut.svg">resources/edit-cut.svg</file>
    <file alias="edit-paste.svg">resources/edit-paste.svg</file>
    <file alias="help-content.svg">resources/help-content.svg</file>
</qresource>
</RCC>

Mỗi mục nhập <file> phải chứa đường dẫn đến tài nguyên trong hệ thống tệp của bạn. Các đường dẫn được chỉ định có liên quan đến thư mục chứa file .qrc. Trong ví dụ trên, thư mục resources cần nằm trong cùng thư mục với file .qrc.

alias là một thuộc tính tùy chọn xác định một tên thay thế ngắn mà bạn có thể sử dụng trong mã của mình để có quyền truy cập vào từng tài nguyên.

Khi bạn có tài nguyên cho ứng dụng của mình, bạn có thể chạy công cụ dòng lệnh là pyrcc5 với đích là file .qrcpyrcc5 được chuyển bằng PyQt và phải hoạt động đầy đủ trên môi trường Python của bạn sau khi bạn đã cài đặt PyQt.

pyrcc5 đọc một file .qrc và tạo ra một mô-đun Python có chứa mã nhị phân cho tất cả các tài nguyên của bạn:

$ pyrcc5 -o qrc_resources.py resources.qrc

Lệnh này sẽ đọc resources.qrc và tạo qrc_resources.py có chứa mã nhị phân cho mỗi tài nguyên. Bạn sẽ có thể sử dụng các tài nguyên đó trong mã Python của mình bằng cách import qrc_resources.

Lưu ý: Nếu xảy ra sự cố khi chạy pyrcc5, hãy đảm bảo rằng bạn đang sử dụng môi trường Python phù hợp. Nếu bạn cài đặt PyQt trong môi trường ảo Python, thì bạn sẽ không thể sử dụng pyrcc5 từ bên ngoài môi trường đó.

Đây là một đoạn mã qrc_resources.py tương ứng với resources.qrc:

# -*- coding: utf-8 -*-

# Resource object code
#
# Created by: The Resource Compiler for PyQt5 (Qt v5.9.5)
#
# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore

qt_resource_data = b"\
\x00\x00\x03\xb1\
\x3c\
\x73\x76\x67\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\
...

Với file qrc_resources.py ở trên, bạn có thể import nó vào ứng dụng của mình và tham chiếu đến từng tài nguyên bằng cách gõ dấu hai chấm (:) và sau đó import alias hoặc đường dẫn của nó. Ví dụ, để truy cập file-new.svg bằng bí danh của nó, bạn sẽ sử dụng chuỗi truy cập ":file-new.svg". Nếu bạn không có alias, bạn sẽ truy cập nó bằng đường dẫn của nó với chuỗi truy cập ":resources/file-new.svg".

Nếu bạn có bí danh, nhưng vì lý do nào đó mà bạn muốn truy cập vào một tài nguyên nhất định bằng đường dẫn của nó, thì bạn có thể phải xóa dấu hai chấm khỏi chuỗi truy cập để làm cho điều này hoạt động bình thường.

Để sử dụng các biểu tượng trong các hành động của mình, trước tiên bạn cần import mô-đun tài nguyên của mình:

import qrc_resources

Khi bạn đã nhập mô-đun có chứa tài nguyên của mình, bạn có thể sử dụng tài nguyên trong GUI của ứng dụng.

Lưu ý: Linters, trình chỉnh sửa và IDE có thể gắn cờ câu lệnh import ở trên là không được sử dụng vì mã của bạn sẽ không đưa vào bất kỳ hành vi sử dụng rõ ràng nào. Một số IDE thậm chí có thể đi xa hơn và tự động xóa dòng đó.

Trong những tình huống này, bạn phải ghi đè các đề xuất của linter, editor hoặc IDE của bạn và giữ import đó trong mã của bạn. Nếu không, ứng dụng của bạn sẽ không thể hiển thị tài nguyên của bạn.

Để tạo một biểu tượng bằng hệ thống tài nguyên, bạn cần khởi tạo QIcon, truyền bí danh hoặc đường dẫn đến hàm tạo của lớp như sau:

newIcon = QIcon(":file-new.svg")

Trong ví dụ trên, bạn tạo một đối tượng QIcon bằng file file-new.svg, nằm trong mô-đun tài nguyên của bạn. Điều này cung cấp một cách thuận tiện để sử dụng các icon và tài nguyên trong ứng dụng GUI của bạn.

Bây giờ quay lại ứng dụng mẫu của bạn và cập nhật dòng cuối cùng của ._createMenuBar() như sau:

from PyQt5.QtGui import QIcon

import qrc_resources
# Snip...

class Window(QMainWindow):
    # Snip...
    def _createMenuBar(self):
        menuBar = self.menuBar()
        # Using a QMenu object
        fileMenu = QMenu("&File", self)
        menuBar.addMenu(fileMenu)
        # Using a title
        editMenu = menuBar.addMenu("&Edit")
        # Using an icon and a title
        helpMenu = menuBar.addMenu(QIcon(":help-content.svg"), "&Help")

Để mã này hoạt động, trước tiên bạn cần import QIcon từ PyQt5.QtGui. Bạn cũng cần phải import qrc_resources. Trong dòng được đánh dấu cuối cùng, bạn thêm một icon để helpMenu sử dụng help-content.svg từ mô-đun tài nguyên của mình.

Nếu bạn chạy ứng dụng mẫu của mình với bản cập nhật này, thì bạn sẽ nhận được kết quả sau:

Thanh menu PyQt với các biểu tượng

Cửa sổ chính của ứng dụng hiện hiển thị một biểu tượng trên menu Help của ứng dụng. Khi bạn nhấp vào biểu tượng, menu sẽ hiển thị văn bản Help. Sử dụng các biểu tượng trong thanh menu không phải là một thực tế phổ biến, nhưng PyQt vẫn cho phép bạn làm điều đó.

Tạo Hành động cho Trình đơn Python và Thanh công cụ trong PyQt

Các hành động PyQt là các đối tượng đại diện cho một lệnh, hoạt động hoặc hành động nhất định trong một ứng dụng. Chúng hữu ích khi bạn cần cung cấp cùng một chức năng cho các thành phần GUI khác nhau, chẳng hạn như tùy chọn menu, nút trên thanh công cụ và phím tắt.

Bạn có thể tạo các hành động bằng cách khởi tạo QAction. Khi bạn đã tạo một hành động, bạn cần thêm nó vào một widget để có thể sử dụng nó trong thực tế.

Bạn cũng cần kết nối các hành động của mình với một số chức năng. Nói cách khác, bạn cần kết nối chúng với hàm hoặc phương thức mà bạn muốn chạy khi hành động được kích hoạt. Điều này sẽ cho phép ứng dụng của bạn thực hiện các hoạt động để phản hồi lại các hành động của người dùng trong GUI.

Các hành động khá linh hoạt. Chúng cho phép bạn sử dụng lại và giữ đồng bộ cùng một chức năng trên các tùy chọn menu, nút trên thanh công cụ và phím tắt. Điều này cung cấp một hành vi nhất quán trong suốt ứng dụng.

Ví dụ: người dùng có thể mong đợi ứng dụng thực hiện hành động tương tự khi họ nhấp vào tùy chọn menu Open… , nhấp vào nút Open thanh công cụ hoặc nhấn Ctrl+O trên bàn phím của họ.

QAction cung cấp một phần trừu tượng cho phép bạn theo dõi các phần tử sau:

  • Các tùy chọn văn bản trên menu
  • Văn bản trên các nút trên thanh công cụ
  • Mẹo trợ giúp về tùy chọn thanh công cụ (chú giải công cụ)
  • Mẹo trợ giúp này là gì
  • Mẹo trợ giúp trên thanh trạng thái (mẹo trạng thái)
  • Phím tắt được liên kết với các tùy chọn
  • Biểu tượng được liên kết với các tùy chọn menu và thanh công cụ
  • Trạng thái enabled hoặc disabled của hành động
  • Trạng thái on hoặc off của hành động

Để tạo các hành động, bạn cần phải khởi tạo QAction. Có ít nhất ba cách chung để làm điều này:

  1. QAction(parent)
  2. QAction(text, parent)
  3. QAction(icon, text, parent)

Trong cả ba trường hợp, parent đại diện cho đối tượng nắm giữ quyền sở hữu của hành động. Đối số này có thể là bất kỳ QObject nào. Một phương pháp hay nhất là tạo các hành động dưới dạng con của cửa sổ mà bạn sẽ sử dụng chúng.

Trong hàm tạo thứ hai và thứ ba, text giữ văn bản mà hành động sẽ hiển thị trên một tùy chọn menu hoặc một nút trên thanh công cụ.

Văn bản của một hành động hiển thị khác nhau trên các tùy chọn menu và các nút trên thanh công cụ. Ví dụ: văn bản &Open... hiển thị là Open… trong một tùy chọn menu và là Open trong nút trên thanh công cụ.

Trong hàm tạo thứ ba, icon là một đối tượng QIcon chứa biểu tượng của hành động. Biểu tượng này sẽ được hiển thị ở phía bên trái của văn bản trong một tùy chọn menu. Vị trí của biểu tượng trong nút thanh công cụ phụ thuộc vào thuộc tính của thanh công cụ .toolButtonStyle, có thể nhận một trong các giá trị sau:

Phong cách Hiển thị nút
Qt.ToolButtonIconOnly Chỉ biểu tượng
Qt.ToolButtonTextOnly Chỉ văn bản
Qt.ToolButtonTextBesideIcon Văn bản bên cạnh biểu tượng
Qt.ToolButtonTextUnderIcon Văn bản dưới biểu tượng
Qt.ToolButtonFollowStyle Tuân theo phong cách chung của nền tảng cơ bản

Bạn cũng có thể thiết lập văn bản và icon của hành động sử dụng các phương thức set tương ứng là .setText() và .setIcon().

Lưu ý: Để có danh sách đầy đủ các thuộc tính QAction, bạn có thể xem tài liệu.

Đây là cách bạn có thể tạo một số hành động cho ứng dụng mẫu của mình bằng cách sử dụng các hàm tạo khác nhau của QAction:

from PyQt5.QtWidgets import QAction
# Snip...

class Window(QMainWindow):
    # Snip...
    def _createActions(self):
        # Creating action using the first constructor
        self.newAction = QAction(self)
        self.newAction.setText("&New")
        # Creating actions using the second constructor
        self.openAction = QAction("&Open...", self)
        self.saveAction = QAction("&Save", self)
        self.exitAction = QAction("&Exit", self)
        self.copyAction = QAction("&Copy", self)
        self.pasteAction = QAction("&Paste", self)
        self.cutAction = QAction("C&ut", self)
        self.helpContentAction = QAction("&Help Content", self)
        self.aboutAction = QAction("&About", self)

Trong ._createActions(), bạn đã tạo một vài hành động cho ứng dụng mẫu của mình. Những hành động này sẽ cho phép bạn thêm các tùy chọn vào menu và thanh công cụ của ứng dụng.

Lưu ý rằng bạn đang tạo các hành động dưới dạng thuộc tính của đối tượng, vì vậy bạn có thể truy cập chúng từ bên ngoài ._createActions() bằng cách sử dụng self. Bằng cách này, bạn sẽ có thể sử dụng các hành động này trên cả menu và thanh công cụ của mình.

Lưu ý: Trong ._createActions(), bạn không sử dụng hàm tạo thứ ba QAction vì sử dụng các biểu tượng sẽ không hợp lý nếu bạn chưa thể nhìn thấy các hành động. Bạn sẽ học cách thêm các biểu tượng vào các hành động trong phần Tạo Thanh công cụ Bằng các Hành động.

Bước tiếp theo là gọi ._createActions() từ trình khởi tạo của Window:

class Window(QMainWindow):
    """Main Window."""
    def __init__(self, parent=None):
        # Snip...
        self._createActions()
        self._createMenuBar()
        self._createToolBars()

Nếu bạn chạy ứng dụng ngay bây giờ, thì bạn sẽ không thấy bất kỳ thay đổi nào trên GUI. Đó là bởi vì các hành động không được hiển thị cho đến khi chúng được thêm vào menu hoặc thanh công cụ. Lưu ý rằng bạn gọi ._createActions() trước khi gọi ._createMenuBar() và ._createToolBars() vì bạn sẽ sử dụng các tác vụ này trên menu và thanh công cụ của mình.

Nếu bạn thêm một hành động vào menu, thì hành động đó sẽ trở thành một tùy chọn menu. Nếu bạn thêm một hành động vào thanh công cụ, thì hành động đó sẽ trở thành một nút trên thanh công cụ. Đây là chủ đề cho một số phần tiếp theo dưới đây.

Thêm tùy chọn vào menu Python trong PyQt

Nếu bạn muốn thêm danh sách các tùy chọn vào một menu nhất định trong PyQt, thì bạn cần phải sử dụng các hành động. Cho đến nay, bạn đã học cách tạo các hành động bằng cách sử dụng các hàm tạo khác nhau của QAction. Các thao tác là một thành phần quan trọng khi tạo menu trong PyQt.

Trong phần này, bạn sẽ học cách sử dụng các hành động để điền vào menu các tùy chọn menu.

Tạo menu bằng các hành động

Để điền các menu với các tùy chọn menu, bạn sẽ sử dụng các hành động. Trong menu, một hành động được biểu thị dưới dạng tùy chọn ngang có ít nhất một văn bản mô tả như NewOpenSave, v.v. Các tùy chọn menu cũng có thể hiển thị một biểu tượng ở bên trái và chuỗi phím tắt, chẳng hạn như Ctrl+S ở bên phải của nó.

Bạn có thể thêm các hành động vào một đối tượng QMenu bằng cách sử dụng .addAction(). Phương thức này có một số biến thể. Hầu hết chúng được cho là tạo ra các hành động khi đang bay. Tuy nhiên, trong hướng dẫn này bạn sẽ phải sử dụng một biến thể của .addAction() mà QMenu thừa kế từ QWidget. Đây là dạng của biến thể này:

QWidget.addAction(action)

Đối số action đại diện cho đối tượng QAction mà bạn muốn thêm vào một đối tượng QWidget nhất định. Với biến thể này của .addAction(), bạn có thể tạo trước các hành động của mình và sau đó thêm chúng vào menu của bạn nếu cần.

Lưu ý: QWidget cũng cung cấp .addActions(). Phương thức này nhận một danh sách các hành động và gắn chúng vào đối tượng widget hiện tại.

Với công cụ này, bạn có thể bắt đầu thêm các hành động vào menu của ứng dụng mẫu của mình. Để thực hiện việc này, bạn cần cập nhật ._createMenuBar():

class Window(QMainWindow):
    # Snip...
    def _createMenuBar(self):
        menuBar = self.menuBar()
        # File menu
        fileMenu = QMenu("&File", self)
        menuBar.addMenu(fileMenu)
        fileMenu.addAction(self.newAction)
        fileMenu.addAction(self.openAction)
        fileMenu.addAction(self.saveAction)
        fileMenu.addAction(self.exitAction)
        # Edit menu
        editMenu = menuBar.addMenu("&Edit")
        editMenu.addAction(self.copyAction)
        editMenu.addAction(self.pasteAction)
        editMenu.addAction(self.cutAction)
        # Help menu
        helpMenu = menuBar.addMenu(QIcon(":help-content.svg"), "&Help")
        helpMenu.addAction(self.helpContentAction)
        helpMenu.addAction(self.aboutAction)

Với bản cập nhật code này cho ._createMenuBar(), bạn thêm rất nhiều tùy chọn vào ba menu của ứng dụng mẫu của mình.

Bây giờ menu File có bốn tùy chọn:

  1. New để tạo tệp mới
  2. Open… để mở một tệp hiện có
  3. Save để lưu các thay đổi đã thực hiện vào tệp
  4. Exit để đóng ứng dụng

Menu Edit có ba lựa chọn:

  1. Copy để sao chép nội dung vào khay nhớ tạm thời của hệ thống
  2. Paste để dán nội dung từ khay nhớ tạm thời của hệ thống
  3. Cut để cắt nội dung vào khay nhớ tạm thời của hệ thống

Menu Help có hai lựa chọn:

  1. Help Content để khởi chạy sổ tay trợ giúp của ứng dụng
  2. About hiển thị hộp thoại giới thiệu

Thứ tự các tùy chọn được hiển thị trong menu từ trên xuống dưới tương ứng với thứ tự mà bạn thêm các tùy chọn trong mã của mình.

Nếu bạn chạy ứng dụng, thì bạn sẽ thấy cửa sổ sau trên màn hình của mình:

Menu PyQt với các tùy chọn

Nếu bạn nhấp vào menu, thì ứng dụng sẽ hiển thị danh sách kéo xuống với các tùy chọn bạn đã thấy trước đó.

Tạo menu con

Đôi khi bạn cần sử dụng menu con trong các ứng dụng GUI của mình. Menu con là một menu lồng nhau hiển thị trong khi bạn di chuyển con trỏ qua một tùy chọn menu nhất định. Để thêm menu con vào ứng dụng, bạn cần gọi .addMenu() trên đối tượng menu vùng chứa.

Giả sử bạn cần thêm menu con trong menu Edit của ứng dụng mẫu. Menu con của bạn sẽ chứa các tùy chọn để tìm và thay thế nội dung, vì vậy bạn sẽ gọi nó là Find and Replace. Menu con này sẽ có hai tùy chọn:

  1. Find… để tìm một số nội dung
  2. Replace… để tìm và thay thế nội dung cũ bằng nội dung mới

Dưới đây là cách bạn có thể thêm menu con này vào ứng dụng mẫu của mình:

class Window(QMainWindow):
    # Snip...
    def _createMenuBar(self):
        # Snip...
        editMenu.addAction(self.cutAction)
        # Find and Replace submenu in the Edit menu
        findMenu = editMenu.addMenu("Find and Replace")
        findMenu.addAction("Find...")
        findMenu.addAction("Replace...")
        # Snip...

Trong dòng đầu tiên được đánh dấu, bạn thêm một đối tượng QMenu có văn bản "Find and Replace" vào menu Edit bằng cách sử dụng .addMenu() trên editMenu. Bước tiếp theo là điền vào menu con các hành động giống như bạn đã làm cho đến nay. Nếu bạn chạy lại ứng dụng mẫu của mình, thì bạn sẽ thấy một tùy chọn menu mới trong menu Edit:

Menu con PyQt

Menu Edit bây giờ có một mục gọi là Find and Replace. Khi bạn di chuột qua tùy chọn menu mới này, một menu con sẽ xuất hiện, hiển thị cho bạn hai tùy chọn mới, Find… và Replace… . Bây giờ bạn đã tạo được một menu con.

Thêm tùy chọn vào thanh công cụ trong PyQt

Thanh công cụ là một thành phần khá hữu ích khi nói đến việc xây dựng các ứng dụng GUI với Python và PyQt. Bạn có thể sử dụng thanh công cụ để giới thiệu cho người dùng một cách nhanh chóng để truy cập vào các tùy chọn thường được sử dụng nhất trong ứng dụng của bạn. Bạn cũng có thể thêm các widget như spin box và combo box vào thanh công cụ để cho phép người dùng sửa đổi trực tiếp một số thuộc tính và biến từ GUI của ứng dụng.

Trong một vài phần sau, bạn sẽ học cách thêm các tùy chọn hoặc nút vào thanh công cụ của mình bằng các thao tác và cả cách thêm tiện ích con vào thanh công cụ .addWidget().

Tạo thanh công cụ bằng các hành động

Để thêm các tùy chọn hoặc nút vào thanh công cụ, bạn cần gọi .addAction(). Trong phần này, bạn sẽ dựa vào biến thể của .addAction() mà QToolBar kế thừa từ QWidget. Vì vậy, bạn sẽ gọi .addAction() với một hành động làm đối số. Điều này sẽ cho phép bạn chia sẻ hành động của mình giữa các menu và thanh công cụ.

Khi bạn tạo các thanh công cụ, bạn sẽ thường gặp phải vấn đề là phải quyết định những tùy chọn nào để thêm vào chúng. Thông thường, bạn sẽ chỉ muốn thêm các hành động được sử dụng thường xuyên nhất vào các thanh công cụ của mình.

Nếu bạn quay lại ứng dụng mẫu của mình, thì bạn sẽ nhớ rằng bạn đã thêm ba thanh công cụ:

  1. File
  2. Edit
  3. Help

Trong thanh công cụ File, bạn có thể thêm các tùy chọn như sau:

  • New
  • Open
  • Save

Trong thanh công cụ Edit, bạn có thể thêm các tùy chọn sau:

  • Copy
  • Paste
  • Cut

Thông thường, khi bạn muốn thêm các nút vào thanh công cụ, thì trước tiên bạn chọn các biểu tượng mà bạn muốn sử dụng trên mỗi nút. Điều này không bắt buộc, nhưng đó là một phương pháp hay nhất. Khi bạn đã chọn các biểu tượng, bạn cần thêm chúng vào các hành động tương ứng của chúng.

Dưới đây là cách bạn có thể thêm các biểu tượng vào các hành động của ứng dụng mẫu của mình:

class Window(QMainWindow):
    # Snip...
    def _createActions(self):
        # File actions
        self.newAction = QAction(self)
        self.newAction.setText("&New")
        self.newAction.setIcon(QIcon(":file-new.svg"))
        self.openAction = QAction(QIcon(":file-open.svg"), "&Open...", self)
        self.saveAction = QAction(QIcon(":file-save.svg"), "&Save", self)
        self.exitAction = QAction("&Exit", self)
        # Edit actions
        self.copyAction = QAction(QIcon(":edit-copy.svg"), "&Copy", self)
        self.pasteAction = QAction(QIcon(":edit-paste.svg"), "&Paste", self)
        self.cutAction = QAction(QIcon(":edit-cut.svg"), "C&ut", self)
        # Snip...

Để thêm các biểu tượng vào hành động của mình, bạn cập nhật các dòng được đánh dấu. Trong trường hợp newAction, bạn sử dụng .setIcon(). Trong phần còn lại của các hành động, bạn sử dụng hàm tạo với một icon, một title và một đối tượng parent làm đối số.

Sau khi các hành động đã chọn của bạn có biểu tượng, bạn có thể thêm các hành động này vào thanh công cụ tương ứng của chúng bằng cách gọi .addAction() trên đối tượng thanh công cụ:

class Window(QMainWindow):
    # Snip...
    def _createToolBars(self):
        # File toolbar
        fileToolBar = self.addToolBar("File")
        fileToolBar.addAction(self.newAction)
        fileToolBar.addAction(self.openAction)
        fileToolBar.addAction(self.saveAction)
        # Edit toolbar
        editToolBar = QToolBar("Edit", self)
        self.addToolBar(editToolBar)
        editToolBar.addAction(self.copyAction)
        editToolBar.addAction(self.pasteAction)
        editToolBar.addAction(self.cutAction)

Với bản cập nhật code này cho ._createToolBars(), bạn thêm các nút cho các tùy chọn New , Open và Save vào thanh công cụ File. Bạn cũng thêm các nút cho các tùy chọn CopyPaste và Cut vào thanh công cụ Edit.

Lưu ý: Thứ tự các nút được hiển thị trên thanh công cụ từ trái sang phải tương ứng với thứ tự bạn thêm các nút trong mã của mình.

Nếu bạn chạy ứng dụng mẫu của mình ngay bây giờ, thì bạn sẽ thấy cửa sổ sau trên màn hình của mình:

Thanh công cụ PyQt có các nút

Ứng dụng mẫu hiện hiển thị hai thanh công cụ với một vài nút mỗi thanh. Người dùng của bạn có thể nhấp vào các nút này để truy cập nhanh vào các tùy chọn được sử dụng phổ biến nhất của ứng dụng.

Lưu ý: Khi bạn viết ._createToolBars() lại lần đầu tiên trong phần Tạo thanh công cụ, bạn đã tạo thanh công cụ trợ giúp. Thanh công cụ này nhằm hiển thị cách thêm thanh công cụ bằng cách sử dụng một biến thể khác của .addToolBar().

Trong bản cập nhật ở trên ._createToolBars(), bạn thoát khỏi thanh công cụ Trợ giúp chỉ để giữ cho ví dụ ngắn gọn và rõ ràng.

Lưu ý rằng, vì bạn chia sẻ các hành động giống nhau giữa các menu và thanh công cụ, nên các tùy chọn menu cũng sẽ hiển thị các biểu tượng ở phía bên trái của chúng, đây là một cải tiến lớn về năng suất và sử dụng tài nguyên. Đây là một trong những lợi thế của việc sử dụng các hành động PyQt để tạo menu và thanh công cụ với Python.

Thêm tiện ích vào Thanh công cụ

Trong một số trường hợp, bạn sẽ thấy hữu ích khi thêm các tiện ích cụ thể như hộp quay, hộp tổ hợp hoặc các tiện ích khác vào thanh công cụ. Một ví dụ phổ biến về điều này là các hộp tổ hợp mà hầu hết các trình xử lý văn bản sử dụng để cho phép người dùng thay đổi phông chữ của tài liệu hoặc kích thước của văn bản đã chọn.

Để thêm tiện ích con vào thanh công cụ, trước tiên bạn cần tạo tiện ích con, thiết lập các thuộc tính của nó và sau đó gọi đối tượng .addWidget() trên thanh công cụ sẽ truyền tiện ích con làm đối số.

Giả sử bạn muốn thêm một đối tượng QSpinBox vào thanh công cụ Edit của ứng dụng mẫu để cho phép người dùng thay đổi kích thước của thứ gì đó, thì đó có thể là kích thước phông chữ. Bạn cần cập nhật ._createToolBars() như sau:

from PyQt5.QtWidgets import QSpinBox
# Snip...

class Window(QMainWindow):
    # Snip...
    def _createToolBars(self):
        # Snip...
        # Adding a widget to the Edit toolbar
        self.fontSizeSpinBox = QSpinBox()
        self.fontSizeSpinBox.setFocusPolicy(Qt.NoFocus)
        editToolBar.addWidget(self.fontSizeSpinBox)

Ở đây, trước tiên bạn import lớp spin box. Sau đó, bạn tạo một đối tượng QSpinBox, đặt focusPolicy của nó thành Qt.NoFocus, và cuối cùng thêm nó vào thanh công cụ Edit của bạn.

Lưu ý: Trong đoạn mã trên, bạn đặt thuộc tính focusPolicy của spin box thành Qt.NoFocus vì nếu tiện ích này lấy tiêu điểm, thì các phím tắt của ứng dụng sẽ không hoạt động bình thường.

Bây giờ, nếu bạn chạy ứng dụng, thì bạn sẽ nhận được kết quả sau:

Thanh công cụ PyQt với các tiện ích

Tại đây, thanh công cụ Edit hiển thị một đối tượng QSpinBox mà người dùng của bạn có thể sử dụng để đặt kích thước phông chữ hoặc bất kỳ thuộc tính số nào khác trên ứng dụng của bạn.

Tùy chỉnh thanh công cụ

Các thanh công cụ PyQt khá linh hoạt và có thể tùy chỉnh. Bạn có thể đặt một loạt các thuộc tính trên một đối tượng thanh công cụ. Một số thuộc tính hữu ích nhất được hiển thị trong bảng sau:

Thuộc tính Tính năng được kiểm soát Cài đặt mặc định
allowedAreas Các khu vực thanh công cụ mà bạn có thể đặt một thanh công cụ nhất định Qt.AllToolBarAreas
floatable Cho dù bạn có thể kéo và thả thanh công cụ như một cửa sổ độc lập hay không True
floating Thanh công cụ có phải là một cửa sổ độc lập hay không True
iconSize Kích thước của các biểu tượng được hiển thị trên các nút trên thanh công cụ Được xác định bởi kiểu của ứng dụng
movable Cho dù bạn có thể di chuyển thanh công cụ trong khu vực thanh công cụ hoặc giữa các khu vực thanh công cụ True
orientation Hướng của thanh công cụ Qt.Horizontal

Tất cả các thuộc tính này đều có một phương thức setter liên quan. Ví dụ, bạn có thể sử dụng .setAllowedAreas() để đặt allowedAreas.setFloatable() để đặt floatable, v.v.

Bây giờ, giả sử bạn không muốn người dùng của mình di chuyển thanh công cụ File xung quanh cửa sổ. Trong trường hợp này, bạn có thể đặt movable thành False sử dụng .setMovable():

class Window(QMainWindow):
    # Snip...
    def _createToolBars(self):
        # File toolbar
        fileToolBar = self.addToolBar("File")
        fileToolBar.setMovable(False)
        # Snip...

Dòng được đánh dấu làm nên điều kỳ diệu ở đây. Giờ đây, người dùng của bạn không thể di chuyển thanh công cụ xung quanh cửa sổ của ứng dụng:

Tùy chỉnh Thanh công cụ PyQt

Các file trên thanh công cụ không hiển thị các đường chấm chấm đôi nữa, vì vậy người dùng sẽ không thể di chuyển nó. Lưu ý rằng thanh công cụ Edit vẫn có thể di chuyển được. Bạn có thể thay đổi các thuộc tính khác trên thanh công cụ của mình bằng cách sử dụng cùng cách tiếp cận này và tùy chỉnh chúng theo nhu cầu của bạn.

Tổ chức Menu và Tùy chọn Thanh công cụ

Để thêm rõ ràng và cải thiện trải nghiệm người dùng trong các ứng dụng GUI của mình, bạn có thể sắp xếp các tùy chọn menu và nút trên thanh công cụ bằng cách sử dụng dấu phân cách. Dấu phân cách hiển thị dưới dạng một đường ngang phân định hoặc ngăn cách, các tùy chọn menu hoặc như một đường thẳng đứng phân tách các nút trên thanh công cụ.

Để chèn hoặc thêm dấu phân tách vào đối tượng menu, menu con hoặc thanh công cụ, bạn có thể gọi .addSeparator() trên bất kỳ đối tượng nào trong số này.

Ví dụ: bạn có thể sử dụng dấu phân tách để tách tùy chọn Exit trên menu File của mình khỏi phần còn lại của các tùy chọn chỉ để làm rõ rằng Exit không liên quan về mặt logic với các tùy chọn còn lại trên menu. Bạn cũng có thể sử dụng dấu phân tách để tách tùy chọn Find and Replace trên menu Edit với phần còn lại của các tùy chọn theo cùng một quy tắc.

Đi tới ứng dụng mẫu của bạn và cập nhật ._createMenuBar()như sau:

class Window(QMainWindow):
    # Snip...
    def _createMenuBar(self):
        # File menu
        # Snip...
        fileMenu.addAction(self.saveAction)
        # Adding a separator
        fileMenu.addSeparator()
        fileMenu.addAction(self.exitAction)
        # Edit menu
        # Snip...
        editMenu.addAction(self.cutAction)
        # Adding a separator
        editMenu.addSeparator()
        # Find and Replace submenu in the Edit menu
        findMenu = editMenu.addMenu("Find and Replace")
        # Snip...

Trong dòng đầu tiên được đánh dấu, bạn thêm dấu phân cách giữa các tùy chọn Save và Exit trong menu File. Trong dòng được đánh dấu thứ hai, bạn thêm dấu phân tách để phân tách tùy chọn Find and Replace với phần còn lại của các tùy chọn trong menu Edit. Sau đây là cách những bổ sung này hoạt động:

Menu PyQt có dấu phân cách

Menu File của bạn bây giờ hiển thị một đường ngang ngăn cách tùy chọn Edit với phần còn lại của các tùy chọn trong trình đơn. Menu Edit cũng cho thấy một dấu phân tách ở cuối danh sách thả xuống của tùy chọn. Việc sử dụng nhất quán dấu phân cách có thể cải thiện một cách tinh tế độ rõ ràng của các menu và thanh công cụ, làm cho các ứng dụng GUI của bạn thân thiện hơn với người dùng.

Bài tập: bạn có thể đi tới định nghĩa ._createToolBars() và thêm dấu phân tách để phân tách đối tượng QSpinBox khỏi phần còn lại của các tùy chọn trên thanh công cụ.

Xây dựng menu ngữ cảnh hoặc menu bật lên trong PyQt

Menu ngữ cảnh, còn được gọi là menu bật lên, là một loại menu đặc biệt xuất hiện để phản ứng với các hành động nhất định của người dùng, chẳng hạn như nhấp chuột phải vào một tiện ích hoặc cửa sổ nhất định. Các menu này cung cấp một danh sách nhỏ các tùy chọn có sẵn trong ngữ cảnh nhất định của hệ điều hành hoặc ứng dụng mà bạn đang sử dụng.

Ví dụ: nếu bạn nhấp chuột phải vào màn hình của máy Windows, thì bạn sẽ nhận được một menu với các tùy chọn tương ứng với ngữ cảnh hoặc không gian cụ thể đó của hệ điều hành. Nếu bạn nhấp chuột phải vào không gian làm việc của một trình soạn thảo văn bản, thì bạn sẽ nhận được một menu ngữ cảnh hoàn toàn khác tùy thuộc vào trình soạn thảo bạn đang sử dụng.

Trong PyQt, bạn có một số tùy chọn để tạo menu ngữ cảnh. Trong hướng dẫn này, bạn sẽ tìm hiểu về hai trong số các tùy chọn đó:

  1. Đặt thuộc tính contextMenuPolicy trên các widget cụ thể thành Qt.ActionsContextMenu
  2. Xử lý sự kiện menu ngữ cảnh trên cửa sổ của ứng dụng thông qua contextMenuEvent()

Tùy chọn đầu tiên là tùy chọn phổ biến và thân thiện với người dùng nhất trong hai tùy chọn này, vì vậy bạn sẽ tìm hiểu về nó trước.

Tùy chọn thứ hai phức tạp hơn một chút và dựa vào việc xử lý các sự kiện của người dùng. Trong lập trình GUI, sự kiện là bất kỳ hành động nào của người dùng trên ứng dụng, chẳng hạn như nhấp vào nút hoặc menu, chọn một mục từ hộp tổ hợp, nhập hoặc cập nhật văn bản trong trường văn bản, nhấn một phím trên bàn phím, v.v. .

Tạo menu ngữ cảnh thông qua chính sách menu ngữ cảnh

Tất cả các thành phần hoặc tiện ích đồ họa PyQt có nguồn gốc từ việc QWidget kế thừa một thuộc tính được gọi là contextMenuPolicy. Thuộc tính này kiểm soát cách tiện ích con hiển thị menu ngữ cảnh. Một trong những giá trị thường được sử dụng nhất cho thuộc tính này là Qt.ActionsContextMenu. Điều này làm cho tiện ích hiển thị danh sách hành động bên trong của nó dưới dạng menu ngữ cảnh.

Để làm cho một tiện ích hiển thị menu ngữ cảnh dựa trên các hành động bên trong của nó, bạn cần thực hiện hai bước:

  1. Thêm một số hành động vào tiện ích bằng cách sử dụng QWidget.addAction().
  2. Đặt contextMenuPolicy thành Qt.ActionsContextMenu trên tiện ích mà đang sử dụng .setContextMenuPolicy().

Thiết lập contextMenuPolicy thành Qt.ActionsContextMenu sẽ làm cho các widget có hành động để hiển thị chúng trong một menu ngữ cảnh. Đây là một cách thực sự nhanh chóng để tạo menu ngữ cảnh với Python và PyQt.

Với kỹ thuật này, bạn có thể thêm menu ngữ cảnh vào tiện ích con trung tâm của ứng dụng mẫu và cung cấp cho người dùng cách truy cập nhanh vào một số tùy chọn của ứng dụng. Để làm điều đó, bạn có thể thêm phương thức sau vào Window:

class Window(QMainWindow):
    # Snip...
    def _createContextMenu(self):
        # Setting contextMenuPolicy
        self.centralWidget.setContextMenuPolicy(Qt.ActionsContextMenu)
        # Populating the widget with actions
        self.centralWidget.addAction(self.newAction)
        self.centralWidget.addAction(self.openAction)
        self.centralWidget.addAction(self.saveAction)
        self.centralWidget.addAction(self.copyAction)
        self.centralWidget.addAction(self.pasteAction)
        self.centralWidget.addAction(self.cutAction)

Trong ._createContextMenu(), trước tiên bạn đặt contextMenuPolicy thành Qt.ActionsContextMenu sử dụng phương thức setter .setContextMenuPolicy(). Sau đó, bạn thêm các hành động vào widget bằng cách sử dụng .addAction() như bình thường. Bước cuối cùng là gọi ._createContextMenu() từ trình khởi tạo của Window:

class Window(QMainWindow):
    """Main Window."""
    def __init__(self, parent=None):
        # Snip...
        self._createToolBars()
        self._createContextMenu()

Nếu bạn chạy ứng dụng mẫu của mình sau những lần bổ sung này, thì bạn sẽ thấy tiện ích con trung tâm của ứng dụng hiển thị menu ngữ cảnh khi bạn nhấp chuột phải vào nó:

Chính sách menu ngữ cảnh PyQt

Bây giờ ứng dụng mẫu của bạn có một menu ngữ cảnh bật lên bất cứ khi nào bạn nhấp chuột phải vào tiện ích trung tâm của ứng dụng. Tiện ích trung tâm trải dài để chiếm tất cả không gian có sẵn trong cửa sổ, vì vậy bạn không bị giới hạn khi nhấp chuột phải vào văn bản nhãn để xem menu ngữ cảnh.

Cuối cùng, vì bạn sử dụng các hành động giống nhau trong toàn bộ ứng dụng này nên các tùy chọn trên menu ngữ cảnh sẽ hiển thị cùng một bộ biểu tượng.

Tạo menu ngữ cảnh thông qua xử lý sự kiện

Một cách thay thế để tạo menu ngữ cảnh trong PyQt là xử lý sự kiện menu ngữ cảnh của cửa sổ chính của ứng dụng. Để thực hiện việc này, bạn cần thực hiện các bước sau:

  1. Ghi đè phương thức xử lý sự kiện .contextMenuEvent() trên đối tượng QMainWindow.
  2. Tạo một đối tượng QMenu truyền một widget (widget ngữ cảnh) làm cha của nó.
  3. Điền vào đối tượng menu bằng các hành động.
  4. Khởi chạy đối tượng menu bằng cách sử dụng QMenu.exec() với sự kiện .globalPos() làm đối số.

Cách quản lý menu ngữ cảnh này phức tạp hơn một chút. Tuy nhiên, nó cho phép bạn kiểm soát tốt những gì xảy ra khi trình đơn ngữ cảnh được gọi. Ví dụ: bạn có thể bật hoặc tắt các tùy chọn menu tùy theo trạng thái của ứng dụng, v.v.

Lưu ý: Trước khi tiếp tục phần này, bạn cần tắt mã bạn đã viết trong phần trước. Để làm điều đó, chỉ cần đi tới trình khởi tạo của Window và rào (comment) dòng mà gọi self._createContextMenu().

Đây là cách bạn có thể thực hiện lại menu ngữ cảnh của ứng dụng mẫu của mình, ghi đè phương thức xử lý sự kiện trên đối tượng cửa sổ chính:

class Window(QMainWindow):
    # Snip...
    def contextMenuEvent(self, event):
        # Creating a menu object with the central widget as parent
        menu = QMenu(self.centralWidget)
        # Populating the menu with actions
        menu.addAction(self.newAction)
        menu.addAction(self.openAction)
        menu.addAction(self.saveAction)
        menu.addAction(self.copyAction)
        menu.addAction(self.pasteAction)
        menu.addAction(self.cutAction)
        # Launching the menu
        menu.exec(event.globalPos())

Trong contextMenuEvent(), trước tiên bạn tạo một đối tượng QMenu (menu) với centralWidget làm tiện ích con của nó. Tiếp theo, bạn điền vào menu với các hành động sử dụng .addAction. Cuối cùng, bạn gọi .exec() trên đối tượng QMenu để hiển thị nó trên màn hình.

Đối số thứ hai của .contextMenuEvent() đại diện cho sự kiện mà phương thức bắt được. Trong trường hợp này, event sẽ là một cú nhấp chuột phải vào widget trung tâm của ứng dụng.

Trong lệnh gọi tới .exec(), bạn sử dụng event.globalPos() làm đối số. Phương thức này trả về vị trí chung của con trỏ chuột khi người dùng nhấp vào cửa sổ PyQt hoặc một tiện ích. Vị trí chuột sẽ cho biết vị trí .exec() trên cửa sổ để hiển thị menu ngữ cảnh.

Nếu bạn chạy ứng dụng mẫu của mình với những thay đổi mới này, thì bạn sẽ nhận được kết quả tương tự như bạn đã nhận được trong phần trước.

Tổ chức các tùy chọn menu ngữ cảnh

Không giống như trong menu và thanh công cụ, trong menu ngữ cảnh, bạn không thể sử dụng .addSeparator() để thêm dấu phân tách và phân tách trực quan các tùy chọn menu của mình theo mối quan hệ giữa chúng. Khi nói đến tổ chức menu ngữ cảnh, bạn cần tạo hành động phân tách:

separator = QAction(parent)
separator.setSeparator(True)

Lời gọi đến .setSeparator(True) trên đối tượng hành động sẽ biến hành động đó thành một dấu phân cách. Khi bạn có hành động phân tách, bạn cần chèn nó vào đúng vị trí trong menu ngữ cảnh bằng cách sử dụng QMenu.addAction().

Nếu bạn nhìn lại ứng dụng mẫu của mình, thì bạn có thể muốn tách các tùy chọn đến từ menu File với các tùy chọn đến từ menu Edit. Để làm điều đó, bạn có thể cập nhật .contextMenuEvent():

class Window(QMainWindow):
    # Snip...
    def contextMenuEvent(self, event):
        # Snip...
        menu.addAction(self.saveAction)
        # Creating a separator action
        separator = QAction(self)
        separator.setSeparator(True)
        # Adding the separator to the menu
        menu.addAction(separator)
        menu.addAction(self.copyAction)
        # Snip...

Trong hai dòng được đánh dấu đầu tiên, bạn tạo hành động phân tách. Trong dòng đánh dấu thứ ba, bạn thêm hành động phân tách vào menu bằng cách sử dụng .addAction().

Thao tác này sẽ thêm một đường ngang giữa tùy chọn File và tùy chọn Edit. Đây là kết quả bạn nhận được:

Menu ngữ cảnh PyQt có dấu phân cách

Bây giờ menu ngữ cảnh của bạn bao gồm một đường ngang phân tách trực quan các tùy chọn đến từ File với các tùy chọn đến từ Edit. Với điều này, bạn đã cải thiện chất lượng hình ảnh của menu và cung cấp trải nghiệm người dùng tốt hơn.

Kết nối Tín hiệu và Khe cắm trong Menu và Thanh công cụ

Trong PyQt, bạn sử dụng các tín hiệu (signal) và khe cắm (slot) để cung cấp chức năng cho các ứng dụng GUI của mình. Các widget PyQt phát ra tín hiệu mỗi khi một sự kiện như nhấp chuột, nhấn phím hoặc thay đổi kích thước cửa sổ xảy ra trên chúng.

Một khe cắm là một callable Python mà bạn có thể kết nối với tín hiệu của một widget để thực hiện một số hành động để đáp ứng với sự kiện người dùng. Nếu một tín hiệu và một khe cắm được kết nối, thì khe cắm sẽ được gọi tự động mỗi khi tín hiệu được phát ra. Nếu một tín hiệu nhất định không được kết nối với một khe cắm, thì sẽ không có gì xảy ra khi tín hiệu được phát ra.

Để làm cho các tùy chọn menu và nút trên thanh công cụ của bạn khởi chạy một số hoạt động khi người dùng nhấp vào chúng, bạn cần kết nối tín hiệu của các hành động cơ bản với một số vị trí tùy chỉnh hoặc được tích hợp sẵn.

Các đối tượng QAction có thể phát ra nhiều loại tín hiệu. Tuy nhiên, tín hiệu được sử dụng phổ biến nhất trong menu và thanh công cụ là .triggered(). Tín hiệu này được phát ra mỗi khi người dùng nhấp vào tùy chọn menu hoặc nút trên thanh công cụ. Để kết nối .triggered() với khe cắm, bạn có thể sử dụng cú pháp sau:

action = QAction("Action Text", parent)
# Connect action's triggered() with a slot
action.triggered.connect(slot)

Trong ví dụ này, slot là một Python có thể gọi được. Nói cách khác, slot có thể là một hàm, một phương thức, một lớp hoặc một thể hiện của một lớp mà thực thi .__call__().

Bạn đã có một tập hợp các hành động trong ứng dụng mẫu của mình. Bây giờ bạn cần mã hóa các vị trí mà bạn sẽ gọi mỗi khi người dùng nhấp vào tùy chọn menu hoặc nút trên thanh công cụ. Đi tới định nghĩa của Window và thêm các phương thức sau:

class Window(QMainWindow):
    # Snip...
    def newFile(self):
        # Logic for creating a new file goes here...
        self.centralWidget.setText("<b>File > New</b> clicked")

    def openFile(self):
        # Logic for opening an existing file goes here...
        self.centralWidget.setText("<b>File > Open...</b> clicked")

    def saveFile(self):
        # Logic for saving a file goes here...
        self.centralWidget.setText("<b>File > Save</b> clicked")

    def copyContent(self):
        # Logic for copying content goes here...
        self.centralWidget.setText("<b>Edit > Copy</b> clicked")

    def pasteContent(self):
        # Logic for pasting content goes here...
        self.centralWidget.setText("<b>Edit > Paste</b> clicked")

    def cutContent(self):
        # Logic for cutting content goes here...
        self.centralWidget.setText("<b>Edit > Cut</b> clicked")

    def helpContent(self):
        # Logic for launching help goes here...
        self.centralWidget.setText("<b>Help > Help Content...</b> clicked")

    def about(self):
        # Logic for showing an about dialog content goes here...
        self.centralWidget.setText("<b>Help > About...</b> clicked")

Các phương thức này sẽ đóng vai trò của các khe cắm của ứng dụng mẫu của bạn. Chúng sẽ được gọi mỗi khi người dùng nhấp vào tùy chọn menu hoặc nút thanh công cụ tương ứng.

Khi bạn có các khe cung cấp chức năng, bạn cần kết nối chúng với tín hiệu .triggered() của hành động. Bằng cách này, ứng dụng sẽ thực hiện các hành động để phản hồi lại các sự kiện của người dùng. Để tạo các kết nối này, hãy chuyển đến ứng dụng mẫu và thêm phương thức sau vào Window:

class Window(QMainWindow):
    # Snip...
    def _connectActions(self):
        # Connect File actions
        self.newAction.triggered.connect(self.newFile)
        self.openAction.triggered.connect(self.openFile)
        self.saveAction.triggered.connect(self.saveFile)
        self.exitAction.triggered.connect(self.close)
        # Connect Edit actions
        self.copyAction.triggered.connect(self.copyContent)
        self.pasteAction.triggered.connect(self.pasteContent)
        self.cutAction.triggered.connect(self.cutContent)
        # Connect Help actions
        self.helpContentAction.triggered.connect(self.helpContent)
        self.aboutAction.triggered.connect(self.about)

Phương thức này sẽ kết nối tất cả các tín hiệu .triggered() của hành động của bạn với các vị trí hoặc lệnh gọi lại tương ứng của chúng. Với bản cập nhật này, ứng dụng mẫu của bạn sẽ hiển thị thông báo trên đối tượng QLabel mà bạn đặt làm tiện ích con trung tâm cho bạn biết tùy chọn menu hoặc nút thanh công cụ nào đã được nhấp.

Trong trường hợp exitAction, bạn kết nối tín hiệu triggered() của nó với khe cắm tích hợp QMainWindow.close(). Bằng cách này, nếu bạn chọn File → Exit, thì ứng dụng của bạn sẽ đóng.

Cuối cùng, đi tới trình khởi tạo của Window và thêm một lời gọi đến ._connectActions():

class Window(QMainWindow):
    """Main Window."""
    def __init__(self, parent=None):
        # Snip...
        # self._createContextMenu()
        self._connectActions()

Với bản cập nhật cuối cùng này, bạn có thể chạy lại ứng dụng. Kết quả sẽ có dạng như sau:

Tín hiệu và khe cắm kết nối PyQt

Nếu bạn nhấp vào tùy chọn menu, nút thanh công cụ hoặc tùy chọn menu ngữ cảnh, thì nhãn ở giữa cửa sổ ứng dụng sẽ hiển thị thông báo cho biết hành động đã được thực thi. Chức năng này không hữu ích lắm ngoài bối cảnh học tập, nhưng nó cung cấp cho bạn ý tưởng về cách làm cho các ứng dụng của bạn thực hiện các hành động trong thế giới thực khi người dùng tương tác với GUI.

Cuối cùng, khi bạn chọn File → Exit, ứng dụng sẽ đóng vì tín hiệu .triggered() của exitAction được kết nối với khe cắm tích hợp QMainWindow.close().

Bài tập: Bạn có thể thử tạo các vị trí tùy chỉnh cho các tùy chọn Find… và Replace… trong menu con Find and Replace, sau đó kết nối tín hiệu .triggered() của chúng với các khe cắm đó để làm cho chúng hoạt động. Bạn cũng có thể thử nghiệm với các khe cắm mà bạn đã mã hóa trong phần này và thử làm những điều mới với chúng.

Đưa vào menu Python một cách động

Khi tạo menu cho một ứng dụng, đôi khi bạn sẽ cần điền các menu đó với các tùy chọn chưa được biết vào thời điểm bạn tạo GUI của ứng dụng. Ví dụ: menu Open Recent trong trình soạn thảo văn bản hiển thị danh sách các tài liệu đã mở gần đây. Bạn không thể điền menu này vào lúc tạo GUI của ứng dụng vì mỗi người dùng sẽ mở các tài liệu khác nhau và không có cách nào để biết trước thông tin này.

Trong trường hợp này, bạn cần điền động các menu để phản hồi lại các hành động của người dùng hoặc trạng thái của ứng dụng. QMenu có một tín hiệu được gọi là .aboutToShow() và bạn có thể kết nối với một khe cắm tùy chỉnh để tự động điền đối tượng menu trước khi nó được hiển thị trên màn hình.

Để tiếp tục phát triển ứng dụng mẫu của mình, giả sử bạn cần tạo menu con Open Recent trong File và tự động điền nó vào các tệp hoặc tài liệu đã mở gần đây. Để thực hiện việc này, bạn cần thực hiện các bước sau:

  1. Tạo menu con Open Recent trong File.
  2. Mã vùng tùy chỉnh tạo động các hành động để điền vào menu.
  3. Kết nối tín hiệu .aboutToShow() của menu với khe tùy chỉnh.

Đây là mã để tạo menu con:

class Window(QMainWindow):
    # Snip...
    def _createMenuBar(self):
        # Snip...
        fileMenu.addAction(self.openAction)
        # Adding an Open Recent submenu
        self.openRecentMenu = fileMenu.addMenu("Open Recent")
        fileMenu.addAction(self.saveAction)
        # Snip...

Trong dòng được đánh dấu, bạn thêm một menu con bên dưới menu File với tiêu đề "Open Recent". Menu con này chưa có các tùy chọn menu. Bạn cần tạo động các hành động để điền nó.

Bạn có thể thực hiện việc này bằng cách viết mã một phương thức để tạo động các hành động và thêm chúng vào menu con. Dưới đây là một ví dụ cho thấy logic chung mà bạn có thể sử dụng:

from functools import partial
# Snip...

class Window(QMainWindow):
    # Snip...
    def populateOpenRecent(self):
        # Step 1. Remove the old options from the menu
        self.openRecentMenu.clear()
        # Step 2. Dynamically create the actions
        actions = []
        filenames = [f"File-{n}" for n in range(5)]
        for filename in filenames:
            action = QAction(filename, self)
            action.triggered.connect(partial(self.openRecentFile, filename))
            actions.append(action)
        # Step 3. Add the actions to the menu
        self.openRecentMenu.addActions(actions)

Trong .populateOpenRecent(), trước tiên bạn xóa các tùy chọn cũ (nếu có) khỏi menu bằng cách sử dụng .clear(). Sau đó, bạn thêm logic để tạo và kết nối động các hành động. Cuối cùng, bạn thêm các thao tác vào menu bằng cách sử dụng .addActions().

Trong vòng lặp for, bạn sử dụng functools.partial() để kết nối tín hiệu .triggered() với .openRecentFile() vì bạn muốn chuyển filename làm đối số cho .openRecentFile(). Đây là một kỹ thuật khá hữu ích khi kết nối tín hiệu với một khe cắm cần thêm đối số. Để nó hoạt động, bạn cần phải import partial() từ functools.

Lưu ý: Logic trong bước thứ hai của ví dụ này không thực sự tải danh sách các tệp đã mở gần đây. Nó chỉ tạo ra một list trong năm tệp giả định với mục đích duy nhất là chỉ ra cách thực hiện kỹ thuật này.

Bước tiếp theo là kết nối tính hiệu .aboutToShow() của .openRecentMenu đến .populateOpenRecent(). Để làm điều đó, hãy thêm dòng sau vào cuối ._connectActions():

class Window(QMainWindow):
    # Snip...
    def _connectActions(self):
        # Snip...
        self.aboutAction.triggered.connect(self.about)
        # Connect Open Recent to dynamically populate it
        self.openRecentMenu.aboutToShow.connect(self.populateOpenRecent)

Trong dòng được đánh dấu, bạn kết nối tín hiệu .aboutToShow với .populateOpenRecent(). Điều này đảm bảo rằng menu của bạn được điền ngay trước khi nó được hiển thị.

Bây giờ bạn cần phải viết mã .openRecentFile(). Đây là phương thức mà ứng dụng của bạn sẽ gọi khi người dùng của bạn nhấp vào bất kỳ hành động nào được tạo động:

class Window(QMainWindow):
    # Snip...
    def openRecentFile(self, filename):
        # Logic for opening a recent file goes here...
        self.centralWidget.setText(f"<b>{filename}</b> opened")

Phương thức này sẽ cập nhật văn bản của đối tượng QLabel mà bạn sử dụng làm tiện ích con trung tâm của ứng dụng mẫu của bạn.

Dưới đây là cách menu con được tạo động của bạn hoạt động trong thực tế:

Các menu được tạo động PyQt

Khi con trỏ chuột của bạn di chuột qua menu Open Recent, menu sẽ phát ra tín hiệu .aboutToShow(). Điều này dẫn đến một lời gọi đến .populateOpenRecent(), tạo và kết nối các hành động. Nếu bạn nhấp vào tên tệp, thì bạn sẽ thấy nhãn trung tâm thay đổi tương ứng để hiển thị thông báo.

Định nghĩa phím tắt cho các tùy chọn menu và thanh công cụ

Phím tắt là một tính năng quan trọng trong ứng dụng GUI. Phím tắt là tổ hợp phím mà bạn có thể nhấn trên bàn phím để truy cập nhanh vào một số tùy chọn phổ biến nhất trong một ứng dụng.

Dưới đây là một số ví dụ về phím tắt:

  • Ctrl+C sao chép một cái gì đó vào khay nhớ tạm.
  • Ctrl+V dán nội dung nào đó từ khay nhớ tạm.
  • Ctrl+Z hoàn tác thao tác cuối cùng.
  • Ctrl+O mở tệp.
  • Ctrl+S lưu các tập tin.

Trong phần bên dưới, bạn sẽ tìm hiểu cách thêm phím tắt vào ứng dụng của mình để cải thiện năng suất và trải nghiệm của người dùng.

Sử dụng chuỗi khóa

Cho đến nay, bạn đã biết rằng QAction là một lớp đa năng để tạo các menu và thanh công cụ. QAction cũng cung cấp một cách xác định phím tắt thân thiện với người dùng cho các tùy chọn menu và các nút trên thanh công cụ của bạn.

QAction thực thi .setShortcut(). Phương thức này nhận một đối tượng QKeySequence làm đối số và trả về một phím tắt.

QKeySequence cung cấp một số hàm tạo. Trong hướng dẫn này, bạn sẽ tìm hiểu về hai trong số chúng:

  1. QKeySequence(ks, format) lấy một chuỗi khóa dựa trên chuỗi (ks) và một định dạng (format) làm đối số và tạo một đối tượng QKeySequence.
  2. QKeySequence(key) lấy một hằng StandardKey làm đối số và tạo một đối tượng QKeySequence khớp với chuỗi khóa đó trên nền tảng bên dưới.

Hàm tạo đầu tiên nhận ra các chuỗi sau:

  • "Ctrl"
  • "Shift"
  • "Alt"
  • "Meta"

Bạn có thể tạo chuỗi dựa trên chuỗi khóa khóa bằng cách kết hợp những chuỗi này với các chữ cái, dấu chấm câu, chữ số, tên phím (UpDownHome), và các phím chức năng ("Ctrl+S""Ctrl+5""Alt+Home""Alt+F4"). Bạn có thể truyền tối đa bốn trong số các chuỗi khóa dựa trên chuỗi này trong danh sách được phân tách bằng dấu phẩy.

Lưu ý: Để có tài liệu tham khảo đầy đủ về các phím tắt tiêu chuẩn trên các nền tảng khác nhau, hãy xem phần Phím tắt Chuẩn của tài liệu QKeySequence.

Hàm tạo thứ hai rất hữu ích nếu bạn đang phát triển một ứng dụng đa nền tảng và muốn tuân theo các phím tắt tiêu chuẩn cho từng nền tảng. Ví dụ: QKeySequence.Copy sẽ trả về phím tắt tiêu chuẩn của nền tảng để sao chép các đối tượng vào khay nhớ tạm.

Lưu ý: Để có tài liệu tham khảo đầy đủ về các khóa tiêu chuẩn mà PyQt cung cấp, hãy xem tài liệu QKeySequence.StandardKey.

Với nền tảng chung này về cách xác định phím tắt cho các tác vụ trong PyQt, bạn có thể quay lại ứng dụng mẫu của mình và thêm một số phím tắt. Để thực hiện việc này, bạn cần cập nhật ._createActions():

from PyQt5.QtGui import QKeySequence
# Snip...

class Window(QMainWindow):
    # Snip...
    def _createActions(self):
        # File actions
        # Snip...
        # Using string-based key sequences
        self.newAction.setShortcut("Ctrl+N")
        self.openAction.setShortcut("Ctrl+O")
        self.saveAction.setShortcut("Ctrl+S")
        # Edit actions
        # Snip...
        # Using standard keys
        self.copyAction.setShortcut(QKeySequence.Copy)
        self.pasteAction.setShortcut(QKeySequence.Paste)
        self.cutAction.setShortcut(QKeySequence.Cut)
        # Snip...

Trước tiên bạn cần import QKeySequence. Bên trong ._createActions(), ba dòng được đánh dấu đầu tiên tạo phím tắt bằng cách sử dụng chuỗi khóa dựa trên chuỗi. Đây là một cách nhanh chóng để thêm phím tắt vào thao tác của bạn. Trong ba dòng được đánh dấu thứ hai, bạn sử dụng QKeySequence để cung cấp các phím tắt tiêu chuẩn.

Nếu bạn chạy ứng dụng mẫu với những bổ sung này, thì các menu của bạn sẽ trông như thế này:

Phím tắt PyQt

Các tùy chọn menu của bạn hiện hiển thị một phím tắt ở phía bên phải của chúng. Nếu bạn nhấn bất kỳ tổ hợp phím nào trong số này, thì bạn sẽ thực hiện hành động tương ứng.

Sử dụng trình tăng tốc bàn phím

Có một giải pháp thay thế khác là bạn có thể sử dụng để thêm phím tắt hoặc trình tăng tốc bàn phím (keyboard accelerator), vào các tùy chọn menu của các ứng dụng của bạn.

Bạn có thể nhận thấy rằng khi bạn đặt văn bản cho một menu hoặc một tùy chọn menu, bạn thường chèn một ký hiệu và (&) vào văn bản. Bạn làm điều này để ký tự ngay sau dấu & sẽ được gạch dưới khi hiển thị trong văn bản của menu hoặc tùy chọn menu. Ví dụ: nếu bạn đặt một dấu & trước chữ F trong tiêu đề của menu File ("&File"), thì F sẽ được gạch dưới khi tiêu đề menu được hiển thị.

Lưu ý: Nếu bạn cần hiển thị ký hiệu & trên văn bản của menu, thì bạn cần sử dụng ký hiệu kép (&&) để thoát khỏi chức năng mặc định của ký hiệu này.

Trong trường hợp thanh menu, việc sử dụng dấu & cho phép bạn gọi bất kỳ menu nào bằng cách nhấn Alt kết hợp với chữ cái được gạch dưới trong tiêu đề menu.

Khi bạn đã khởi chạy menu, bạn có thể truy cập bất kỳ tùy chọn menu nào bằng cách nhấn vào chữ cái được gạch chân trong văn bản của tùy chọn. Ví dụ, trong File bạn có thể truy cập vào tùy chọn Exit bằng cách nhấn vào chữ E.

Lưu ý: Khi bạn sử dụng ký hiệu và để cung cấp trình tăng tốc bàn phím, hãy nhớ rằng bạn không thể có hai tùy chọn trong cùng một menu chia sẻ cùng một ký tự truy cập.

Nếu bạn đặt C làm ký tự truy cập cho tùy chọn Copy, thì bạn không thể đặt C làm ký tự truy cập cho tùy chọn Cut . Nói cách khác, trong một menu nhất định, các ký tự truy cập phải là duy nhất.

Tính năng này sẽ cho phép bạn cung cấp trình tăng tốc bàn phím nhanh cho những người dùng thích sử dụng bàn phím của họ để làm việc với các ứng dụng của bạn. Kỹ thuật này đặc biệt hữu ích cho các tùy chọn không cung cấp phím tắt rõ ràng.

Tạo menu và thanh công cụ: Các phương pháp và mẹo hay nhất

Khi bạn đang tạo menu và thanh công cụ bằng Python và PyQt, bạn nên tuân theo một số tiêu chuẩn thường được coi là thực tiễn tốt nhất trong lập trình GUI:

  1. Sắp xếp menu của bạn theo thứ tự được chấp nhận chung. Ví dụ: nếu bạn có menu File, thì nó phải là menu đầu tiên từ trái sang phải. Nếu bạn có menu Edit, thì nó sẽ là menu thứ hai. Help nên là menu ngoài cùng bên phải, v.v.
  2. Điền vào menu của bạn với các tùy chọn phổ biến cho loại ứng dụng bạn đang phát triển. Ví dụ, trong trình soạn thảo văn bản, menu File thường bao gồm các tùy chọn như NewOpenSave và Exit. Menu Edit thường bao gồm các tùy chọn như CopyPasteCut , Undo, v.v.
  3. Sử dụng các phím tắt tiêu chuẩn cho các tùy chọn phổ biến. Ví dụ: sử dụng Ctrl+C để CopyCtrl+V để PasteCtrl+X để Cut , v.v.
  4. Sử dụng dấu phân cách để phân tách các tùy chọn không liên quan. Những dấu hiệu trực quan này sẽ giúp ứng dụng của bạn điều hướng dễ dàng hơn.
  5. Thêm dấu chấm lửng (...) vào tiêu đề của các tùy chọn khởi chạy các hộp thoại bổ sung. Ví dụ: sử dụng Save As… thay vì Save As , About… thay vì About , v.v.
  6. Sử dụng ký hiệu và (&) trong các tùy chọn menu của bạn để cung cấp trình tăng tốc bàn phím thuận tiện. Ví dụ: "&Open" thay vì "Open""&Exit" thay vì "Exit".

Nếu bạn tuân theo các nguyên tắc này, thì các ứng dụng GUI của bạn sẽ cung cấp trải nghiệm quen thuộc và hấp dẫn cho người dùng của bạn.

Xây dựng thanh trạng thái Python trong PyQt

Một thanh trạng thái là một bảng điều khiển ngang mà thường được đặt ở dưới cùng của cửa sổ chính trong một ứng dụng GUI. Mục đích chính của nó là hiển thị thông tin về trạng thái hiện tại của ứng dụng. Thanh trạng thái cũng có thể được chia thành các phần để hiển thị các thông tin khác nhau trên mỗi phần.

Theo tài liệu Qt, có ba loại chỉ báo trạng thái:

  1. Các chỉ báo tạm thời chiếm gần như toàn bộ thanh trạng thái trong một thời gian ngắn để hiển thị văn bản chú giải công cụ, mục menu và các thông tin nhạy cảm về thời gian khác.
  2. Các chỉ báo bình thường chiếm một phần của thanh trạng thái và hiển thị thông tin mà người dùng có thể muốn tham chiếu định kỳ, chẳng hạn như số lượng từ trong trình xử lý văn bản. Chúng có thể được ẩn trong thời gian ngắn bởi các chỉ báo tạm thời.
  3. Các chỉ báo cố định luôn được hiển thị trên thanh trạng thái, ngay cả khi chỉ báo tạm thời được kích hoạt. Chúng được sử dụng để hiển thị thông tin quan trọng về chế độ hiện tại của ứng dụng, chẳng hạn như khi phím Caps Lock được nhấn.

Bạn có thể thêm thanh trạng thái vào ứng dụng kiểu cửa sổ chính của mình bằng một trong các tùy chọn sau:

  • Kêu gọi đối tượng .statusBar()của bạn QMainWindow.statusBar()tạo và trả về một thanh trạng thái trống cho cửa sổ chính.
  • Tạo một đối tượng QStatusBar, sau đó gọi .setStatusBar() trên cửa sổ chính của bạn với đối tượng thanh trạng thái làm đối số. Bằng cách đó, .setStatusBar() sẽ đặt đối tượng thanh trạng thái của bạn làm thanh trạng thái của cửa sổ chính.

Tại đây, bạn có hai cách triển khai thay thế để thêm thanh trạng thái vào ứng dụng mẫu của mình:

# 1. Using .statusBar()
def _createStatusBar(self):
    self.statusbar = self.statusBar()

# 2. Using .setStatusBar()
def _createStatusBar(self):
    self.statusbar = QStatusBar()
    self.setStatusBar(self.statusbar)

Cả hai cách triển khai đều tạo ra cùng một kết quả. Tuy nhiên, hầu hết thời gian, bạn sẽ sử dụng triển khai đầu tiên để tạo các thanh trạng thái của mình. Lưu ý rằng để triển khai thứ hai hoạt động, bạn cần phải import QStatusBar từ PyQt5.QtWidgets.

Thêm một trong các triển khai ở trên vào Window của ứng dụng của bạn và sau đó gọi ._createStatusBar() trong trình khởi tạo lớp. Với những bổ sung này, khi bạn chạy lại ứng dụng của mình, bạn sẽ thấy một cửa sổ như sau:

Thanh trạng thái PyQt

Ứng dụng của bạn bây giờ có một thanh trạng thái ở cuối cửa sổ chính. Thanh trạng thái gần như vô hình, nhưng nếu bạn nhìn kỹ, bạn sẽ nhận thấy một hình tam giác chấm nhỏ ở góc dưới bên phải của cửa sổ.

Hiển thị Thông báo Trạng thái Tạm thời

Mục đích chính của thanh trạng thái là hiển thị thông tin trạng thái cho người dùng ứng dụng của bạn. Để hiển thị thông báo trạng thái tạm thời trên thanh trạng thái, bạn cần sử dụng QStatusBar.showMessage(). Phương thức này có hai đối số sau:

  1. message giữ một thông báo chỉ báo trạng thái dưới dạng một chuỗi.
  2. timeout giữ số mili giây mà thông báo sẽ được hiển thị trên thanh trạng thái.

Nếu timeout là 0, là giá trị mặc định của nó, thì thông báo vẫn còn trên thanh trạng thái cho đến khi bạn gọi .clearMessage() hoặc .showMessage() trên thanh trạng thái.

Nếu có một thông báo đang hoạt động trên thanh trạng thái của bạn và bạn gọi .showMessage() bằng một tin nhắn mới, thì tin nhắn mới sẽ che khuất hoặc thay thế tin nhắn cũ.

Đi tới ứng dụng mẫu của bạn và thêm dòng sau vào ._createStatusBar():

class Window(QMainWindow):
    # Snip...
    def _createStatusBar(self):
        self.statusbar = self.statusBar()
        # Adding a temporary message
        self.statusbar.showMessage("Ready", 3000)

Dòng cuối cùng được highlight trong ._createStatusBar() sẽ làm cho ứng dụng của bạn hiển thị thông báo Ready trên thanh trạng thái của ứng dụng trong 3000mili giây:

Thông báo trạng thái PyQt

Khi bạn chạy ứng dụng, thanh trạng thái sẽ hiển thị thông báo Ready. Sau 3000mili giây, thông báo biến mất và thanh trạng thái bị xóa và sẵn sàng hiển thị thông báo trạng thái mới.

Hiển thị thông báo vĩnh viễn trong thanh trạng thái

Bạn cũng có thể hiển thị thông báo vĩnh viễn trên thanh trạng thái của ứng dụng. Một thông báo vĩnh viễn giữ cho người dùng được thông báo về một số trạng thái chung của ứng dụng. Ví dụ: trong trình soạn thảo văn bản, bạn có thể muốn hiển thị một thông báo cố định với thông tin về mã hóa văn bản của tệp hiện đang mở.

Để thêm thông báo cố định vào thanh trạng thái của bạn, bạn sử dụng một đối tượng QLabel để giữ thông báo. Sau đó, bạn thêm nhãn vào thanh trạng thái bằng cách gọi .addPermanentWidget(). Phương thức này sẽ thêm vĩnh viễn widget đã cho vào thanh trạng thái hiện tại. Cha của tiện ích con được đặt thành thanh trạng thái.

.addPermanentWidget() gồm hai đối số sau:

  1. widget giữ đối tượng widget mà bạn muốn thêm vào thanh trạng thái. Một số widget thường được sử dụng trên vai trò này là QLabelQToolButton, và QProgressBar.
  2. stretch được sử dụng để tính toán kích thước phù hợp cho tiện ích con khi thanh trạng thái phát triển và thu nhỏ lại. Nó mặc định là 0, có nghĩa là tiện ích con sẽ chiếm lượng không gian tối thiểu.

Hãy nhớ rằng một tiện ích vĩnh viễn sẽ không bị che khuất hoặc bị thay thế bởi các tin nhắn tạm thời. .addPermanentWidget() định vị các widget ở phía bên phải của thanh trạng thái.

Lưu ý: Bạn có thể sử dụng .addPermanentWidget() không chỉ để hiển thị thông báo vĩnh viễn trên thanh trạng thái của mình mà còn để hiển thị cho người dùng thanh tiến trình để theo dõi thời lượng của một hoạt động nhất định. Bạn cũng có thể cung cấp các nút trên thanh trạng thái để cho phép người dùng thay đổi các thuộc tính như mã hóa tệp trên trình soạn thảo văn bản.

Khi bạn sử dụng các loại tiện ích này trên thanh trạng thái, hãy cố gắng bám vào tiện ích được sử dụng phổ biến nhất cho loại ứng dụng mà bạn đang phát triển. Bằng cách này, người dùng của bạn sẽ cảm thấy như đang ở nhà.

Giả sử bạn muốn biến ứng dụng mẫu của mình thành một trình soạn thảo văn bản và bạn muốn thêm thông báo vào thanh trạng thái hiển thị thông tin về số từ của tệp hiện tại. Để làm điều đó, bạn có thể tạo một phương thức được gọi là .getWordCount() và sau đó thêm một thông báo cố định bằng cách sử dụng .addPermanentWidget() và một đối tượng QLabel:

class Window(QMainWindow):
    # Snip...
    def getWordCount(self):
        # Logic for computing the word count goes here...
        return 42

Phương thức này bổ sung logic để tính toán số lượng từ trong tài liệu hiện đang mở. Bây giờ, bạn có thể hiển thị thông tin này dưới dạng tin nhắn vĩnh viễn:

class Window(QMainWindow):
    # Snip...
    def _createStatusBar(self):
        self.statusbar = self.statusBar()
        # Adding a temporary message
        self.statusbar.showMessage("Ready", 3000)
        # Adding a permanent message
        self.wcLabel = QLabel(f"{self.getWordCount()} Words")
        self.statusbar.addPermanentWidget(self.wcLabel)

Trong hai dòng cuối cùng, đầu tiên bạn tạo một đối tượng QLabel (wcLabel) để chứa thông báo về số lượng từ. Để tạo tin nhắn, bạn sử dụng một chuỗi f, trong đó bạn chèn một lệnh gọi .getWordCount() để lấy thông tin về số lượng từ. Sau đó, bạn thêm nhãn vào thanh trạng thái bằng cách sử dụng .addPermanentWidget().

Trong trường hợp này, bạn tạo đối tượng QLabel dưới dạng thuộc tính thể hiện vì số lượng từ cần được cập nhật theo những thay đổi mà người dùng thực hiện đối với tệp hiện tại.

Nếu bạn chạy ứng dụng với bản cập nhật này, thì bạn sẽ thấy thông báo đếm từ ở phía bên phải của thanh trạng thái:

Thanh trạng thái PyQt với các tiện ích vĩnh viễn

Thanh trạng thái hiển thị thông báo cho người dùng biết về số lượng từ trong tệp hiện tại giả định. Khả năng hiển thị cho người dùng thông tin cố định hoặc các tùy chọn khác trên thanh trạng thái khá hữu ích và có thể giúp bạn cải thiện đáng kể trải nghiệm người dùng cho các ứng dụng của mình.

Thêm Mẹo trợ giúp vào Hành động

Khi nói đến việc tạo các ứng dụng GUI, điều quan trọng là phải cung cấp các mẹo trợ giúp cho người dùng của bạn về các chức năng cụ thể trên giao diện của ứng dụng. Mẹo trợ giúp là các thông báo ngắn cung cấp hướng dẫn nhanh cho người dùng về một số tùy chọn mà ứng dụng cung cấp.

Hành động PyQt cho phép bạn xác định các loại mẹo trợ giúp sau:

  • Mẹo trạng thái là các mẹo trợ giúp mà ứng dụng hiển thị trên thanh trạng thái khi người dùng di con trỏ chuột qua tùy chọn menu hoặc nút trên thanh công cụ. Theo mặc định, mẹo trạng thái chứa một chuỗi trống.
  • Chú giải công cụ là các mẹo trợ giúp mà ứng dụng hiển thị dưới dạng thông báo nổi khi người dùng di con trỏ chuột qua nút hoặc tiện ích trên thanh công cụ. Theo mặc định, chú giải công cụ chứa văn bản xác định hành động đang thực hiện.

Lưu ý: PyQt cũng cung cấp mẹo trợ giúp What's This mà bạn có thể sử dụng trong các tiện ích và hành động để hiển thị mô tả phong phú hơn về chức năng mà tiện ích hoặc hành động cung cấp. Tuy nhiên, chủ đề này nằm ngoài phạm vi của hướng dẫn này.

Để tìm hiểu cách hoạt động của các mẹo trợ giúp, bạn có thể thêm một số mẹo trạng thái và chú giải công cụ vào đơn đăng ký mẫu của mình. Đi tới ._createActions() và thêm các dòng mã sau:

class Window(QMainWindow):
    # Snip...
    def _createActions(self):
        # File actions
        # Snip...
        self.saveAction.setShortcut("Ctrl+S")
        # Adding help tips
        newTip = "Create a new file"
        self.newAction.setStatusTip(newTip)
        self.newAction.setToolTip(newTip)
        # Edit actions
        self.copyAction = QAction(QIcon(":edit-copy.svg"), "&Copy", self)
        # Snip...

Ba dòng được đánh dấu đặt thông báo "Create a new file" làm trạng thái và chú giải công cụ cho tùy chọn New. Nếu bạn chạy ứng dụng ngay bây giờ, thì bạn sẽ thấy rằng tùy chọn New hiển thị một mẹo trợ giúp ngắn nhưng mang tính mô tả cho người dùng:

Mẹo trợ giúp PyQt

Khi bạn nhấp vào menu File và giữ con trỏ chuột chạm vào New, bạn có thể thấy thông báo mẹo trợ giúp hiển thị ở bên trái của thanh trạng thái. Mặt khác, nếu bạn di chuyển con trỏ chuột qua nút Thanh công cụ New, thì bạn có thể thấy thông báo trên thanh trạng thái và cũng như một hộp nổi nhỏ bên cạnh con trỏ chuột.

Nói chung, thêm các mẹo trợ giúp vào menu và thanh công cụ Python của bạn được coi là một phương pháp hay nhất. Nó sẽ giúp người dùng điều hướng và tìm hiểu các ứng dụng GUI của bạn dễ dàng hơn.

Bài tập: Như một bài tập cuối cùng, bạn có thể tiếp tục thêm các mẹo trợ giúp vào phần còn lại của các hành động trong ứng dụng mẫu của mình và xem nó trông như thế nào sau khi bạn hoàn thành.

Phần kết luận

Menu , thanh công cụ và thanh trạng thái là các thành phần đồ họa phổ biến và quan trọng của hầu hết các ứng dụng GUI. Bạn có thể sử dụng chúng để cung cấp cho người dùng của mình một cách nhanh chóng để truy cập các tùy chọn và chức năng của ứng dụng. Chúng cũng làm cho các ứng dụng của bạn trông bóng bẩy, chuyên nghiệp và cung cấp trải nghiệm tuyệt vời cho người dùng của bạn.

Trong hướng dẫn này, bạn đã học cách:

  • Lập trình tạo menu, thanh công cụ và thanh trạng thái
  • Sử dụng các hành động PyQt để điền các menu và thanh công cụ của bạn
  • Cung cấp thông tin trạng thái bằng cách sử dụng thanh trạng thái

Trong quá trình này, bạn đã học được một số phương pháp lập trình tốt nhất đáng xem xét khi thêm và sử dụng menu, thanh công cụ và thanh trạng thái trong các ứng dụng GUI của mình.

» Tiếp: Tôi có thể làm gì với Python?
« Trước: f-Strings của Python 3: Cú pháp định dạng chuỗi được cải thiện
Các khóa học qua video:
Python SQL Server PHP C# Lập trình C Java HTML5-CSS3-JavaScript
Học trên YouTube <76K/tháng. Đăng ký Hội viên
Viết nhanh hơn - Học tốt hơn
Giải phóng thời gian, khai phóng năng lực
Copied !!!