Sự tương tác của một ứng dụng là quá trình qua lại giữa người dùng và hệ thống, nơi người dùng thực hiện các hành động thông qua giao diện và ứng dụng phản hồi lại những hành động đó. Quá trình này tạo nên một trải nghiệm người dùng mượt mà, giúp người dùng đạt được mục tiêu của mình khi sử dụng ứng dụng.
Các cơ chế trong PyQt để phản hồi lại tương tác của người dùng:
1. Signal và slot:
Signal: là tín hiệu thông báo rằng một sự kiện hoặc hành động đã xảy ra. Signal thường được gắn liền với một đối tượng (widget) cụ thể.
Ví dụ signal gắn với đối tượng QPushButton:
clicked(): phát ra khi nút được nhấn
pressed(): phát ra khi nút được nhấn xuống (nhưng chưa được thả ra)
released(): phát ra khi nút được thả ra (sau khi nhấn.
Ví dụ signal gắn với đối tượng QLineEdit:
textChanged(str): phát ra khi văn bản trong ô nhập liệu thay đổi
returnPressed(): Phát ra khi người dùng nhấn phím Enter trong ô nhập liệu.
Slot: là các hàm hoặc phương thức được gọi để xử lý một signal khi nó được phát ra. Slot có thể là các hàm được định nghĩa bởi người dùng hoặc các slot có sẵn trong PyQt.
Ví dụ sử dụng Signal - Slot:
from PyQt6.QtWidgets import QApplication, QWidget, QPushButton, QLabel
class MyApp(QWidget):
def __init__(self):
super().__init__()
self.label = QLabel('Button not clicked', self)
btn = QPushButton('Click me', self)
btn.clicked.connect(self.onButtonClick) # Kết nối signal 'clicked' với slot 'onButtonClick'
self.label.move(50, 50)
btn.move(50, 100)
self.setGeometry(300, 300, 200, 150)
self.setWindowTitle('Signal-Slot Example')
self.show()
def onButtonClick(self):
self.label.setText('Button clicked!')
if __name__ == '__main__':
app = QApplication([])
ex = MyApp()
app.exec()
Giải thích:
Tín hiệu clicked() của đối tượng nút nhấn được phát ra và kết hợp với phương thức onButtonClick(). Mục đích khi nhấn vào button sẽ đổi văn bản “Click me” sang “Button clicked!"
2. Event handler:
Event là các hành động cụ thể xảy ra trong ứng dụng (ví dụ: nhấn phím, di chuyển chuột) và được xử lý trực tiếp bởi các event handler trong widget.
Các phương thức phổ biến:
mousePressEvent: Xử lý sự kiện nhấn chuột.
keyPressEvent: Xử lý sự kiện nhấn phím.
closeEvent: Xử lý sự kiện đóng cửa sổ.
resizeEvent: Xử lý sự kiện thay đổi kích thước cửa sổ.
Ví dụ sử dụng event handler:
from PyQt6.QtWidgets import QApplication, QWidget
from PyQt6.QtCore import Qt
class MyApp(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setGeometry(300, 300, 300, 200)
self.setWindowTitle('Event Handling Example')
self.show()
def keyPressEvent(self, event):
if event.key() == Qt.Key.Key_Escape:
self.close() # Đóng cửa sổ khi nhấn phím Escape
if __name__ == '__main__':
app = QApplication([])
ex = MyApp()
app.exec()
Giải thích: trong sự kiện keyPressEvent kiểm tra nếu phím Esc được nhấn sẽ đóng cửa sổ.
Signal - Slot
ten_doi_tuong: Object name của các thành phần giao diện (có thể đặt tên trực tiếp trong Qt Designer)
signal: là các tín hiệu được phát ra từ widget
connect(): hàm kết nối signal với slot
mySlot: là phương thức viết ra để phản hồi tương tác của người dùng.
2. Event Handler
class MyApp(QWidget):
def __init__(self):
super().__init__()
def mousePressEvent(self, event):
# Code thực hiện khi nhấn chuột
print("Mouse clicked!")
def keyPressEvent(self, event):
# Code thực hiện khi nhấn phím
print(f"Key pressed: {event.text()}")
def resizeEvent(self, event):
# Code thực hiện khi thay đổi kích thước cửa sổ
print(f"Window resized to: {self.width()} x {self.height()}")
Event được viết dạng phương thức bên trong lớp, có 2 đối số self và event, event là một đối tượng đại diện cho sự kiện đang xảy ra trong ứng dụng, và nó chứa thông tin cần thiết để xử lý sự kiện đó. Mỗi loại sự kiện (chuột, phím, thay đổi kích thước) có một lớp sự kiện tương ứng với các thuộc tính và phương thức cụ thể để truy cập thông tin liên quan.
Cửa sổ thông báo trong PyQt là cửa sổ xuất hiện để xác nhận hoặc thông báo lỗi, tin nhắn đến người dùng. Nó có một số nút tiêu chuẩn, chẳng hạn như nút OK, nút Yes và nút No.
Thực hành khởi tạo cửa sổ hội thoại:
Thư viện PyQt cung cấp lớp QMessageBox để tạo hộp thoại như sau:
import sys
from PyQt6.QtWidgets import QApplication, QMessageBox
app = QApplication(sys.argv)
msg_box = QMessageBox()
msg_box.setWindowTitle("Lỗi")
msg_box.setIcon(QMessageBox.Icon.Warning)
msg_box.setText("Vui lòng nhập email hoặc số điện thoại!")
msg_box.setStyleSheet("background-color: #F8F2EC; color: #356a9c")
sys.exit(msg_box.exec())
Giải thích:
QMessageBox() để khởi tạo đối tượng hộp thoại.
setWindowTitle: thuộc tính hiển thị tên của cửa sổ
setIcon: cài đặt thuộc tính tạo icon hiển thị kèm hộp thoại. Có các icon lớp QMessageBox cung cấp như sau
QMessageBox.Icon.Warning:
QMessageBox.Icon.Question:
QMessageBox.Icon.Information:
QMessageBox.Icon.Critical:
setText: cài đặt thuộc tính hiển thị thông báo/tin nhắn lên cửa sổ
setStyleSheet: cài đặt thuộc tính style (làm đẹp) cho cửa sổ, bao gồm nhiều cặp thuộc tính, mỗi cặp thuộc tính cách nhau dấu chấm phẩy.
msg_box.exec(): phương thức thực thi vòng lặp và hiển thị msg_box, vòng lặp này sẽ tồn tại xuyên suốt chương trình đến khi cửa sổ bị đóng.
Giải code:Giải thích đoạn mã:
Thư viện và import:
from PyQt6.QtCore import Qt
: Import các module cần thiết từ PyQt6 để xử lý sự kiện.from PyQt6.QtWidgets import QApplication, QMainWindow, QMessageBox, QWidget
: Import các lớp cần thiết cho giao diện ứng dụng.from PyQt6 import uic
: Dùng để tải file.ui
(tạo từ Qt Designer) vào mã Python.import sys
: Import modulesys
để có thể thoát ứng dụng một cách an toàn.
Lớp
Login
:- Là một lớp kế thừa từ
QMainWindow
, biểu diễn cửa sổ đăng nhập. - Hàm
__init__()
khởi tạo và tải giao diện từ filelogin.ui
. self.btnRegister.clicked.connect(self.show_register)
: Kết nối nút "Đăng ký" với phương thứcshow_register
.self.btnLogin.clicked.connect(self.check_login)
: Kết nối nút "Đăng nhập" với phương thứccheck_login
.check_login()
: Kiểm tra thông tin đăng nhập:- Lấy dữ liệu từ các trường nhập liệu
txtEmail
vàtxtPassword
. - Nếu thông tin đúng (email là
"admin@example.com"
và mật khẩu là"admin"
):- Hiển thị cửa sổ chính (
main.show()
) và đóng cửa sổ đăng nhập (self.close()
).
- Hiển thị cửa sổ chính (
- Nếu thông tin sai:
- Hiển thị hộp thoại thông báo lỗi với nội dung "Vui lòng nhập kiểm tra lại thông tin đăng nhập".
- Lấy dữ liệu từ các trường nhập liệu
show_register()
: Mở cửa sổ đăng ký và đóng cửa sổ đăng nhập hiện tại.
- Là một lớp kế thừa từ
Lớp
Register
:- Biểu diễn cửa sổ đăng ký, kế thừa từ
QMainWindow
. - Tương tự như lớp
Login
, nhưng phương thứcshow_login()
sẽ mở lại cửa sổ đăng nhập và đóng cửa sổ đăng ký hiện tại.
- Biểu diễn cửa sổ đăng ký, kế thừa từ
Lớp
Main
:- Biểu diễn cửa sổ chính của ứng dụng sau khi đăng nhập thành công.
- Tải giao diện từ file
main.ui
.
Khởi chạy ứng dụng:
- Tạo đối tượng
QApplication
. - Tạo các đối tượng cho từng cửa sổ (
Login
,Register
,Main
). - Hiển thị cửa sổ đăng nhập đầu tiên (
login.show()
). - Bắt đầu vòng lặp sự kiện với
app.exec()
.
- Tạo đối tượng
Phân tích theo đề bài:
- Nút "Đăng nhập" (
btnLogin
): Kết nối với phương thứccheck_login
, kiểm tra xem giá trị của trường email và password có khớp với thông tin định sẵn không. Nếu đúng, chuyển sang cửa sổ chính, nếu sai, hiện hộp thoại cảnh báo với thông báo lỗi. - Nút "Đăng ký" (
btnRegister
): Mở cửa sổ đăng ký. - Hộp thoại lỗi (
QMessageBox
): Hiển thị thông báo khi nhập thông tin sai.
Cấu trúc này phù hợp với yêu cầu của giao diện: nếu thông tin đăng nhập sai, hiển thị một thông báo lỗi, nếu đúng, mở trang chính của ứng dụng.