Thông báo: Download 4 khóa học Python từ cơ bản đến nâng cao tại đây.
Cách sử dụng QVBoxLayout trong PyQt
Trong giao diện người dùng với PyQt, việc sắp xếp các thành phần giao diện một cách hợp lý và dễ quản lý là yếu tố quan trọng để tạo nên những ứng dụng trực quan và hiệu quả. QVBoxLayout là một công cụ mạnh mẽ trong PyQt giúp bạn tổ chức các widget theo chiều dọc một cách dễ dàng và linh hoạt. Trong bài viết này, bạn sẽ học cách sử dụng QVBoxLayout để sắp xếp các widget trong một ứng dụng PyQt, từ những bước cơ bản đến các kỹ thuật nâng cao như căn chỉnh, giãn nở, và phân bố không gian cho các widget.
Giới thiệu về PyQt QVBoxLayout
QVBoxLayout là một lớp trong PyQt dùng để chia widget cha thành các hộp nằm dọc và sắp xếp các widget con lần lượt từ trên xuống dưới.
Chương trình dưới đây minh họa cách sử dụng lớp QVBoxLayout:
import sys from PyQt6.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout class MainWindow(QWidget): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setWindowTitle('PyQt QVBoxLayout') # Tạo một layout layout = QVBoxLayout() self.setLayout(layout) # Tạo các nút và thêm chúng vào layout titles = ['Find Next', 'Find All', 'Close'] buttons = [QPushButton(title) for title in titles] for button in buttons: layout.addWidget(button) # Hiển thị cửa sổ self.show() if __name__ == '__main__': app = QApplication(sys.argv) window = MainWindow() sys.exit(app.exec())
Cách hoạt động:
Bài viết này được đăng tại [free tuts .net]
Đầu tiên, tạo một đối tượng QVBoxLayout:
layout = QVBoxLayout()
Tiếp theo, thiết lập layout cho MainWindow bằng cách gọi phương thức setLayout():
self.setLayout(layout)
Sau đó, định nghĩa một danh sách gồm ba chuỗi ký tự đại diện cho tiêu đề của các nút:
titles = ['Find Next', 'Find All', 'Close']
Tiếp theo, tạo ba nút QPushButton từ danh sách titles bằng cách sử dụng list comprehension:
buttons = [QPushButton(title) for title in titles]
Cuối cùng, thêm các nút vào layout bằng cách sử dụng vòng lặp for:
for button in buttons: layout.addWidget(button)
Căn chỉnh
QVBoxLayout sẽ kéo dãn các widget theo một cách nhất định. Ví dụ, QVBoxLayout sẽ kéo dãn các QPushButton theo chiều ngang nhưng không theo chiều dọc. Điều này có nghĩa là khi bạn tăng chiều rộng của widget cha, chiều rộng của tất cả các nút cũng sẽ tăng theo.
Tuy nhiên, khi bạn tăng chiều cao của widget cha, chiều cao của các nút sẽ không thay đổi. Quan trọng hơn, QVBoxLayout sẽ phân bổ không gian của widget cha đồng đều cho từng nút.
Căn dưới cùng
Để đẩy các nút xuống phía dưới của widget cha, bạn có thể thêm một khoảng trống dọc vào đầu layout bằng cách sử dụng phương thức addStretch() của đối tượng QVBoxLayout:
import sys from PyQt6.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout class MainWindow(QWidget): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setWindowTitle('PyQt QVBoxLayout') # Tạo một layout layout = QVBoxLayout() self.setLayout(layout) # Thêm khoảng trống dọc layout.addStretch() # Tạo các nút và thêm chúng vào layout titles = ['Find Next', 'Find All', 'Close'] buttons = [QPushButton(title) for title in titles] for button in buttons: layout.addWidget(button) # Hiển thị cửa sổ self.show() if __name__ == '__main__': app = QApplication(sys.argv) window = MainWindow() sys.exit(app.exec())
Nếu bạn tăng chiều cao của cửa sổ, khoảng trống dọc sẽ kéo dài đến hết QVBoxLayout và để lại không gian đủ cho các nút.
Căn trên cùng
Tương tự, bạn có thể thêm một khoảng trống dọc làm phần tử cuối cùng trong layout để đẩy các nút lên trên bằng cách gọi phương thức addStretch() sau khi thêm các nút vào layout:
import sys from PyQt6.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout class MainWindow(QWidget): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setWindowTitle('PyQt QVBoxLayout') # Tạo một layout layout = QVBoxLayout() self.setLayout(layout) # Tạo các nút và thêm chúng vào layout titles = ['Find Next', 'Find All', 'Close'] buttons = [QPushButton(title) for title in titles] for button in buttons: layout.addWidget(button) # Thêm khoảng trống dọc layout.addStretch() # Hiển thị cửa sổ self.show() if __name__ == '__main__': app = QApplication(sys.argv) window = MainWindow() sys.exit(app.exec())
Căn giữa
Để căn giữa các nút trong widget cha, bạn thêm một khoảng trống dọc ở đầu và một ở cuối của layout như sau:
import sys from PyQt6.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout class MainWindow(QWidget): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setWindowTitle('PyQt QVBoxLayout') # Tạo một layout layout = QVBoxLayout() self.setLayout(layout) # Thêm khoảng trống dọc layout.addStretch() # Tạo các nút và thêm chúng vào layout titles = ['Find Next', 'Find All', 'Close'] buttons = [QPushButton(title) for title in titles] for button in buttons: layout.addWidget(button) # Thêm khoảng trống dọc layout.addStretch() # Hiển thị cửa sổ self.show() if __name__ == '__main__': app = QApplication(sys.argv) window = MainWindow() sys.exit(app.exec())
Lưu ý rằng bạn có thể thêm một khoảng trống dọc giữa các widget trong QVBoxLayout. Ví dụ, đoạn mã sau thêm một khoảng trống dọc giữa nút thứ hai và nút thứ ba:
import sys from PyQt6.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout class MainWindow(QWidget): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setWindowTitle('PyQt QVBoxLayout') # Tạo một layout layout = QVBoxLayout() self.setLayout(layout) # Tạo các nút find_next_btn = QPushButton('Find Next') find_all_btn = QPushButton('Find All') close_btn = QPushButton('Find All') # Thêm nút đầu tiên và nút thứ hai vào layout layout.addWidget(find_next_btn) layout.addWidget(find_all_btn) # Thêm khoảng trống dọc layout.addStretch() # Thêm nút thứ ba layout.addWidget(close_btn) # Hiển thị cửa sổ self.show() if __name__ == '__main__': app = QApplication(sys.argv) window = MainWindow() sys.exit(app.exec())
Thiết lập hệ số giãn nở của layout trong PYQT
Đoạn mã sau hiển thị ba widget QLabel với các màu nền khác nhau (đỏ, xanh lá cây, và xanh dương) sử dụng QVBoxLayout:
import sys from PyQt6.QtWidgets import QApplication, QWidget, QLabel, QVBoxLayout class MainWindow(QWidget): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setWindowTitle('PyQt QVBoxLayout') # Tạo một layout layout = QVBoxLayout() self.setLayout(layout) # Tạo các label label_1 = QLabel() label_1.setStyleSheet('QLabel{background-color:red}') label_2 = QLabel() label_2.setStyleSheet('QLabel{background-color:green}') label_3 = QLabel() label_3.setStyleSheet('QLabel{background-color:blue}') layout.addWidget(label_1) layout.addWidget(label_2) layout.addWidget(label_3) # Hiển thị cửa sổ self.show() if __name__ == '__main__': app = QApplication(sys.argv) window = MainWindow() sys.exit(app.exec())
Lưu ý rằng chúng ta sử dụng style sheets để thiết lập màu nền cho các QLabel.
Không giống như các widget QPushButton, các widget QLabel sẽ kéo dãn cả theo chiều dọc và chiều ngang khi bạn thay đổi kích thước của widget cha.
Để phân bổ không gian cho từng widget QLabel theo tỷ lệ, bạn sử dụng phương thức setStretchFactor() với cú pháp như sau:
setStretchFactor(widget, factor)
Phương thức setStretchFactor() yêu cầu hai đối số: widget và hệ số giãn nở.
Ví dụ, để cấp cho widget label_3 gấp đôi không gian của hai widget còn lại, bạn thiết lập hệ số giãn nở cho widget label_3 là 2:
import sys from PyQt6.QtWidgets import QApplication, QWidget, QLabel, QVBoxLayout class MainWindow(QWidget): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setWindowTitle('PyQt QVBoxLayout') # Tạo một layout layout = QVBoxLayout() self.setLayout(layout) # Tạo các label label_1 = QLabel() label_1.setStyleSheet('QLabel{background-color:red}') label_2 = QLabel() label_2.setStyleSheet('QLabel{background-color:green}') label_3 = QLabel() label_3.setStyleSheet('QLabel{background-color:blue}') layout.addWidget(label_1) layout.addWidget(label_2) layout.addWidget(label_3) # Thiết lập hệ số giãn nở layout.setStretchFactor(label_1, 1) layout.setStretchFactor(label_2, 1) layout.setStretchFactor(label_3, 2) # Hiển thị cửa sổ self.show() if __name__ == '__main__': app = QApplication(sys.argv) window = MainWindow() sys.exit(app.exec())
Như bạn thấy, hệ số giãn nở xác định tỷ lệ không gian được phân bổ cho từng widget trong QVBoxLayout.
Kết bài
QVBoxLayout là một lớp layout mạnh mẽ và linh hoạt trong PyQt, cho phép bạn sắp xếp các widget theo chiều dọc một cách dễ dàng. Với khả năng giãn nở widget theo chiều ngang, chiều dọc hoặc cả hai, QVBoxLayout giúp tối ưu hóa không gian giao diện và tạo ra trải nghiệm người dùng mượt mà hơn. Bằng cách sử dụng các phương thức như setStretchFactor(), bạn có thể kiểm soát chính xác cách mà không gian được phân bổ cho từng widget, từ đó tạo ra giao diện cân đối và chuyên nghiệp. Sử dụng QVBoxLayout là một bước quan trọng để nâng cao chất lượng và hiệu quả của các ứng dụng PyQt.