PYQT TUTORIAL
Hướng dẫn sử dụng LangChain bằng Python Cách tự viết Context Manager trong Python Cách background của hình ảnh trong Python Cách làm việc với Notion API trong Python Cách đo Time chạy trong Python Cách sao chép danh sách (List) trong Python Cách kiểm tra List trống trong Python Cách sắp xếp dictionary theo giá trị trong Python PyQt là gì? Tạo một chương trình "Hello World". Tín hiệu và Khe (Signals & Slots) trong PyQt Cách sử dụng widget PyQt QLabel Cách sử dụng widget QPushButton của PyQt Cách sử dụng widget QLineEdit trong PyQt Cách sử dụng QVBoxLayout trong PyQt Cách sử dụng QGridLayout trong PyQt Cách sử dụng QFormLayout trong PyQt Cách sử dụng lớp QCheckBox trong PyQt Cách sử dụng lớp PyQt QRadioButton Sử dụng PyQt QComboBox để tạo Widget Combobox Cách sử dụng widget PyQt QSpinBox để tạo một spin box Cách tạo một widget nhập ngày sử dụng lớp PyQt QDateEdit Cách tạo một widget nhập giờ sử dụng lớp PyQt QTimeEdit Cách tạo một widget nhập ngày và giờ sử dụng PyQt QDateTimeEdit Cách sử dụng lớp PyQt QSlider để tạo một widget thanh trượt (slider). Cách dùng PyQt QWidget để làm container chứa các widget khác. Cách dùng lớp PyQt QTabWidget để tạo một widget dạng tab Cách dùng lớp PyQt QGroupBox để tạo một khung nhóm với tiêu đề Cách dùng lớp PyQt QTextEdit để tạo một widget cho phép chỉnh sửa Cách sử dụng lớp PyQt QProgressBar để tạo một widget progress bar Cách sử dụng lớp PyQt QMessageBox để tạo một hộp thoại Cách dùng lớp PyQt QInputDialog để tạo một hộp thoại nhập liệu Cách dùng lớp PyQt QFileDialog để tạo hộp thoại chọn file Cách sử dụng lớp QMainWindow của PyQt để tạo cửa sổ Cách sử dụng lớp PyQt QMenu để tạo menu Cách dùng lớp PyQt QToolBar để tạo các widget toolbar Cách dùng lớp QDockWidget của PyQt để tạo một widget Cách dùng lớp QStatusBar trong PyQt để tạo thanh status bar Cách sử dụng lớp QListWidget trong Python Cách sử dụng lớp QTableWidget để tạo một bảng Cách sử dụng lớp QTreeWidget của PyQt Cách sử dụng Qt Designer để thiết kế UX/UI trong PyQt. Cách sử dụng QThread trong PyQt Cách tạo các lớp QThreadPool đa luồng trong PyQt Cách hoạt động của Model/View trong PyQt Cách sử dụng Qt Style Sheets (QSS) trong PyQt. Chuyển đổi PyQt sang EXE trong PyQt
CÁC CHỦ ĐỀ
BÀI MỚI NHẤT
MỚI CẬP NHẬT

Thông báo: Download 4 khóa học Python từ cơ bản đến nâng cao tại đây.

Cách dùng lớp QDockWidget của PyQt để tạo một widget

Trong giao diện người dùng (GUI) với PyQt, lớp QDockWidget là một công cụ hữu ích để tạo ra các cửa sổ phụ có thể linh hoạt gắn vào hoặc tách rời khỏi cửa sổ chính. Với QDockWidget, bạn có thể cung cấp cho người dùng khả năng tùy chỉnh bố cục ứng dụng, cho phép di chuyển, ẩn/hiện, hoặc nổi các widget trong các khu vực khác nhau của cửa sổ chính. Trong bài viết này, mìnhsẽ tìm hiểu cách sử dụng QDockWidget để tạo ra các widget có thể gắn hoặc nổi, từ đó xây dựng giao diện người dùng linh hoạt và tương tác hơn trong PyQt.

test php

banquyen png
Bài viết này được đăng tại freetuts.net, không được copy dưới mọi hình thức.

Giới thiệu về lớp QDockWidget trong PyQt

Lớp QDockWidget cho phép bạn tạo một widget có thể được gắn (dock) bên trong QMainWindow hoặc có thể được tách rời để trở thành một cửa sổ riêng.

PyQt QDockWidget Editor Example png

Ví dụ về QDockWidget - Editor

Một QDockWidget có một thanh tiêu đề và một khu vực nội dung. Thanh tiêu đề hiển thị tiêu đề của widget, cùng với các nút như float (để tách rời) và close (để đóng widget).

Để tạo một dock widget và thêm nó vào cửa sổ chính, bạn thực hiện các bước sau:

Bài viết này được đăng tại [free tuts .net]

  1. Đầu tiên, tạo một dock widget bằng cách sử dụng lớp QDockWidget:

dock = QDockWidget(tên_widget)

Sau đó, thiết lập các tính năng cho dock widget bằng phương thức setFeatures() của đối tượng QDockWidget. Ví dụ, bạn có thể vô hiệu hóa tất cả các tính năng docking như sau:

dock.setFeatures(QDockWidget.DockWidgetFeature.NoDockWidgetFeatures)

Cuối cùng, thêm dock widget vào cửa sổ chính bằng phương thức addDockWidget(). Ví dụ, để thêm dock widget vào khu vực bên trái của cửa sổ chính, bạn làm như sau:

self.addDockWidget(Qt.DockWidgetArea.LeftDockWidgetArea, dock)

Lúc này, dock widget sẽ trống. Để thêm các widget con vào dock widget, bạn cần bọc các widget con bên trong một QWidget và sử dụng phương thức setWidget() của QDockWidget để thêm nó vào:

# Tạo một widget
widget = QWidget()

# Thêm các widget con vào widget chính
# ...

# Đặt widget vào dock widget
dock.setWidget(widget)

Nếu dock widget bị đóng, bạn có thể hiển thị lại nó bằng phương thức show():

dock.show()

Ví dụ tạo một dock widget cho ứng dụng Text Editor

Dưới đây là một ví dụ về việc tạo một dock widget cho chương trình Text Editor:

import sys
from pathlib import Path
from PyQt6.QtWidgets import (QApplication, QMainWindow, QTextEdit, QFileDialog, 
                             QMessageBox, QToolBar, QLabel, QDockWidget, QWidget, 
                             QFormLayout, QLineEdit, QPushButton)
from PyQt6.QtGui import QIcon, QAction
from PyQt6.QtCore import QSize, Qt

class MainWindow(QMainWindow):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.setWindowIcon(QIcon('./assets/editor.png'))
        self.setGeometry(100, 100, 500, 300)

        self.title = 'Editor'
        self.filters = 'Text Files (*.txt)'
        self.set_title()
        self.path = None

        # Khởi tạo QTextEdit cho việc chỉnh sửa văn bản
        self.text_edit = QTextEdit(self)
        self.text_edit.textChanged.connect(self.text_changed)
        self.setCentralWidget(self.text_edit)

        # Menu bar
        menu_bar = self.menuBar()

        file_menu = menu_bar.addMenu('&File')
        edit_menu = menu_bar.addMenu('&Edit')
        view_menu = menu_bar.addMenu('&View')
        help_menu = menu_bar.addMenu('&Help')

        # Tạo các action cho menu
        new_action = QAction(QIcon('./assets/new.png'), '&New', self)
        new_action.setStatusTip('Tạo tài liệu mới')
        new_action.setShortcut('Ctrl+N')
        new_action.triggered.connect(self.new_document)
        file_menu.addAction(new_action)

        open_action = QAction(QIcon('./assets/open.png'), '&Open...', self)
        open_action.triggered.connect(self.open_document)
        open_action.setStatusTip('Mở tài liệu')
        open_action.setShortcut('Ctrl+O')
        file_menu.addAction(open_action)

        save_action = QAction(QIcon('./assets/save.png'), '&Save', self)
        save_action.setStatusTip('Lưu tài liệu')
        save_action.setShortcut('Ctrl+S')
        save_action.triggered.connect(self.save_document)
        file_menu.addAction(save_action)

        file_menu.addSeparator()

        exit_action = QAction(QIcon('./assets/exit.png'), '&Exit', self)
        exit_action.setStatusTip('Thoát ứng dụng')
        exit_action.setShortcut('Alt+F4')
        exit_action.triggered.connect(self.quit)
        file_menu.addAction(exit_action)

        undo_action = QAction(QIcon('./assets/undo.png'), '&Undo', self)
        undo_action.setStatusTip('Hoàn tác')
        undo_action.setShortcut('Ctrl+Z')
        undo_action.triggered.connect(self.text_edit.undo)
        edit_menu.addAction(undo_action)

        redo_action = QAction(QIcon('./assets/redo.png'), '&Redo', self)
        redo_action.setStatusTip('Làm lại')
        redo_action.setShortcut('Ctrl+Y')
        redo_action.triggered.connect(self.text_edit.redo)
        edit_menu.addAction(redo_action)

        view_search_action = QAction(QIcon('./assets/search.png'),'Search',self)
        view_search_action.setStatusTip('Hiển thị dock tìm kiếm')
        view_search_action.setShortcut('Ctrl+F')
        view_search_action.triggered.connect(self.show_search_dock)
        view_menu.addAction(view_search_action)

        about_action = QAction(QIcon('./assets/about.png'), 'About', self)
        help_menu.addAction(about_action)
        about_action.setStatusTip('Thông tin ứng dụng')
        about_action.setShortcut('F1')

        # Thanh công cụ (toolbar)
        toolbar = QToolBar('Main ToolBar')
        self.addToolBar(toolbar)
        toolbar.setIconSize(QSize(16, 16))

        toolbar.addAction(new_action)
        toolbar.addAction(save_action)
        toolbar.addAction(open_action)
        toolbar.addSeparator()
        toolbar.addAction(undo_action)
        toolbar.addAction(redo_action)
        toolbar.addSeparator()
        toolbar.addAction(exit_action)

        # Thanh trạng thái (status bar)
        self.status_bar = self.statusBar()
        self.status_bar.showMessage('Sẵn sàng', 5000)
        self.character_count = QLabel("Chiều dài: 0")
        self.status_bar.addPermanentWidget(self.character_count)

        # Dock widget cho tìm kiếm
        self.dock = QDockWidget('Tìm kiếm')
        self.addDockWidget(Qt.DockWidgetArea.LeftDockWidgetArea, self.dock)

        search_form = QWidget()
        layout = QFormLayout(search_form)
        search_form.setLayout(layout)

        self.search_term = QLineEdit(search_form)
        self.search_term.setPlaceholderText("Nhập từ khóa tìm kiếm")
        layout.addRow(self.search_term)

        btn_search = QPushButton('Tìm', clicked=self.search)
        layout.addRow(btn_search)
        self.dock.setWidget(search_form)

        self.show()

    def show_search_dock(self):
        self.dock.show()

    def search(self):
        term = self.search_term.text()
        if not term:
            return

        cur = self.text_edit.find(term)
        if not cur:
            self.status_bar.showMessage(f'Không tìm thấy từ "{term}"', 2000)

    def set_title(self, filename=None):
        title = f"{filename if filename else 'Untitled'} - {self.title}"
        self.setWindowTitle(title)

    def confirm_save(self):
        if not self.text_edit.document().isModified():
            return True

        message = f"Bạn có muốn lưu thay đổi cho {self.path if self.path else 'Untitled'}?"
        MsgBoxBtn = QMessageBox.StandardButton.Save | QMessageBox.StandardButton.Discard | QMessageBox.StandardButton.Cancel

        button = QMessageBox.question(self, self.title, message, buttons=MsgBoxBtn)

        if button == QMessageBox.StandardButton.Cancel:
            return False

        if button == QMessageBox.StandardButton.Save:
            self.save_document()

        return True

    def new_document(self):
        if self.confirm_save():
            self.text_edit.clear()
            self.set_title()

    def write_file(self):
        self.path.write_text(self.text_edit.toPlainText())
        self.statusBar().showMessage('Tập tin đã được lưu...', 3000)

    def save_document(self):
        if self.path:
            return self.write_file()

        filename, _ = QFileDialog.getSaveFileName(self, 'Lưu tập tin', filter=self.filters)
        if not filename:
            return

        self.path = Path(filename)
        self.write_file()
        self.set_title(filename)

    def open_document(self):
        filename, _ = QFileDialog.getOpenFileName(self, filter=self.filters)
        if filename:
            self.path = Path(filename)
            self.text_edit.setText(self.path.read_text())
            self.set_title(filename)

    def quit(self):
        if self.confirm_save():
            self.destroy()

    def text_changed(self):
        text = self.text_edit.toPlainText()
        self.character_count.setText(f'Chiều dài: {len(text)}')

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    app.exec()

Cách hoạt động

Đầu tiên, tạo một dock widget và đặt tiêu đề của nó là ‘Search’:

self.dock = QDockWidget('Search')

Tiếp theo, thêm dock widget vào khu vực gắn bên trái cửa sổ chính:

self.addDockWidget(Qt.DockWidgetArea.LeftDockWidgetArea, dock)

Sau đó, tạo một form tìm kiếm sẽ được thêm vào dock widget:

search_form = QWidget()
layout = QFormLayout(search_form)
search_form.setLayout(layout)

self.search_term = QLineEdit(search_form)
self.search_term.setPlaceholderText("Enter a search term")
layout.addRow(self.search_term)

btn_search = QPushButton('Go', clicked=self.search)
layout.addRow(btn_search)

Sau đó, thêm form tìm kiếm vào dock widget:

self.dock.setWidget(search_form)

Cuối cùng, khi người dùng nhập một từ khóa tìm kiếm và nhấp vào nút "Go", chúng ta sử dụng phương thức find() của QTextEdit để tìm kiếm văn bản:

Kết bài

QDockWidget là một thành phần mạnh mẽ giúp bạn tạo các khu vực có thể gắn hoặc thả rời khỏi cửa sổ chính, cung cấp cho người dùng sự linh hoạt khi sử dụng ứng dụng. Với ví dụ trong hướng dẫn, chúng ta đã tạo thành công khu vực tìm kiếm bên trái cửa sổ chính và tích hợp thêm thanh công cụ, menu, cùng các tính năng chỉnh sửa như undo/redo để tăng cường trải nghiệm người dùng. Hãy thử chạy ứng dụng để kiểm tra cách các thành phần này hoạt động và xem cách dock widget có thể giúp cải thiện tính tương tác và hiệu quả của giao diện người dùng trong các ứng dụng PyQt.

Cùng chuyên mục:

Hướng dẫn xây dựng Command-Line Interface (CLI) bằng Quo trong Python

Hướng dẫn xây dựng Command-Line Interface (CLI) bằng Quo trong Python

Hướng dẫn toàn diện về module datetime trong Python

Hướng dẫn toàn diện về module datetime trong Python

Cách truy cập và thiết lập biến môi trường trong Python

Cách truy cập và thiết lập biến môi trường trong Python

Lớp dữ liệu (Data Classes) trong Python với decorator @dataclass

Lớp dữ liệu (Data Classes) trong Python với decorator @dataclass

Từ khóa yield trong Python

Từ khóa yield trong Python

Sự khác biệt giữa sort() và sorted() trong Python

Sự khác biệt giữa sort() và sorted() trong Python

Sử dụng Poetry để quản lý dependencies trong Python

Sử dụng Poetry để quản lý dependencies trong Python

Định dạng chuỗi Strings trong Python

Định dạng chuỗi Strings trong Python

Một tác vụ phổ biến khi làm việc với danh sách trong Python

Một tác vụ phổ biến khi làm việc với danh sách trong Python

Làm việc với các biến môi trường trong Python

Làm việc với các biến môi trường trong Python

Sự khác biệt giữa set() và frozenset() trong Python

Sự khác biệt giữa set() và frozenset() trong Python

Sự khác biệt giữa iterator và iterable trong Python

Sự khác biệt giữa iterator và iterable trong Python

Cách làm việc với file tarball/tar trong Python

Cách làm việc với file tarball/tar trong Python

Chuyển đổi kiểu dữ liệu trong Python

Chuyển đổi kiểu dữ liệu trong Python

Sự khác biệt giữa toán tử == và is trong Python

Sự khác biệt giữa toán tử == và is trong Python

Làm việc với file ZIP trong Python

Làm việc với file ZIP trong Python

Cách sử dụng ThreadPoolExecutor trong Python

Cách sử dụng ThreadPoolExecutor trong Python

Sự khác biệt giữa byte objects và string trong Python

Sự khác biệt giữa byte objects và string trong Python

Xử lý độ chính xác các hàm floor, ceil, round, trunc, format  trong Python

Xử lý độ chính xác các hàm floor, ceil, round, trunc, format trong Python

Cách lặp qua nhiều list với hàm zip() trong Python

Cách lặp qua nhiều list với hàm zip() trong Python

Top