Hướng dẫn dùng pyqt python



Các khóa học qua video:
Lập trình C Java C# SQL Server PHP HTML5-CSS3-JavaScript

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

  • Hiểu PyQt
  • Cài đặt PyQt
    • Cài đặt trên toàn hệ thống với pip
    • Cài đặt môi trường ảo với pip
    • Cài đặt dành riêng cho nền tảng
    • Cài đặt Anaconda
  • Tạo ứng dụng PyQt đầu tiên của bạn
  • Xem xét các kiểu mã
  • Học kiến ​​thức cơ bản về PyQt
    • Vật dụng
    • Người quản lý bố cục
    • Hộp thoại
    • Windows chính
    • Các ứng dụng
    • Vòng lặp sự kiện
    • Tín hiệu và khe cắm
  • Tạo máy tính với Python và PyQt
    • Tạo bộ xương
    • Hoàn thành Chế độ xem
    • Tạo bộ điều khiển cơ bản
    • Thực hiện mô hình
    • Hoàn thiện bộ điều khiển
    • Chạy Máy tính
  • Công cụ bổ sung
  • Phần kết luận
  • Đọc thêm


Ngay cả khi các ứng dụng web và di động dường như vượt qua thị trường phát triển phần mềm, vẫn có nhu cầu về các ứng dụng máy tính để bàn Giao diện người dùng đồ họa (GUI) truyền thống . Đối với các nhà phát triển quan tâm đến việc xây dựng các loại ứng dụng này bằng Python, có rất nhiều thư viện để lựa chọn, bao gồm Tkinter , wxPython , PyQt , PySide2 và các thư viện khác. Trong hướng dẫn này, bạn sẽ phát triển các ứng dụng GUI trên máy tính để bàn với Python và PyQt .

Bạn sẽ học cách:

  • Tạo giao diện người dùng đồ họa với Python và PyQt
  • Mang lại sức sống cho các ứng dụng của bạn bằng cách kết nối các sự kiện của người dùng với các hành động cụ thể
  • Tạo các ứng dụng GUI đầy đủ chức năng để giải quyết các vấn đề trong thế giới thực

Đối với hướng dẫn này, bạn sẽ tạo một ứng dụng máy tính với Python và PyQt. Điều này sẽ giúp bạn nắm bắt các nguyên tắc cơ bản và giúp bạn bắt đầu và sử dụng thư viện. Bạn có thể tải xuống mã nguồn cho dự án và tất cả các ví dụ trong hướng dẫn này bằng cách nhấp vào liên kết bên dưới:

Hiểu PyQt

PyQt là một liên kết Python cho Qt , là một tập hợp các thư viện C ++ và các công cụ phát triển bao gồm các bản tóm tắt độc lập với nền tảng cho Giao diện người dùng đồ họa (GUI), cũng như mạng, luồng, biểu thức chính quy , cơ sở dữ liệu SQL, SVG, OpenGL, XML và nhiều tính năng mạnh mẽ khác. Được phát triển bởi RiverBank Computing Ltd , PyQt có sẵn trong hai phiên bản:

  1. PyQt4 : một phiên bản được xây dựng dựa trên Qt 4.x và 5.x
  2. PyQt5 : một phiên bản chỉ được xây dựng dựa trên Qt 5.x

Mặc dù PyQt4 có thể được xây dựng dựa trên Qt 5.x, chỉ một tập hợp con nhỏ cũng tương thích với Qt 4.x sẽ được hỗ trợ. Điều này có nghĩa là nếu bạn quyết định sử dụng PyQt4, thì có thể bạn sẽ bỏ lỡ một số tính năng và cải tiến mới trong PyQt5. Xem tài liệu PyQt4 để biết thêm thông tin về chủ đề này.

Bạn sẽ bao gồm PyQt5 trong hướng dẫn này, vì nó có vẻ là tương lai của thư viện. Từ bây giờ, hãy đảm bảo coi bất kỳ đề cập nào về PyQt là tham chiếu đến PyQt5.

Lưu ý: Nếu bạn muốn đi sâu hơn vào sự khác biệt giữa hai phiên bản của thư viện, thì bạn có thể xem trang liên quan trên tài liệu PyQt5 .

PyQt5 dựa trên Qt v5 và bao gồm các lớp bao gồm Giao diện người dùng đồ họa cũng như xử lý XML, giao tiếp mạng, biểu thức chính quy, luồng, cơ sở dữ liệu SQL, đa phương tiện, duyệt web và các công nghệ khác có sẵn trong Qt. PyQt5 triển khai hơn một nghìn lớp Qt này trong một tập hợp các mô-đun Python , tất cả đều được chứa trong một gói Python cấp cao nhất được gọi PyQt5.

PyQt5 tương thích với Windows, Unix, Linux, macOS, iOS và Android. Đây có thể là một tính năng hấp dẫn nếu bạn đang tìm kiếm một thư viện hoặc khuôn khổ để phát triển các ứng dụng đa nền tảng với giao diện riêng trên mỗi nền tảng.

PyQt5 có sẵn dưới hai giấy phép:

  1. Giấy phép Thương mại Bờ sông
  2. Giấy phép Công cộng Chung (GPL), phiên bản 3

Giấy phép PyQt5 của bạn phải tương thích với giấy phép Qt của bạn. Nếu bạn sử dụng phiên bản GPL, thì mã của bạn cũng phải sử dụng giấy phép tương thích với GPL. Nếu bạn muốn sử dụng PyQt5 để tạo các ứng dụng thương mại, thì bạn sẽ cần giấy phép thương mại để cài đặt.

Lưu ý: Các Qt Công ty đã phát triển và hiện đang duy trì Python riêng của mình bắt buộc đối với các thư viện Qt. Thư viện Python được gọi là Qt cho Python và được coi là Qt chính thức cho Python. Trong trường hợp này, gói Python được gọi là PySide2.

Vì PyQt5 và PySide2 đều được xây dựng dựa trên Qt nên các API của chúng khá giống nhau, thậm chí gần như giống hệt nhau. Đó là lý do tại sao việc chuyển mã PyQt5 sang PySide2 có thể đơn giản như cập nhật một số lần nhập. Nếu bạn học một trong số họ, thì bạn sẽ có thể làm việc với người kia với nỗ lực tối thiểu. Nếu bạn muốn tìm hiểu sâu hơn về sự khác biệt giữa hai thư viện này, thì bạn có thể xem các tài nguyên sau:

  • PyQt so với Qt cho Python (PySide2)
  • Sự khác biệt giữa PyQt5 và PySide2 là gì?

Cài đặt PyQt

Bạn có một số tùy chọn để lựa chọn khi cài đặt PyQt trên hệ thống hoặc môi trường phát triển của mình. Tùy chọn đầu tiên là xây dựng từ nguồn. Điều này có thể hơi phức tạp, vì vậy bạn có thể muốn tránh nó nếu có thể. Nếu bạn thực sự cần xây dựng từ nguồn, thì bạn có thể xem tài liệu của thư viện đề xuất trong những trường hợp đó.

Lưu ý: Hầu hết các tùy chọn cài đặt mà bạn sẽ đề cập ở đây đều yêu cầu bạn có một bản cài đặt Python đang hoạt động. Nếu bạn cần tìm hiểu sâu hơn về cách cài đặt Python, hãy xem Cài đặt Python trên Windows, macOS và Linux .

Một lựa chọn khác sẽ là sử dụng bánh xe nhị phân . Bánh xe là một cách rất phổ biến để quản lý việc cài đặt các gói Python . Tuy nhiên, bạn cần lưu ý rằng bánh xe cho PyQt5 chỉ khả dụng cho Python 3.5 trở lên. Có bánh xe cho:

  • Linux (64-bit)
  • hệ điều hành Mac
  • Windows (32-bit và 64-bit)

Tất cả các bánh xe này đều bao gồm các bản sao của các thư viện Qt tương ứng, vì vậy bạn sẽ không cần phải cài đặt chúng một cách riêng biệt.

Tùy chọn thứ ba của bạn là sử dụng trình quản lý gói trên các bản phân phối Linux và macOS. Đối với Windows, bạn có thể sử dụng .exetệp nhị phân . Tùy chọn thứ tư và cuối cùng của bạn là sử dụng bản phân phối Anaconda để cài đặt PyQt trên hệ thống của bạn. Một số phần tiếp theo sẽ hướng dẫn bạn một số tùy chọn mà bạn có để cài đặt đúng cách PyQt5 từ các nguồn khác nhau và trên các nền tảng khác nhau.

Cài đặt trên toàn hệ thống với pip

Nếu bạn đang sử dụng Python 3.5 trở lên, thì bạn có thể cài đặt PyQt5 từ PyPI bằng cách chạy lệnh sau:

Với lệnh này, bạn sẽ cài đặt PyQt5 trong hệ thống cơ sở của mình. Bạn có thể bắt đầu sử dụng thư viện ngay sau khi quá trình cài đặt kết thúc. Tùy thuộc vào hệ điều hành của bạn, bạn có thể cần quyền root hoặc quản trị viên để cài đặt này hoạt động.

Cài đặt môi trường ảo với pip

Bạn có thể quyết định không cài đặt PyQt trực tiếp trên hệ thống cơ sở của mình để tránh làm xáo trộn cấu hình của bạn. Trong trường hợp này, bạn có thể sử dụng môi trường ảo Python . Sử dụng các lệnh sau để tạo một và cài đặt PyQt5:

$ python3 -m venv pyqtvenv
$ source pyqtvenv/bin/activate
(pyqtvenv) $ pip install pyqt5
Collecting pyqt5
...
Successfully installed PyQt5-sip-4.19.17 pyqt5-5.12.2

Tại đây, bạn tạo một môi trường ảo với venv. Sau khi bạn kích hoạt nó, bạn cài đặt pyqt5trong môi trường đó với pip install pyqt5. Thay thế cài đặt này là tùy chọn được khuyến nghị nhất nếu bạn muốn giữ cho hệ thống cơ sở của mình sạch sẽ.

Cài đặt dành riêng cho nền tảng

Trong hệ sinh thái Linux, một số bản phân phối bao gồm các gói nhị phân cho PyQt trong kho của chúng. Nếu điều này đúng với bản phân phối của bạn, thì bạn có thể cài đặt thư viện bằng trình quản lý gói của bản phân phối. Ví dụ: trên Ubuntu 18.04, bạn có thể sử dụng lệnh sau:

$ sudo apt install python3-pyqt5

Với lệnh này, bạn sẽ cài đặt PyQt5 và tất cả các phụ thuộc của nó trong hệ thống cơ sở của bạn, vì vậy bạn có thể sử dụng thư viện trong bất kỳ dự án GUI nào của mình. Lưu ý rằng đặc quyền root là cần thiết mà bạn gọi ở đây sudo.

Nếu bạn là người dùng Mac, thì bạn có thể cài đặt PyQt5 bằng trình quản lý gói Homebrew . Để làm điều đó, hãy mở một thiết bị đầu cuối và nhập lệnh sau:

Nếu mọi việc suôn sẻ, thì bạn sẽ có PyQt5 được cài đặt trên hệ thống cơ sở của mình, sẵn sàng để bạn sử dụng.

Lưu ý: Nếu bạn sử dụng trình quản lý gói trên Linux hoặc macOS, thì có khả năng bạn sẽ không nhận được phiên bản mới nhất của PyQt5. Một pipcài đặt sẽ tốt hơn nếu bạn muốn đảm bảo rằng bạn có phiên bản mới nhất.

Nếu bạn thích sử dụng Windows, nhưng bạn quyết định không sử dụng bánh xe nhị phân, thì đường dẫn của bạn thông qua cài đặt PyQt có thể khó khăn. Đó là bởi vì trang tải xuống PyQt5 dường như không còn cung cấp các tệp ( .exetệp) nhị phân Windows cho các phiên bản sau. Tuy nhiên, bạn có thể tìm thấy một số gói nhị phân Windows cho các phiên bản cũ hơn của thư viện tại trang dự án . Tệp nhị phân mới nhất được tạo cho PyQt v5.6 .

Nếu bạn thực sự cần cài đặt PyQt theo cách này, thì bạn sẽ cần:

  1. Xác định phiên bản Python bạn đang chạy và liệu bạn có Python 32 bit hay 64 bit
  2. Tải xuống phiên bản phù hợp để cài đặt Python của bạn
  3. Cài đặt PyQt bằng cách chạy .exetệp và làm theo hướng dẫn trên màn hình

Cài đặt Anaconda

Một giải pháp thay thế khác mà bạn có thể sử dụng để cài đặt PyQt là Anaconda , một bản phân phối Python cho khoa học dữ liệu. Anaconda là một gói và trình quản lý môi trường đa nền tảng và miễn phí, bao gồm một bộ sưu tập hơn 1.500 gói mã nguồn mở .

Anaconda cung cấp một trình hướng dẫn cài đặt thân thiện với người dùng mà bạn có thể sử dụng để cài đặt PyQt trên hệ thống của mình. Bạn có thể tải xuống phiên bản thích hợp cho nền tảng hiện tại của mình và làm theo hướng dẫn trên màn hình. Nếu bạn cài đặt phiên bản mới nhất của Anaconda, thì bạn sẽ có các gói sau:

  • pyqt: một ràng buộc Python cho bộ công cụ GUI đa nền tảng Qt (Giấy phép thương mại, GPL-2.0, GPL-3.0)
  • anyqt: lớp tương thích cho PyQt4 / PyQt5 (giấy phép GPL-3.0)
  • qtpy: một lớp trừu tượng PyQt5 / PyQt4 / PySide (giấy phép MIT)
  • pyqtgraph: một thư viện Python cho Đồ họa Khoa học (giấy phép MIT)

Với bộ gói này, bạn sẽ có tất cả những gì bạn cần để phát triển các ứng dụng GUI trên máy tính để bàn với Python và PyQt.

Lưu ý: Lưu ý rằng cài đặt Anaconda sẽ chiếm một lượng lớn dung lượng ổ đĩa. Nếu bạn cài đặt Anaconda chỉ để sử dụng các gói PyQt, thì bạn sẽ có một lượng lớn các gói và thư viện không sử dụng trên hệ thống của mình. Hãy ghi nhớ điều này khi bạn cân nhắc sử dụng phân phối Anaconda.

Tạo ứng dụng PyQt đầu tiên của bạn

Bây giờ bạn đã cài đặt PyQt hoạt động, bạn đã sẵn sàng để bắt đầu viết mã. Bạn sẽ tạo một "Xin chào, Thế giới!" ứng dụng với Python và PyQt. Dưới đây là các bước bạn sẽ làm theo:

  1. Nhập QApplicationvà tất cả các widget được yêu cầu từ PyQt5.QtWidgets.
  2. Tạo một phiên bản của QApplication.
  3. Tạo một phiên bản GUI của ứng dụng của bạn.
  4. Hiển thị GUI của ứng dụng của bạn.
  5. Chạy vòng lặp sự kiện của ứng dụng của bạn (hoặc vòng lặp chính).

Bạn có thể tải xuống mã nguồn cho các ví dụ mà bạn sẽ trình bày trong phần này tại liên kết bên dưới:

Bạn sẽ bắt đầu với một tệp có tên hello.pytrong thư mục làm việc hiện tại của mình:

# Filename: hello.py

"""Simple Hello World example with PyQt5."""

import sys

# 1. Import `QApplication` and all the required widgets
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QLabel
from PyQt5.QtWidgets import QWidget

Đầu tiên, bạn nhập sys, điều này sẽ cho phép bạn xử lý trạng thái thoát của ứng dụng. Sau đó, bạn nhập QApplicationQWidgetvà QLabeltừ QtWidgets, đó là một phần của gói gọi PyQt5. Bạn sẽ sử dụng những lần nhập này sau này, nhưng hiện tại, bạn đã hoàn thành bước một.

Đối với bước hai, bạn cần tạo một phiên bản QApplicationnhư sau:

# 2. Create an instance of QApplication
app = QApplication(sys.argv)

Tại đây, bạn tạo phiên bản của QApplication. Vì QApplicationđối tượng ( app) thực hiện quá nhiều lần khởi tạo, bạn nên tạo nó trước khi tạo bất kỳ đối tượng nào khác liên quan đến GUI. Đối QApplicationtượng cũng xử lý các đối số dòng lệnh phổ biến , vì vậy bạn cũng cần phải chuyển vào sys.argvdưới dạng đối số khi bạn tạo app.

Lưu ý: sys.argv chứa các listđối số dòng lệnh được truyền vào tập lệnh Python. Nếu ứng dụng của bạn không chấp nhận các đối số dòng lệnh, thì bạn có thể sử dụng giá trị trống listthay vì sys.argv. Đó là, bạn có thể làm một cái gì đó như thế nào app = QApplication([]).

Bước ba là tạo GUI của ứng dụng. Đối với ví dụ này, GUI của bạn sẽ dựa trên QWidget, là lớp cơ sở của tất cả các đối tượng giao diện người dùng trong PyQt. Hãy tạo GUI:

# 3. Create an instance of your application's GUI
window = QWidget()
window.setWindowTitle('PyQt5 App')
window.setGeometry(100, 100, 280, 80)
window.move(60, 15)
helloMsg = QLabel('

Hello World!

'
, parent=window) helloMsg.move(60, 15)

Trong mã này, windowlà một ví dụ của QWidget, cung cấp tất cả các tính năng bạn sẽ cần để tạo cửa sổ (hoặc biểu mẫu) của ứng dụng. Với .setWindowTitle(), bạn có thể thêm tiêu đề vào cửa sổ ứng dụng của mình. Trong trường hợp này, tiêu đề sẽ hiển thị là PyQt5 App.

Bạn có thể sử dụng .setGeometry()để xác định kích thước của cửa sổ và vị trí đặt nó trên màn hình của bạn. Hai tham số đầu tiên là xvà ytọa độ mà tại đó cửa sổ sẽ được đặt trên màn hình. Tham số thứ ba và thứ tư là widthvà heightcủa cửa sổ.

Mọi ứng dụng GUI chức năng đều cần các widget! Tại đây, bạn sử dụng một QLabelđối tượng ( helloMsg) để hiển thị thông báo Hello World!trên cửa sổ ứng dụng của mình. QLabelcác đối tượng có thể chấp nhận văn bản HTML, vì vậy bạn có thể sử dụng phần tử HTML '

Hello World!

'để định dạng văn bản dưới dạng h2tiêu đề. Cuối cùng, bạn sử dụng .move()để đặt helloMsgtại các tọa độ (60, 15)trên cửa sổ ứng dụng của bạn.

Lưu ý: Trong PyQt5, bạn có thể sử dụng bất kỳ tiện ích nào (một lớp con của QWidget) làm cửa sổ cấp cao nhất hoặc thậm chí là một nút hoặc một nhãn. Điều kiện duy nhất là bạn không vượt qua parentnó. Khi bạn sử dụng một widget như thế này, PyQt5 sẽ tự động cung cấp cho nó một thanh tiêu đề và biến nó thành một cửa sổ bình thường.

Mối quan hệ cha mẹ - con cái được sử dụng cho hai mục đích bổ sung:

  1. Tiện ích con không có parentlà cửa sổ chính hoặc cửa sổ cấp cao nhất .
  2. Một widget có parent(luôn là một widget khác) được chứa (hoặc hiển thị) bên trong nó parent.

Mối quan hệ này cũng xác định quyền sở hữu , với việc cha mẹ sở hữu con cái của họ. Mô hình quyền sở hữu PyQt5 đảm bảo rằng nếu bạn xóa parent(ví dụ: cửa sổ cấp cao nhất), thì tất cả các cửa sổ con (tiện ích con) của nó cũng sẽ tự động bị xóa.

Để tránh rò rỉ bộ nhớ, bạn phải luôn đảm bảo rằng bất kỳ QWidgetđối tượng nào cũng có parent, ngoại trừ các cửa sổ cấp cao nhất.

Bạn đã thực hiện xong bước ba, vì vậy hãy viết mã hai bước cuối cùng và chuẩn bị cho ứng dụng PyQt GUI đầu tiên của bạn sẵn sàng hoạt động:

# 4. Show your application's GUI
window.show()

# 5. Run your application's event loop (or main loop)
sys.exit(app.exec_())

Ở đây, bạn gọi .show()vào window. Cuộc gọi để .show()lên lịch một sự kiện sơn. Nói cách khác, nó thêm một sự kiện mới vào hàng đợi sự kiện của ứng dụng. Bạn đề cập đến vòng lặp sự kiện trong phần sau.

Lưu ý: Sự kiện sơn là một yêu cầu sơn các vật dụng tạo GUI.

Cuối cùng, bạn bắt đầu vòng lặp sự kiện của ứng dụng bằng cách gọi app.exec_(). Lệnh gọi tới .exec_()được gói gọn trong một lệnh gọi tới sys.exit(), cho phép bạn thoát khỏi Python một cách rõ ràng và giải phóng tài nguyên bộ nhớ khi ứng dụng kết thúc. Bạn có thể chạy hello.pybằng lệnh sau:

Khi bạn chạy tập lệnh này , bạn sẽ thấy một cửa sổ như sau:

Hướng dẫn dùng pyqt python

Tại đây, ứng dụng của bạn sẽ hiển thị một cửa sổ (dựa trên QWidget) với thông báo Hello World!trên đó. Để hiển thị thông báo, bạn sử dụng một QLabelchứa thông báo ở định dạng HTML.

Chúc mừng! Bạn đã tạo ứng dụng máy tính để bàn PyQt GUI đầu tiên của mình!

Xem xét các kiểu mã

Nếu bạn xem kỹ mã cho ứng dụng đầu tiên của mình, thì bạn sẽ nhận thấy rằng PyQt không tuân theo các quy ước đặt tên và kiểu mã PEP 8 . PyQt được xây dựng dựa trên Qt, được viết bằng C ++ và sử dụng kiểu đặt tên camelCase cho các hàm, phương thức và biến. Điều đó nói rằng, bạn sẽ cần quyết định kiểu đặt tên nào bạn sẽ sử dụng cho các ứng dụng PyQt GUI của riêng mình.

Về vấn đề này, PEP 8 tuyên bố rằng:

Các mô-đun và gói mới (bao gồm cả các khuôn khổ của bên thứ ba) nên được viết theo các tiêu chuẩn này, nhưng khi một thư viện hiện có có kiểu khác, thì tính nhất quán nội bộ được ưu tiên. ( Nguồn )

Ngoài ra, Zen of Python nói:

… Tính thực tế đánh bại sự thuần khiết. ( Nguồn )

Nếu bạn muốn viết mã nhất quán, thì bạn có thể muốn bỏ qua kiểu đặt tên PEP 8 và gắn bó với kiểu đặt tên PyQt. Đây là một quyết định mà bạn cần phải thực hiện. Trong hướng dẫn này, bạn sẽ làm theo kiểu đặt tên PyQt để có tính nhất quán.

Học kiến ​​thức cơ bản về PyQt

Bạn sẽ cần phải nắm vững các khái niệm cơ bản của logic PyQt để sử dụng hiệu quả thư viện để phát triển các ứng dụng GUI. Một số khái niệm này bao gồm:

  • Vật dụng
  • Trình quản lý bố cục
  • Hộp thoại
  • Cửa sổ chính
  • Các ứng dụng
  • Vòng lặp sự kiện
  • Tín hiệu và khe cắm

Các yếu tố này sẽ là nền tảng xây dựng các ứng dụng PyQt GUI của bạn. Hầu hết chúng được biểu diễn dưới dạng các lớp Python. PyQt5.QtWidgetslà mô-đun cung cấp tất cả các lớp này. Những yếu tố này cực kỳ quan trọng, vì vậy bạn sẽ đề cập đến chúng trong một vài phần tiếp theo.

Vật dụng

QWidgetlà lớp cơ sở cho tất cả các đối tượng giao diện người dùng hoặc widget . Đây là các thành phần đồ họa hình chữ nhật mà bạn có thể đặt trên cửa sổ ứng dụng của mình để xây dựng GUI. Các widget chứa một loạt các thuộc tính và phương thức cho phép bạn mô hình hóa sự xuất hiện và hành vi của chúng. Họ cũng có thể vẽ đại diện của mình trên màn hình.

Các widget cũng nhận các lần nhấp chuột, nhấn phím và các sự kiện khác từ người dùng, hệ thống cửa sổ và nhiều nguồn khác. Mỗi khi một widget bắt được một sự kiện, nó sẽ phát ra một tín hiệu để thông báo về sự thay đổi trạng thái của nó. PyQt5 có một bộ sưu tập vật dụng hiện đại và phong phú phục vụ một số mục đích. Một số widget phổ biến và hữu ích nhất là:

  • nút
  • Nhãn
  • Chỉnh sửa dòng
  • Hộp kết hợp
  • Các nút radio

Chúng ta hãy xem xét kỹ hơn từng vật dụng này. Đầu tiên là nút . Bạn có thể tạo một nút bằng cách khởi tạo QPushButton, một lớp cung cấp nút lệnh cổ điển. Nút điển hình là OKCancelApplyYesNo, và Close. Đây là cách chúng trông như thế nào trên hệ thống Linux:

Hướng dẫn dùng pyqt python

Các nút như thế này có lẽ là tiện ích được sử dụng phổ biến nhất trong bất kỳ GUI nào. Khi bạn nhấp vào chúng, bạn có thể ra lệnh cho máy tính thực hiện các hành động. Bạn thậm chí có thể thực hiện các hành động để phản hồi người dùng nhấp vào một nút.

Tiếp theo là các nhãn mà bạn có thể tạo QLabel. Nhãn cung cấp cho bạn một cách để hiển thị thông tin hữu ích dưới dạng văn bản hoặc hình ảnh:

Hướng dẫn dùng pyqt python

Bạn có thể sử dụng các nhãn như thế này để giải thích rõ hơn về mục đích hoặc cách sử dụng GUI của mình. Bạn có thể chỉnh sửa giao diện của chúng theo một số cách và thậm chí chúng có thể chấp nhận văn bản HTML, như bạn đã thấy trước đó. Nhãn cũng có thể được sử dụng để chỉ định khóa ghi nhớ tiêu điểm cho một tiện ích con khác.

Một tiện ích phổ biến khác là chỉnh sửa dòng , một hộp văn bản một dòng mà bạn có thể tạo bằng QLineEdit. Chỉnh sửa dòng rất hữu ích khi bạn cần người dùng nhập hoặc chỉnh sửa dữ liệu ở định dạng văn bản thuần túy. Đây là cách chúng trông như thế nào trên hệ thống Linux:

Hướng dẫn dùng pyqt python

Chỉnh sửa dòng như thế này cung cấp các hoạt động chỉnh sửa cơ bản như copypasteundoredo, kéo, thả, và vân vân. Trong hình trên, bạn cũng có thể thấy rằng các đối tượng trên hàng đầu tiên hiển thị văn bản giữ chỗ để thông báo cho người dùng loại đầu vào nào được yêu cầu.

Hộp tổ hợp là một tiện ích hữu ích khác mà bạn có thể tạo bằng QComboBox. Hộp tổ hợp sẽ hiển thị cho người dùng của bạn một danh sách các tùy chọn theo cách chiếm một lượng không gian màn hình tối thiểu. Dưới đây là một ví dụ về danh sách thả xuống trên hệ thống Linux:

Hộp tổ hợp này ở chế độ chỉ đọc , có nghĩa là người dùng có thể chọn một trong số các tùy chọn nhưng không thể thêm tùy chọn của riêng họ. Hộp tổ hợp cũng có thể được chỉnh sửa , cho phép người dùng thêm các tùy chọn mới. Chúng có thể chứa pixmap, chuỗi hoặc cả hai.

Tiện ích cuối cùng mà bạn sẽ đề cập ở đây là nút radio , bạn có thể tạo bằng nút radioQRadioButton . Một QRadioButtonđối tượng là một nút tùy chọn có thể được bật lên (kiểm tra) hoặc tắt (kiểm soát). Các nút radio hữu ích khi bạn cần người dùng chọn một trong nhiều tùy chọn. Trong trường hợp này, tất cả các tùy chọn đều hiển thị trên màn hình cùng một lúc:

Trong nhóm nút radio này, chỉ có thể kiểm tra một nút tại một thời điểm nhất định. Nếu người dùng chọn một nút radio khác, thì nút đã chọn trước đó sẽ tự động tắt.

PyQt5 có một bộ sưu tập lớn các vật dụng. Tại thời điểm viết bài này, có hơn bốn mươi sẵn có để bạn sử dụng để tạo GUI cho ứng dụng của mình. Những thứ bạn đã đề cập cho đến nay chỉ là một mẫu nhỏ, nhưng chúng cho bạn thấy sức mạnh và tính linh hoạt của PyQt5. Trong phần tiếp theo, bạn sẽ trình bày cách bố trí các widget khác nhau để tạo các GUI hiện đại và chức năng cho các ứng dụng của bạn.

Người quản lý bố cục

Bây giờ bạn đã biết widget là gì và cách sử dụng chúng để xây dựng GUI. Nhưng làm thế nào bạn có thể sắp xếp một tập hợp các widget để tạo ra một GUI vừa mạch lạc vừa có chức năng? Có nhiều kỹ thuật mà bạn có thể sử dụng để bố trí các widget trên một biểu mẫu hoặc cửa sổ. Ví dụ: bạn có thể sử dụng .resize()và .move()cung cấp cho các widget kích thước và vị trí tuyệt đối. Tuy nhiên, điều này có thể có một số hạn chế:

  • Bạn sẽ phải thực hiện nhiều phép tính thủ công để xác định kích thước và vị trí chính xác của mọi tiện ích con trong các biểu mẫu của mình.
  • Bạn sẽ phải thực hiện thêm một số phép tính để phản hồi chính xác các thay đổi về kích thước biểu mẫu ( sự kiện thay đổi kích thước ).
  • Bạn sẽ phải thực hiện lại tất cả các phép tính bất cứ khi nào bạn thay đổi bố cục của biểu mẫu hoặc thêm hoặc xóa các tiện ích con.

Một giải pháp thay thế là sử dụng .resizeEvent()để tính toán kích thước và vị trí tiện ích một cách động. Tuy nhiên, giải pháp thay thế hiệu quả nhất có thể là sử dụng trình quản lý bố cục , điều này sẽ làm tăng năng suất của bạn và cải thiện khả năng bảo trì mã của bạn.

Trình quản lý bố cục là các lớp cho phép bạn định kích thước và định vị các widget của mình ở những vị trí bạn muốn chúng có trên biểu mẫu của ứng dụng. Trình quản lý bố cục tự động điều chỉnh để thay đổi kích thước các sự kiện và thay đổi nội dung. Họ cũng kiểm soát kích thước của các vật dụng bên trong chúng. Điều này có nghĩa là các tiện ích con trong một bố cục được tự động thay đổi kích thước bất cứ khi nào biểu mẫu được thay đổi kích thước.

Lưu ý: Nếu bạn phát triển các ứng dụng quốc tế, thì bạn có thể đã thấy các nhãn đã dịch có thể được cắt ngắn như thế nào. Điều này đặc biệt có thể xảy ra khi ngôn ngữ đích dài hơn ngôn ngữ gốc. Trình quản lý bố cục có thể giúp bạn tránh được cạm bẫy phổ biến này. Tuy nhiên, tính năng này có thể hơi phức tạp và đôi khi có thể thất bại với những ngôn ngữ đặc biệt nhiều chữ.

PyQt cung cấp bốn lớp trình quản lý bố cục cơ bản:

  1. QHBoxLayout
  2. QVBoxLayout
  3. QGridLayout
  4. QFormLayout

Lớp trình quản lý bố cục đầu tiên là QHBoxLayout, sắp xếp các widget theo chiều ngang từ trái sang phải:

Hướng dẫn dùng pyqt python

Các widget sẽ xuất hiện bên cạnh cái kia, bắt đầu từ bên trái.

Ví dụ mã này cho bạn thấy cách sử dụng QHBoxLayoutđể sắp xếp các nút theo chiều ngang:

 1# Filename: h_layout.py
 2
 3"""Horizontal layout example."""
 4
 5import sys
 6
 7from PyQt5.QtWidgets import QApplication
 8from PyQt5.QtWidgets import QHBoxLayout
 9from PyQt5.QtWidgets import QPushButton
10from PyQt5.QtWidgets import QWidget
11
12app = QApplication(sys.argv)
13window = QWidget()
14window.setWindowTitle('QHBoxLayout')
15layout = QHBoxLayout()
16layout.addWidget(QPushButton('Left'))
17layout.addWidget(QPushButton('Center'))
18layout.addWidget(QPushButton('Right'))
19window.setLayout(layout)
20window.show()
21sys.exit(app.exec_())

Các dòng được đánh dấu làm nên điều kỳ diệu ở đây:

  • Dòng 15 tạo một QHBoxLayoutđối tượng được gọi layout.
  • Các dòng từ 16 đến 18 thêm ba nút vào layoutvới.addWidget()
  • Dòng 19 đặt layoutlàm bố cục cửa sổ của bạn với .setLayout().

Khi bạn chạy python3 h_layout.pytừ dòng lệnh của mình, bạn sẽ nhận được kết quả sau:

Hướng dẫn dùng pyqt python

Trong hình trên, bạn đã thêm ba nút theo chiều ngang. Lưu ý rằng các nút được hiển thị từ trái sang phải theo thứ tự giống như khi bạn thêm chúng vào mã của mình.

Lớp trình quản lý bố cục tiếp theo là QVBoxLayout, sắp xếp các widget theo chiều dọc, từ trên xuống dưới:

Hướng dẫn dùng pyqt python

Mỗi tiện ích con mới sẽ xuất hiện bên dưới tiện ích trước đó. Bạn có thể sử dụng lớp này để xây dựng các đối tượng bố cục hộp dọc và tổ chức tiện ích con của bạn từ trên xuống dưới.

Đây là cách bạn có thể tạo và sử dụng một QVBoxLayoutđối tượng:

 1# Filename: v_layout.py
 2
 3"""Vertical layout example."""
 4
 5import sys
 6
 7from PyQt5.QtWidgets import QApplication
 8from PyQt5.QtWidgets import QPushButton
 9from PyQt5.QtWidgets import QVBoxLayout
10from PyQt5.QtWidgets import QWidget
11
12app = QApplication(sys.argv)
13window = QWidget()
14window.setWindowTitle('QVBoxLayout')
15layout = QVBoxLayout()
16layout.addWidget(QPushButton('Top'))
17layout.addWidget(QPushButton('Center'))
18layout.addWidget(QPushButton('Bottom'))
19window.setLayout(layout)
20window.show()
21sys.exit(app.exec_())

Trong dòng 15, bạn tạo một phiên bản của QVBoxLayout. Trong ba dòng tiếp theo, bạn thêm ba nút vào layout. Cuối cùng, bạn sử dụng layoutđể sắp xếp widget theo bố cục dọc.

Khi bạn chạy ứng dụng này, bạn sẽ nhận được đầu ra như sau:

Hướng dẫn dùng pyqt python

Ứng dụng này hiển thị ba nút theo bố cục dọc, một bên dưới nút kia. Các nút xuất hiện theo thứ tự khi bạn thêm chúng vào mã của mình, từ trên xuống dưới.

Lớp trình quản lý bố cục thứ ba là QGridLayout, sắp xếp các widget thành một lưới các hàng và cột. Mọi tiện ích sẽ có một vị trí tương đối trên lưới. Bạn có thể xác định vị trí của tiện ích bằng cách chuyển cho nó một cặp tọa độ ở dạng (row, column). Các tọa độ này phải là intsố hợp lệ . Chúng xác định ô nào của lưới mà bạn sẽ đặt tiện ích. Bố cục lưới hoạt động như sau:

Hướng dẫn dùng pyqt python

QGridLayoutlấy không gian có sẵn cho nó parent, chia nó thành rowsvà columnsvà đặt mỗi tiện ích vào ô riêng của nó.

Đây là cách sử dụng QGridLayouttrong GUI của bạn:

 1# Filename: g_layout.py
 2
 3"""Grid layout example."""
 4
 5import sys
 6
 7from PyQt5.QtWidgets import QApplication
 8from PyQt5.QtWidgets import QGridLayout
 9from PyQt5.QtWidgets import QPushButton
10from PyQt5.QtWidgets import QWidget
11
12app = QApplication(sys.argv)
13window = QWidget()
14window.setWindowTitle('QGridLayout')
15layout = QGridLayout()
16layout.addWidget(QPushButton('Button (0, 0)'), 0, 0)
17layout.addWidget(QPushButton('Button (0, 1)'), 0, 1)
18layout.addWidget(QPushButton('Button (0, 2)'), 0, 2)
19layout.addWidget(QPushButton('Button (1, 0)'), 1, 0)
20layout.addWidget(QPushButton('Button (1, 1)'), 1, 1)
21layout.addWidget(QPushButton('Button (1, 2)'), 1, 2)
22layout.addWidget(QPushButton('Button (2, 0)'), 2, 0)
23layout.addWidget(QPushButton('Button (2, 1) + 2 Columns Span'), 2, 1, 1, 2)
24window.setLayout(layout)
25window.show()
26sys.exit(app.exec_())

Trong ví dụ này, bạn tạo một ứng dụng sử dụng một QGridLayoutđối tượng để tổ chức các widget của nó. Lưu ý rằng, trong trường hợp này, đối số thứ hai và thứ ba mà bạn chuyển đến .addWidget()là các intđối số xác định vị trí của mỗi tiện ích con.

Trong dòng 23, bạn thêm hai đối số nữa vào .addWidget(). Các đối số này được gọi rowSpanvà columnSpanvà chúng là đối số thứ tư và thứ năm được truyền cho hàm. Bạn có thể sử dụng chúng để tạo tiện ích con chiếm nhiều hơn một hàng hoặc cột như bạn đã làm với QPushButton('Button (2, 1) + 2 Columns Span')ở đây.

Nếu bạn chạy mã này từ dòng lệnh của mình, thì bạn sẽ nhận được một cửa sổ như sau:

Hướng dẫn dùng pyqt python

Bạn có thể thấy các tiện ích con của mình được sắp xếp trong một lưới các hàng và cột. Tiện ích con cuối cùng chiếm nhiều ô, như bạn đã chỉ định trong dòng 23.

Lớp quản lý bố cục cuối cùng là QFormLayout, sắp xếp các widget theo bố cục hai cột. Cột đầu tiên thường hiển thị thông báo trong nhãn. Cột thứ hai thường chứa các widget như QLineEditQComboBoxQSpinBox, và vân vân. Những điều này cho phép người dùng nhập hoặc chỉnh sửa dữ liệu liên quan đến thông tin trong cột đầu tiên. Sơ đồ sau đây cho thấy cách bố cục biểu mẫu hoạt động trong thực tế:

Hướng dẫn dùng pyqt python

Cột bên trái bao gồm các nhãn và cột bên phải bao gồm các tiện ích trường. Nếu bạn đang xử lý một ứng dụng cơ sở dữ liệu , thì kiểu bố cục này có thể là một lựa chọn hấp dẫn để tăng năng suất khi bạn tạo biểu mẫu của mình.

Ví dụ sau cho bạn thấy cách tạo một ứng dụng sử dụng một QFormLayoutđối tượng để sắp xếp các widget của nó:

 1# Filename: f_layout.py
 2
 3"""Form layout example."""
 4
 5import sys
 6
 7from PyQt5.QtWidgets import QApplication
 8from PyQt5.QtWidgets import QFormLayout
 9from PyQt5.QtWidgets import QLineEdit
10from PyQt5.QtWidgets import QWidget
11
12app = QApplication(sys.argv)
13window = QWidget()
14window.setWindowTitle('QFormLayout')
15layout = QFormLayout()
16layout.addRow('Name:', QLineEdit())
17layout.addRow('Age:', QLineEdit())
18layout.addRow('Job:', QLineEdit())
19layout.addRow('Hobbies:', QLineEdit())
20window.setLayout(layout)
21window.show()
22sys.exit(app.exec_())

Các dòng từ 15 đến 20 thực hiện công việc khó khăn trong ví dụ này. Lưu ý rằng QFormLayoutcó một phương thức thuận tiện được gọi .addRow(). Bạn có thể sử dụng phương pháp này để thêm một hàng hai tiện ích con vào bố cục. Đối số đầu tiên của .addRow()phải là nhãn và đối số thứ hai phải là bất kỳ tiện ích con nào khác cho phép người dùng nhập hoặc chỉnh sửa dữ liệu.

Nếu bạn chạy mã này, thì bạn sẽ nhận được kết quả sau:

Hướng dẫn dùng pyqt python

Hình trên cho thấy một GUI sử dụng bố cục biểu mẫu. Cột đầu tiên chứa các nhãn để hỏi người dùng một số thông tin. Cột thứ hai hiển thị các widget cho phép người dùng nhập hoặc chỉnh sửa thông tin bạn yêu cầu từ chúng.

Hộp thoại (Dialog)

Với PyQt, bạn có thể phát triển hai loại ứng dụng GUI trên máy tính để bàn. Tùy thuộc vào lớp bạn sử dụng để tạo biểu mẫu hoặc cửa sổ chính, bạn sẽ có một trong những điều sau:

  1. Ứng dụng Kiểu cửa sổ chính: Cửa sổ chính của ứng dụng kế thừa từ QMainWindow.
  2. Ứng dụng Kiểu hộp thoại: Cửa sổ chính của ứng dụng kế thừa từ QDialog.

Trước tiên, bạn sẽ bắt đầu với các ứng dụng Kiểu hộp thoại. Trong phần tiếp theo, bạn sẽ trình bày các ứng dụng Kiểu Cửa sổ Chính.

Để phát triển ứng dụng Kiểu hộp thoại, bạn cần tạo một lớp GUI kế thừa QDialog, lớp này là lớp cơ sở của tất cả các cửa sổ hộp thoại. Một cửa sổ hộp thoại luôn luôn là một cửa sổ cấp cao mà bạn có thể sử dụng như là cửa sổ chính cho các ứng dụng Dialog-Phong cách của bạn.

Lưu ý: Cửa sổ hộp thoại cũng thường được sử dụng trong các ứng dụng Kiểu Cửa sổ Chính để giao tiếp và tương tác ngắn với người dùng.

Khi các cửa sổ hộp thoại được sử dụng để giao tiếp với người dùng, chúng có thể là:

  • Hộp thoại phương thức: chặn đầu vào cho bất kỳ cửa sổ hiển thị nào khác trong cùng một ứng dụng. Bạn có thể hiển thị một hộp thoại phương thức bằng cách gọi .exec_().
  • Hộp thoại Modeless: hoạt động độc lập với các cửa sổ khác trong cùng một ứng dụng. Bạn có thể hiển thị một hộp thoại không có mô hình bằng cách sử dụng .show().

Cửa sổ hộp thoại cũng có thể cung cấp giá trị trả về và có các nút mặc định (ví dụ: OKvà Cancel).

Hộp thoại luôn là một tiện ích con cấp cao nhất. Nếu nó có một parent, thì vị trí mặc định của nó sẽ được căn giữa ở trên cùng của tiện ích con cấp cao nhất của cha mẹ. Loại hộp thoại này cũng sẽ chia sẻ mục nhập trên thanh tác vụ của cha mẹ. Nếu bạn không đặt parentcho một hộp thoại nhất định, thì hộp thoại sẽ nhận được mục nhập của chính nó trên thanh tác vụ của hệ thống.

Dưới đây là ví dụ về cách bạn sử dụng QDialogđể phát triển ứng dụng Kiểu hộp thoại:

 1# Filename: dialog.py
 2
 3"""Dialog-Style application."""
 4
 5import sys
 6
 7from PyQt5.QtWidgets import QApplication
 8from PyQt5.QtWidgets import QDialog
 9from PyQt5.QtWidgets import QDialogButtonBox
10from PyQt5.QtWidgets import QFormLayout
11from PyQt5.QtWidgets import QLineEdit
12from PyQt5.QtWidgets import QVBoxLayout
13
14class Dialog(QDialog):
15    """Dialog."""
16    def __init__(self, parent=None):
17        """Initializer."""
18        super().__init__(parent)
19        self.setWindowTitle('QDialog')
20        dlgLayout = QVBoxLayout()
21        formLayout = QFormLayout()
22        formLayout.addRow('Name:', QLineEdit())
23        formLayout.addRow('Age:', QLineEdit())
24        formLayout.addRow('Job:', QLineEdit())
25        formLayout.addRow('Hobbies:', QLineEdit())
26        dlgLayout.addLayout(formLayout)
27        btns = QDialogButtonBox()
28        btns.setStandardButtons(
29            QDialogButtonBox.Cancel | QDialogButtonBox.Ok)
30        dlgLayout.addWidget(btns)
31        self.setLayout(dlgLayout)
32
33if __name__ == '__main__':
34    app = QApplication(sys.argv)
35    dlg = Dialog()
36    dlg.show()
37    sys.exit(app.exec_())

Ứng dụng này phức tạp hơn một chút. Đây là những gì đang xảy ra:

  • Dòng 14 tạo ra một lớp đầy đủ Dialogcho GUI, lớp kế thừa từ QDialog.
  • Dòng 20 chỉ định một QVBoxLayoutđối tượng cho dlgLaout.
  • Dòng 21 gán một QVFormLayoutđối tượng cho formLayout.
  • Dòng 22 đến 25 thêm tiện ích con vào formLayout.
  • Dòng 26 dùng dlgLayoutđể sắp xếp tất cả các widget trên biểu mẫu.
  • Dòng 27 cung cấp một đối tượng thuận tiện để đặt các nút hộp thoại.
  • Dòng 28 và 29 thêm hai nút tiêu chuẩn: Okvà Cancel.
  • Các dòng từ 33 đến 37 bao gồm mã chương trình tạo sẵn trong một if __name__ == '__main__':thành ngữ . Đây được coi là cách luyện tập tốt nhất cho Pythonistas.

Lưu ý: Nếu bạn nhìn vào dòng 26 trong khối mã ở trên, thì bạn sẽ nhận thấy rằng các trình quản lý bố cục có thể được lồng vào nhau. Bạn có thể lồng các bố cục bằng cách gọi bố cục .addLayout()vùng chứa và chuyển vào bố cục lồng nhau làm đối số cho phương thức này.

Khối mã ở trên hiển thị cửa sổ sau:

Hướng dẫn dùng pyqt python

Đây là GUI mà bạn đã tạo bằng cách sử dụng QFormLayoutcho các tiện ích và QVBoxLayoutcho bố cục của ứng dụng chung ( dlgLayoutở dòng 20).

Windows chính

Hầu hết thời gian, các ứng dụng GUI của bạn sẽ là Kiểu cửa sổ chính . Điều này có nghĩa là chúng sẽ có thanh menu , một số thanh công cụ, thanh trạng thái và tiện ích trung tâm sẽ là yếu tố chính của GUI. Các ứng dụng của bạn cũng sẽ có một số cửa sổ hộp thoại để thực hiện các tác vụ phụ phụ thuộc vào đầu vào của người dùng.

Bạn sẽ sử dụng lớp này QMainWindowđể phát triển các ứng dụng Kiểu Cửa sổ Chính. Bạn cần kế thừa từ QMainWindowđể tạo lớp GUI chính của mình. Một thể hiện của một lớp dẫn xuất từ ​​đó QMainWindowđược coi là một cửa sổ chính . QMainWindowcung cấp một khuôn khổ để xây dựng GUI cho ứng dụng của bạn. Lớp có bố cục cài sẵn của riêng nó, bạn có thể sử dụng bố cục này để đặt các nội dung sau:

  • Một thanh menu ở trên cùng của cửa sổ. Thanh menu giữ menu chính của ứng dụng.

  • Một số thanh công cụ nằm ở hai bên cửa sổ. Thanh công cụ thích hợp để giữ các nút công cụ và các loại tiện ích con khác như QComboBox,, QSpinBoxv.v.

  • Một tiện ích trung tâm nằm ở giữa cửa sổ. Tiện ích trung tâm có thể thuộc bất kỳ loại nào, hoặc có thể là một tiện ích tổng hợp.

  • Một số widget dock nằm xung quanh widget trung tâm. Dock widget là các cửa sổ nhỏ, có thể di chuyển được.

  • Một thanh trạng thái ở cuối cửa sổ. Thanh trạng thái hiển thị thông tin về trạng thái chung của ứng dụng.

Bạn không thể tạo một cửa sổ chính mà không đặt tiện ích trung tâm trước. Bạn phải có một tiện ích con trung tâm, ngay cả khi nó chỉ là một trình giữ chỗ. Trong trường hợp này, bạn có thể sử dụng một QWidgetđối tượng làm tiện ích con trung tâm của mình. Bạn có thể đặt tiện ích trung tâm của cửa sổ chính với .setCentralWidget(). Bố cục của cửa sổ chính sẽ cho phép bạn chỉ có một widget trung tâm, nhưng nó có thể là một widget đơn lẻ hoặc tổng hợp.

Ví dụ mã sau đây cho bạn thấy cách sử dụng QMainWindowđể tạo ứng dụng Kiểu cửa sổ chính:

 1# Filename: main_window.py
 2
 3"""Main Window-Style application."""
 4
 5import sys
 6
 7from PyQt5.QtWidgets import QApplication
 8from PyQt5.QtWidgets import QLabel
 9from PyQt5.QtWidgets import QMainWindow
10from PyQt5.QtWidgets import QStatusBar
11from PyQt5.QtWidgets import QToolBar
12
13class Window(QMainWindow):
14    """Main Window."""
15    def __init__(self, parent=None):
16        """Initializer."""
17        super().__init__(parent)
18        self.setWindowTitle('QMainWindow')
19        self.setCentralWidget(QLabel("I'm the Central Widget"))
20        self._createMenu()
21        self._createToolBar()
22        self._createStatusBar()
23
24    def _createMenu(self):
25        self.menu = self.menuBar().addMenu("&Menu")
26        self.menu.addAction('&Exit', self.close)
27
28    def _createToolBar(self):
29        tools = QToolBar()
30        self.addToolBar(tools)
31        tools.addAction('Exit', self.close)
32
33    def _createStatusBar(self):
34        status = QStatusBar()
35        status.showMessage("I'm the Status Bar")
36        self.setStatusBar(status)
37
38if __name__ == '__main__':
39    app = QApplication(sys.argv)
40    win = Window()
41    win.show()
42    sys.exit(app.exec_())

Đây là cách mã này hoạt động:

  • Dòng 13 tạo một lớp Windowkế thừa từ QMainWindow.
  • Dòng 18 đặt tiêu đề của cửa sổ.
  • Dòng 19 đặt a QLabellàm tiện ích con trung tâm.
  • Các dòng 20 đến 22 gọi các phương thức riêng tư trong các dòng tiếp theo để tạo các phần tử GUI khác nhau:
    • Các dòng từ 24 đến 26 tạo menu chính.
    • Dòng 28 đến 31 tạo thanh công cụ.
    • Dòng 33 đến dòng 36 tạo thanh trạng thái.

Lưu ý: Khi bạn triển khai các thành phần GUI khác nhau theo phương pháp riêng của chúng, bạn đang làm cho mã của mình dễ đọc hơn và dễ bảo trì hơn. Tuy nhiên, đây không phải là một yêu cầu bắt buộc, vì vậy bạn có thể tự do sắp xếp mã của mình theo cách bạn thích nhất.

Khi bạn chạy đoạn mã trên, bạn sẽ thấy một cửa sổ như sau:

Hướng dẫn dùng pyqt python

Bạn có thể thấy rằng ứng dụng Kiểu cửa sổ chính của bạn có các thành phần sau:

  • Một menu chính được gọi là Menu
  • Một thanh công cụ với một Exitnút công cụ chức năng
  • Một tiện ích trung tâm (một QLabelđối tượng)
  • Một thanh trạng thái ở cuối cửa sổ

Cho đến nay, bạn đã đề cập đến một số thành phần đồ họa quan trọng hơn của bộ widget của PyQt5. Trong hai phần tiếp theo, bạn sẽ trình bày một số khái niệm quan trọng khác liên quan đến các ứng dụng PyQt GUI.

Các ứng dụng

Lớp cơ bản nhất mà bạn sẽ sử dụng khi phát triển các ứng dụng PyQt GUI là QApplication. Lớp này là cốt lõi của bất kỳ ứng dụng PyQt nào. Nó quản lý luồng điều khiển của ứng dụng cũng như các cài đặt chính của nó. Trong PyQt, bất kỳ trường hợp nào của QApplicationđều được coi là một ứng dụng . Mọi ứng dụng PyQt GUI phải có một QApplicationđối tượng. Một số trách nhiệm của ứng dụng bao gồm:

  • Xử lý khởi tạo và hoàn thiện
  • Cung cấp vòng lặp sự kiện và xử lý sự kiện
  • Xử lý hầu hết các cài đặt trên toàn hệ thống và toàn ứng dụng
  • Cung cấp quyền truy cập vào thông tin toàn cầu, chẳng hạn như thư mục của ứng dụng, kích thước màn hình, v.v.
  • Phân tích cú pháp các đối số dòng lệnh phổ biến
  • Xác định giao diện của ứng dụng
  • Cung cấp khả năng bản địa hóa

Đây chỉ là một số trách nhiệm cốt lõi của QApplication. Như bạn có thể thấy, đây là một lớp cơ bản khi nói đến việc phát triển các ứng dụng PyQt GUI!

Một trong những trách nhiệm quan trọng nhất QApplicationlà cung cấp vòng lặp sự kiện và toàn bộ cơ chế xử lý sự kiện. Bây giờ chúng ta hãy xem xét kỹ hơn vòng lặp sự kiện.

Vòng lặp sự kiện

Các ứng dụng GUI là hướng sự kiện . Điều này có nghĩa là các chức năng và phương thức được thực thi theo các thao tác của người dùng như nhấp vào nút, 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 phần chỉnh sửa văn bản, nhấn phím trên bàn phím, v.v. Những hành động của người dùng này thường được gọi là sự kiện .

Các sự kiện thường được xử lý bởi một vòng lặp sự kiện (còn được gọi là vòng lặp chính ). Vòng lặp sự kiện là một vòng lặp vô hạn trong đó tất cả các sự kiện từ người dùng, hệ thống cửa sổ và bất kỳ nguồn nào khác đều được xử lý và gửi đi. Vòng lặp sự kiện đợi một sự kiện xảy ra và sau đó điều động nó thực hiện một số tác vụ. Vòng lặp sự kiện tiếp tục hoạt động cho đến khi ứng dụng được kết thúc.

Các vòng lặp sự kiện được sử dụng bởi tất cả các ứng dụng GUI. Vòng lặp sự kiện là một loại vòng lặp vô hạn chờ sự xuất hiện của các sự kiện. Nếu một sự kiện xảy ra, thì vòng lặp sẽ kiểm tra xem sự kiện đó có phải là một Terminatesự kiện hay không. Trong trường hợp đó, vòng lặp bị kết thúc và ứng dụng sẽ thoát. Nếu không, sự kiện được gửi đến hàng đợi sự kiện của ứng dụng để xử lý thêm và vòng lặp bắt đầu lại.

Trong PyQt, bạn có thể chạy vòng lặp sự kiện của ứng dụng bằng cách gọi .exec_()trên QApplicationđối tượng.

Lưu ý: PyQt lần đầu tiên được phát triển để nhắm mục tiêu Python 2, đã có một exectừ khóa. Trong các phiên bản trước, dấu gạch dưới đã được thêm vào cuối .exec_()để giúp tránh xung đột tên.

PyQt5 nhắm mục tiêu Python 3, không có exectừ khóa. Tuy nhiên, thư viện cung cấp hai phương thức bắt đầu vòng lặp sự kiện:

  1. .exec_()
  2. .exec()

Điều này có nghĩa là bạn có thể xóa .exec_()khỏi mã của mình và .exec()thay vào đó bạn có thể sử dụng một cách an toàn .

Đối với một sự kiện để kích hoạt một hành động phản hồi, bạn cần kết nối sự kiện với hành động bạn muốn được thực hiện. Trong PyQt5, bạn có thể thiết lập kết nối đó bằng cách sử dụng cơ chế tín hiệu và khe cắm. Bạn sẽ đề cập đến những điều này trong phần tiếp theo.

Tín hiệu và khe cắm

Các widget PyQt hoạt động như những người nắm bắt sự kiện . Điều này có nghĩa là mọi tiện ích con đều có thể nắm bắt một số sự kiện cụ thể, chẳng hạn như nhấp chuột, nhấn phím, v.v. Để đáp lại những sự kiện này, các widget luôn phát ra một tín hiệu , đây là một loại thông báo thông báo về sự thay đổi trạng thái của nó.

Tín hiệu tự nó không thực hiện bất kỳ hành động nào. Nếu bạn muốn một tín hiệu để kích hoạt một hành động, thì bạn cần kết nối nó với một vị trí . Đây là chức năng hoặc phương thức sẽ thực hiện một hành động bất cứ khi nào tín hiệu kết nối được phát ra. Bạn có thể sử dụng bất kỳ Python nào có thể gọi (hoặc gọi lại ) làm vị trí.

Nếu một tín hiệu được kết nối với một khe cắm, thì khe cắm đó được gọi bất cứ khi nào tín hiệu được phát ra. Nếu một tín hiệu không được kết nối với bất kỳ khe cắm nào, thì không có gì xảy ra và tín hiệu bị bỏ qua. Dưới đây là một số tính năng hữu ích nhất của cơ chế này:

  • Một tín hiệu có thể được kết nối với một hoặc nhiều khe cắm.
  • Một tín hiệu cũng có thể được kết nối với một tín hiệu khác.
  • Một khe cắm có thể được kết nối với một hoặc nhiều tín hiệu.

Bạn có thể sử dụng cú pháp sau để kết nối tín hiệu với một khe cắm:

widget.signal.connect(slot_function)

Điều này sẽ kết nối slot_functionvới widget.signal. Bất cứ khi nào signalđược phát ra, slot_function()sẽ được gọi.

Mã này chỉ cho bạn cách sử dụng cơ chế tín hiệu và vị trí:

 1# Filename: signals_slots.py
 2
 3"""Signals and slots example."""
 4
 5import sys
 6
 7from PyQt5.QtWidgets import QApplication
 8from PyQt5.QtWidgets import QLabel
 9from PyQt5.QtWidgets import QPushButton
10from PyQt5.QtWidgets import QVBoxLayout
11from PyQt5.QtWidgets import QWidget
12
13def greeting():
14    """Slot function."""
15    if msg.text():
16        msg.setText("")
17    else:
18        msg.setText("Hello World!")
19
20app = QApplication(sys.argv)
21window = QWidget()
22window.setWindowTitle('Signals and slots')
23layout = QVBoxLayout()
24
25btn = QPushButton('Greet')
26btn.clicked.connect(greeting)  # Connect clicked to greeting()
27
28layout.addWidget(btn)
29msg = QLabel('')
30layout.addWidget(msg)
31window.setLayout(layout)
32window.show()
33sys.exit(app.exec_())

Trong dòng 13, bạn tạo greeting(), mà bạn sẽ sử dụng làm vị trí. Sau đó ở dòng 26, bạn kết nối clickedtín hiệu của nút với greeting(). Bằng cách này, bất cứ khi nào người dùng nhấp vào nút, greeting()sẽ được gọi và msgsẽ xen kẽ giữa thông báo Hello World!và một chuỗi trống:

Khi bạn nhấp vào GreetHello World!thông báo sẽ xuất hiện và biến mất trên màn hình của bạn.

Lưu ý: Mỗi tiện ích con đều có tập hợp các tín hiệu được xác định trước của riêng nó. Bạn có thể kiểm tra chúng trên trang tài liệu của tiện ích con.

Nếu hàm vị trí của bạn cần nhận thêm các đối số, thì bạn có thể chuyển chúng vào bằng cách sử dụng functools.partial. Ví dụ: bạn có thể sửa đổi greeting()như sau:

def greeting(who):
    """Slot function."""
    if msg.text():
        msg.setText('')
    else:
        msg.setText(f'Hello {who}')

Bây giờ, greeting()cần nhận một đối số được gọi who. Nếu bạn muốn kết nối phiên bản mới này của greeting()đến btn.clickedtín hiệu, sau đó bạn có thể làm một cái gì đó như thế này:

btn.clicked.connect(functools.partial(greeting, 'World!'))

Để mã này hoạt động, functoolstrước tiên bạn cần nhập . Lệnh gọi để functools.partial()trả về một đối tượng hoạt động tương tự như gọi greeting()với who='World!'. Bây giờ, khi người dùng nhấp vào nút, thông báo 'Hello World!'sẽ được hiển thị trong nhãn cũng như trước đó.

Lưu ý: Bạn cũng có thể sử dụng lambdađể kết nối tín hiệu với một vị trí yêu cầu đối số phụ. Đối với một bài tập thực hành, hãy thử viết mã ví dụ trên bằng cách sử dụng lambdathay vì functools.partial().

Cơ chế tín hiệu và khe cắm là những gì bạn sẽ sử dụng để mang lại sức sống cho các ứng dụng PyQt5 GUI của mình. Cơ chế này sẽ cho phép bạn biến các sự kiện của người dùng thành các hành động cụ thể. Bạn có thể tìm hiểu sâu hơn về cơ chế tín hiệu và khe cắm bằng cách xem tài liệu PyQt5 .

Bây giờ bạn đã hoàn thành các khái niệm quan trọng nhất của PyQt5. Với kiến ​​thức này và tài liệu của thư viện trong tay, bạn đã sẵn sàng để bắt đầu phát triển các ứng dụng GUI của riêng mình. Trong phần tiếp theo, bạn sẽ xây dựng ứng dụng GUI đầy đủ chức năng đầu tiên của mình.

Hãy đi cho nó!

Tạo máy tính với Python và PyQt

Trong phần này, bạn sẽ phát triển một máy tính bằng cách sử dụng mẫu thiết kế Model-View-Controller (MVC) . Mẫu này có ba lớp mã, mỗi lớp có các vai trò khác nhau:

  1. Mô hình quan tâm đến logic kinh doanh của ứng dụng của bạn . Nó chứa các chức năng và dữ liệu cốt lõi. Đối với máy tính của bạn, mô hình sẽ xử lý các phép tính.

  2. Chế độ xem triển khai GUI của ứng dụng của bạn. Nó lưu trữ tất cả các widget mà người dùng cuối cần để tương tác với ứng dụng. Chế độ xem cũng nhận các hành động và sự kiện của người dùng. Đối với máy tính của bạn, giao diện sẽ là cửa sổ bạn sẽ thấy trên màn hình của mình.

  3. Bộ điều khiển kết nối mô hình và khung nhìn để làm cho ứng dụng hoạt động. Các sự kiện (hoặc yêu cầu) của người dùng được gửi đến bộ điều khiển, điều này làm cho mô hình hoạt động. Khi mô hình cung cấp kết quả (hoặc dữ liệu) được yêu cầu ở định dạng phù hợp, bộ điều khiển sẽ chuyển tiếp nó đến dạng xem. Đối với máy tính của bạn, bộ điều khiển sẽ nhận các sự kiện của người dùng từ GUI, yêu cầu mô hình thực hiện các phép tính và cập nhật GUI với kết quả.

Đây là mẫu MVC từng bước cho ứng dụng GUI trên máy tính để bàn:

  1. Người dùng thực hiện một hành động hoặc yêu cầu (sự kiện) trên giao diện (GUI).
  2. Chế độ xem thông báo cho bộ điều khiển về hành động của người dùng.
  3. Bộ điều khiển nhận yêu cầu của người dùng và truy vấn mô hình để có phản hồi.
  4. Mô hình xử lý truy vấn bộ điều khiển, thực hiện các hoạt động được yêu cầu và trả về một câu trả lời hoặc kết quả.
  5. Bộ điều khiển nhận câu trả lời của mô hình và cập nhật chế độ xem cho phù hợp.
  6. Người dùng cuối cùng cũng nhìn thấy kết quả được yêu cầu trên chế độ xem.

Bạn sẽ sử dụng mẫu thiết kế MVC này để xây dựng máy tính của mình.

Tạo bộ xương

Bạn sẽ bắt đầu bằng cách triển khai một khung cơ bản cho ứng dụng của mình, được gọi là pycalc.py. Bạn có thể tìm thấy tập lệnh này và phần còn lại của mã nguồn tại liên kết bên dưới:

Nếu bạn muốn tự mình viết mã dự án, hãy tiếp tục và tạo pycalc.pytrong thư mục làm việc hiện tại của bạn. Sau đó, mở tệp trong trình chỉnh sửa mã của bạn và nhập mã sau:

#!/usr/bin/env python3

# Filename: pycalc.py

"""PyCalc is a simple calculator built using Python and PyQt5."""

import sys

# Import QApplication and the required widgets from PyQt5.QtWidgets
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QMainWindow
from PyQt5.QtWidgets import QWidget

__version__ = '0.1'
__author__ = 'Leodanis Pozo Ramos'

# Create a subclass of QMainWindow to setup the calculator's GUI
class PyCalcUi(QMainWindow):
    """PyCalc's View (GUI)."""
    def __init__(self):
        """View initializer."""
        super().__init__()
        # Set some main window's properties
        self.setWindowTitle('PyCalc')
        self.setFixedSize(235, 235)
        # Set the central widget
        self._centralWidget = QWidget(self)
        self.setCentralWidget(self._centralWidget)

# Client code
def main():
    """Main function."""
    # Create an instance of QApplication
    pycalc = QApplication(sys.argv)
    # Show the calculator's GUI
    view = PyCalcUi()
    view.show()
    # Execute the calculator's main loop
    sys.exit(pycalc.exec_())

if __name__ == '__main__':
    main()

Tập lệnh này thực hiện tất cả mã bạn cần để chạy một ứng dụng GUI cơ bản. Bạn sẽ sử dụng bộ xương này để xây dựng máy tính của mình. Đây là cách nó hoạt động:

  • Các dòng 10 đến 12 nhập các mô-đun và lớp bắt buộc từ PyQt5.QtWidgets.

  • Dòng 18 tạo GUI với lớp PyCalcUi. Lưu ý rằng lớp này kế thừa từ QMainWindow.

  • Dòng 24 đặt tiêu đề của cửa sổ thành PyCalc.

  • Dòng 25 sử dụng .setFixedSize()để cung cấp cho cửa sổ một kích thước cố định. Điều này đảm bảo rằng người dùng sẽ không thể thay đổi kích thước cửa sổ.

  • Dòng 27 tạo một QWidgetđối tượng để đóng vai trò của một widget trung tâm. Hãy nhớ rằng vì lớp GUI của bạn kế thừa từ đó QMainWindow, bạn cần một widget trung tâm. Đối tượng này sẽ là parentphần còn lại của thành phần GUI.

  • Dòng 31 xác định chức năng chính của máy tính của bạn , được coi là một phương pháp hay nhất. Chức năng này sẽ là điểm vào ứng dụng. Bên trong main(), chương trình của bạn thực hiện những việc sau:

    • Dòng 34 tạo một QApplicationđối tượng pycalc.
    • Dòng 37 hiển thị GUI với view.show().
    • Dòng 39 chạy vòng lặp sự kiện của ứng dụng với pycalc.exec_().

Khi bạn chạy tập lệnh, cửa sổ sau sẽ xuất hiện trên màn hình của bạn:

Hướng dẫn dùng pyqt python

Đây là khung ứng dụng GUI của bạn.

Hoàn thành Chế độ xem

GUI mà bạn có tại thời điểm này không thực sự giống như một máy tính. Hãy hoàn thành GUI bằng cách thêm màn hình và các nút cho các con số. Bạn cũng sẽ thêm các nút cho các phép toán cơ bản và để xóa màn hình.

Trước tiên, bạn sẽ cần thêm các lần nhập sau vào đầu tệp của mình:

from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QGridLayout
from PyQt5.QtWidgets import QLineEdit
from PyQt5.QtWidgets import QPushButton
from PyQt5.QtWidgets import QVBoxLayout

Bạn sẽ sử dụng a QVBoxLayoutcho bố cục chung của máy tính. Bạn cũng sẽ sử dụng một QGridLayoutđối tượng để sắp xếp các nút. Cuối cùng, bạn nhập QLineEditcho màn hình và QPushButtoncho các nút. Bây giờ sẽ có tám câu lệnh nhập ở đầu tệp của bạn.

Bây giờ bạn có thể cập nhật trình khởi tạo cho PyCalcUi:

# Create a subclass of QMainWindow to setup the calculator's GUI
class PyCalcUi(QMainWindow):
    """PyCalc's View (GUI)."""
    def __init__(self):
        """View initializer."""
        super().__init__()
        # Set some main window's properties
        self.setWindowTitle('PyCalc')
        self.setFixedSize(235, 235)
        # Set the central widget and the general layout
        self.generalLayout = QVBoxLayout()
        self._centralWidget = QWidget(self)
        self.setCentralWidget(self._centralWidget)
        self._centralWidget.setLayout(self.generalLayout)
        # Create the display and the buttons
        self._createDisplay()
        self._createButtons()

Tại đây, bạn đã thêm các dòng mã được đánh dấu. Bạn sẽ sử dụng một QVBoxLayoutđể đặt màn hình ở trên cùng và các nút trong bố cục lưới ở dưới cùng.

Các lệnh gọi đến ._createDisplay()và ._createButtons()sẽ không hoạt động, bởi vì bạn chưa triển khai các phương pháp đó. Hãy khắc phục điều đó bằng cách viết mã ._createDisplay():

class PyCalcUi(QMainWindow):
    # Snip
    def _createDisplay(self):
        """Create the display."""
        # Create the display widget
        self.display = QLineEdit()
        # Set some display's properties
        self.display.setFixedHeight(35)
        self.display.setAlignment(Qt.AlignRight)
        self.display.setReadOnly(True)
        # Add the display to the general layout
        self.generalLayout.addWidget(self.display)

Để tạo tiện ích hiển thị, bạn sử dụng một QLineEditđối tượng. Sau đó, bạn đặt các thuộc tính hiển thị sau:

  • Màn hình có chiều cao cố định là 35 pixel.
  • Màn hình hiển thị văn bản được căn trái.
  • Màn hình được đặt ở chế độ chỉ đọc để tránh chỉnh sửa trực tiếp.

Dòng cuối cùng thêm màn hình vào bố cục chung của máy tính với generalLayout.addWidget().

Tiếp theo, bạn sẽ triển khai ._createButtons()để tạo các nút cho máy tính của mình. Bạn sẽ sử dụng từ điển để giữ văn bản và vị trí của từng nút trên lưới. Bạn cũng sẽ sử dụng QGridLayoutđể sắp xếp các nút trên cửa sổ máy tính. Mã cuối cùng sẽ giống như sau:

class PyCalcUi(QMainWindow):
    # Snip
    def _createButtons(self):
        """Create the buttons."""
        self.buttons = {}
        buttonsLayout = QGridLayout()
        # Button text | position on the QGridLayout
        buttons = {'7': (0, 0),
                   '8': (0, 1),
                   '9': (0, 2),
                   '/': (0, 3),
                   'C': (0, 4),
                   '4': (1, 0),
                   '5': (1, 1),
                   '6': (1, 2),
                   '*': (1, 3),
                   '(': (1, 4),
                   '1': (2, 0),
                   '2': (2, 1),
                   '3': (2, 2),
                   '-': (2, 3),
                   ')': (2, 4),
                   '0': (3, 0),
                   '00': (3, 1),
                   '.': (3, 2),
                   '+': (3, 3),
                   '=': (3, 4),
                  }
        # Create the buttons and add them to the grid layout
        for btnText, pos in buttons.items():
            self.buttons[btnText] = QPushButton(btnText)
            self.buttons[btnText].setFixedSize(40, 40)
            buttonsLayout.addWidget(self.buttons[btnText], pos[0], pos[1])
        # Add buttonsLayout to the general layout
        self.generalLayout.addLayout(buttonsLayout)

Trước tiên, bạn tạo một từ điển trống self.buttonsđể giữ các nút trên máy tính. Sau đó, bạn tạo một từ điển tạm thời để lưu trữ các nhãn và vị trí tương đối của chúng trên bố cục lưới ( buttonsLayout). Bên trong forvòng lặp, bạn tạo các nút và thêm chúng vào cả self.buttonsvà buttonsLayout. Mỗi nút sẽ có kích thước 40x40pixel cố định mà bạn đặt .setFixedSize(40, 40).

Lưu ý: Khi nói đến kích thước tiện ích, bạn sẽ hiếm khi tìm thấy các đơn vị đo lường trong tài liệu PyQt. Giả định rằng đơn vị đo lường là pixel (ngoại trừ QPrinter, sử dụng điểm ).

Giờ đây, GUI (hoặc chế độ xem) của máy tính có thể hiển thị màn hình và các nút. Nhưng vẫn không có cách nào để cập nhật thông tin hiển thị trên màn hình. Bạn có thể khắc phục điều này bằng cách thêm một số phương pháp bổ sung:

  1. .setDisplayText() để thiết lập và cập nhật văn bản của màn hình
  2. .displayText() để lấy văn bản của màn hình hiện tại
  3. .clearDisplay() để xóa văn bản của màn hình

Các phương thức này sẽ tạo thành giao diện công khai GUI và hoàn thành lớp chế độ xem cho máy tính Python của bạn. Đây là cách triển khai khả thi:

class PyCalcUi(QMainWindow):
    # Snip
    def setDisplayText(self, text):
        """Set display's text."""
        self.display.setText(text)
        self.display.setFocus()

    def displayText(self):
        """Get display's text."""
        return self.display.text()

    def clearDisplay(self):
        """Clear the display."""
        self.setDisplayText('')

Đây là những gì mỗi chức năng làm:

  • .setDisplayText()sử dụng .setText()để đặt và cập nhật văn bản của màn hình cũng .setFocus()như đặt tiêu điểm của con trỏ trên màn hình.

  • .displayText()là một phương thức getter trả về văn bản hiện tại của màn hình. Khi người dùng nhấp vào dấu bằng ( =), chương trình sẽ sử dụng giá trị trả về .displayText()là biểu thức toán học được đánh giá.

  • .clearDisplay()đặt văn bản của màn hình thành một chuỗi rỗng ( '') để người dùng có thể giới thiệu một biểu thức toán học mới.

Bây giờ GUI của máy tính của bạn đã sẵn sàng! Khi chạy ứng dụng, bạn sẽ thấy một cửa sổ như sau:

Hướng dẫn dùng pyqt python

Bạn đã hoàn thành giao diện GUI của máy tính. Tuy nhiên, nếu bạn cố gắng thực hiện một số phép tính, thì bạn sẽ nhận thấy rằng máy tính vẫn chưa thực hiện được bất kỳ điều gì. Đó là bởi vì bạn chưa triển khai mô hình hoặc bộ điều khiển. Tiếp theo, bạn sẽ thêm một lớp bộ điều khiển cơ bản để bắt đầu mang lại sức sống cho máy tính của mình.

Tạo bộ điều khiển cơ bản

Trong phần này, bạn sẽ viết mã lớp bộ điều khiển của máy tính. Lớp này sẽ kết nối khung nhìn với mô hình. Bạn sẽ sử dụng lớp bộ điều khiển để làm cho máy tính thực hiện các hành động theo các sự kiện của người dùng. Bạn sẽ bắt đầu với việc nhập sau:

from functools import partial

Ở đầu pycalc.py, bạn nhập partial()để kết nối tín hiệu với các phương thức cần thêm đối số.

Lớp bộ điều khiển của bạn cần thực hiện ba tác vụ chính:

  1. Truy cập giao diện công khai của GUI
  2. Xử lý việc tạo các biểu thức toán học
  3. Kết nối clickedtín hiệu nút với các khe cắm thích hợp

Điều này sẽ đảm bảo rằng máy tính của bạn đang hoạt động chính xác. Đây là cách bạn viết mã lớp bộ điều khiển:

# Create a Controller class to connect the GUI and the model
class PyCalcCtrl:
    """PyCalc Controller class."""
    def __init__(self, view):
        """Controller initializer."""
        self._view = view
        # Connect signals and slots
        self._connectSignals()

    def _buildExpression(self, sub_exp):
        """Build expression."""
        expression = self._view.displayText() + sub_exp
        self._view.setDisplayText(expression)

    def _connectSignals(self):
        """Connect signals and slots."""
        for btnText, btn in self._view.buttons.items():
            if btnText not in {'=', 'C'}:
                btn.clicked.connect(partial(self._buildExpression, btnText))

        self._view.buttons['C'].clicked.connect(self._view.clearDisplay)

Điều đầu tiên bạn làm là đưa ra PyCalcCtrlmột thể hiện của khung nhìn PyCalcUi. Bạn sẽ sử dụng phiên bản này để có toàn quyền truy cập vào giao diện công khai của chế độ xem. Tiếp theo, bạn tạo ._buildExpression()để xử lý việc tạo biểu thức toán học. Phương pháp này cũng cập nhật màn hình của máy tính để đáp ứng với đầu vào của người dùng.

Cuối cùng, bạn sử dụng ._connectSignals()để kết nối các nút có thể in với ._buildExpression(). Điều này cho phép người dùng của bạn tạo biểu thức toán học bằng cách nhấp vào các nút của máy tính. Ở dòng cuối cùng, bạn kết nối nút xóa ( C) với ._view.clearDisplay(). Phương pháp này sẽ xóa văn bản trên màn hình.

Để lớp bộ điều khiển mới này hoạt động, bạn cần cập nhật main():

# Client code
def main():
    """Main function."""
    # Create an instance of QApplication
    pycalc = QApplication(sys.argv)
    # Show the calculator's GUI
    view = PyCalcUi()
    view.show()
    # Create instances of the model and the controller
    PyCalcCtrl(view=view)
    # Execute calculator's main loop
    sys.exit(pycalc.exec_())

Đoạn mã này tạo một phiên bản của PyCalcCtrl(view=view)với giá trị viewđược truyền vào làm đối số. Thao tác này sẽ khởi tạo bộ điều khiển và kết nối các tín hiệu và khe cắm để cung cấp cho máy tính của bạn một số chức năng.

Nếu bạn chạy ứng dụng, thì bạn sẽ thấy một cái gì đó như sau:

Như bạn có thể thấy, máy tính đã có một số chức năng hữu ích! Bây giờ, bạn có thể xây dựng các biểu thức toán học bằng cách nhấp vào các nút. Lưu ý rằng dấu bằng ( =) chưa hoạt động. Để khắc phục điều này, bạn cần triển khai mô hình của máy tính.

Thực hiện mô hình

Mô hình là lớp mã quản lý logic nghiệp vụ. Trong trường hợp này, logic kinh doanh là tất cả về các phép tính toán học cơ bản. Mô hình của bạn sẽ đánh giá các biểu thức toán học do người dùng của bạn giới thiệu. Vì mô hình cần xử lý lỗi, bạn sẽ xác định hằng số chung sau:

Đây là thông báo mà người dùng sẽ thấy nếu họ đưa ra một biểu thức toán học không hợp lệ.

Mô hình của bạn sẽ là một chức năng duy nhất:

# Create a Model to handle the calculator's operation
def evaluateExpression(expression):
    """Evaluate an expression."""
    try:
        result = str(eval(expression, {}, {}))
    except Exception:
        result = ERROR_MSG

    return result

Ở đây, bạn sử dụng eval()để đánh giá một chuỗi dưới dạng một biểu thức. Nếu điều này thành công, thì bạn sẽ trả về kết quả. Nếu không, bạn sẽ trả lại thông báo lỗi. Lưu ý rằng chức năng này không hoàn hảo. Nó có một số vấn đề quan trọng:

  • Các try...exceptkhối không bắt bất kỳ ngoại lệ cụ thể, mà không phải là một thực hành tốt nhất trong Python.
  • Chức năng này dựa trên việc sử dụng eval(), có thể dẫn đến một số vấn đề bảo mật nghiêm trọng . Lời khuyên chung là chỉ sử dụng eval()trên đầu vào đáng tin cậy.

Bạn có thể tự do làm lại chức năng để làm cho nó trở nên đáng tin cậy và an toàn hơn. Đối với hướng dẫn này, bạn sẽ sử dụng chức năng như hiện tại.

Hoàn thiện bộ điều khiển

Khi bạn đã hoàn thành mô hình của máy tính, bạn có thể hoàn thành bộ điều khiển. Phiên bản cuối cùng của PyCalcCtrlsẽ bao gồm logic để xử lý các phép tính và đảm bảo dấu bằng ( =) hoạt động chính xác:

# Create a Controller class to connect the GUI and the model
class PyCalcCtrl:
    """PyCalc's Controller."""
    def __init__(self, model, view):
        """Controller initializer."""
        self._evaluate = model
        self._view = view
        # Connect signals and slots
        self._connectSignals()

    def _calculateResult(self):
        """Evaluate expressions."""
        result = self._evaluate(expression=self._view.displayText())
        self._view.setDisplayText(result)

    def _buildExpression(self, sub_exp):
        """Build expression."""
        if self._view.displayText() == ERROR_MSG:
            self._view.clearDisplay()

        expression = self._view.displayText() + sub_exp
        self._view.setDisplayText(expression)

    def _connectSignals(self):
        """Connect signals and slots."""
        for btnText, btn in self._view.buttons.items():
            if btnText not in {'=', 'C'}:
                btn.clicked.connect(partial(self._buildExpression, btnText))

        self._view.buttons['='].clicked.connect(self._calculateResult)
        self._view.display.returnPressed.connect(self._calculateResult)
        self._view.buttons['C'].clicked.connect(self._view.clearDisplay)

Các dòng mã mới được đánh dấu. Đầu tiên, bạn thêm một tham số mới vào hàm init. Bây giờ lớp nhận được các cá thể từ cả mô hình và khung nhìn. Sau đó ._calculateResult(), bạn lấy nội dung của màn hình, đánh giá nó như một biểu thức toán học, và cuối cùng là hiển thị kết quả trong màn hình.

Bạn cũng thêm một ifcâu lệnh ._buildExpression()để kiểm tra xem có lỗi xảy ra hay không. Nếu vậy, bạn xóa màn hình và bắt đầu lại với một biểu thức mới. Cuối cùng, bạn thêm hai kết nối nữa vào bên trong ._connectSignals(). Đầu tiên cho phép dấu bằng ( =). Thứ hai đảm bảo rằng khi người dùng nhấn Enter, máy tính sẽ xử lý biểu thức như mong đợi.

Để tất cả mã này hoạt động, bạn cần cập nhật main():

# Client code
def main():
    """Main function."""
    # Create an instance of `QApplication`
    pycalc = QApplication(sys.argv)
    # Show the calculator's GUI
    view = PyCalcUi()
    view.show()
    # Create instances of the model and the controller
    model = evaluateExpression
    PyCalcCtrl(model=model, view=view)
    # Execute calculator's main loop
    sys.exit(pycalc.exec_())

Ở đây, của bạn modelcó một tham chiếu đến evaluateExpression(). Ngoài ra, PyCalcCtrl()bây giờ nhận được hai đối số: the modelvà view.

Chạy Máy tính

Bây giờ bạn đã hoàn thành mã, đã đến lúc kiểm tra! Nếu bạn chạy ứng dụng, thì bạn sẽ thấy một cái gì đó như thế này:

Để sử dụng PyCalc, hãy nhập một biểu thức toán học hợp lệ bằng chuột của bạn. Sau đó, nhấn Enterhoặc nhấp vào dấu bằng ( =) để xem kết quả trên màn hình máy tính.

Chúc mừng! Bạn đã phát triển ứng dụng máy tính để bàn GUI đầy đủ chức năng đầu tiên của mình với Python và PyQt!

Công cụ bổ sung

PyQt5 cung cấp một bộ công cụ bổ sung khá hữu ích để giúp bạn xây dựng các ứng dụng GUI vững chắc, hiện đại và đầy đủ tính năng. Dưới đây là một số công cụ đáng chú ý nhất mà bạn có thể sử dụng:

  • Qt Designer
  • Bộ công cụ quốc tế hóa
  • Hệ thống tài nguyên PyQt5

Qt Designer là công cụ Qt để thiết kế và xây dựng giao diện người dùng đồ họa. Bạn có thể sử dụng nó để thiết kế widget, hộp thoại hoặc hoàn thành các cửa sổ chính bằng cách sử dụng các biểu mẫu trên màn hình và cơ chế kéo và thả. Hình sau cho thấy một số tính năng của Nhà thiết kế Qt:

Qt Designer sử dụng các .uitệp XML để lưu trữ các thiết kế GUI của bạn. Bạn có thể tải chúng bằng QUiLoader. PyQt bao gồm một mô-đun gọi là uic để trợ giúp việc này. Bạn cũng có thể chuyển đổi .uinội dung tệp thành mã Python bằng một công cụ dòng lệnh được gọi là pyuic5.

PyQt5 cũng cung cấp một bộ công cụ toàn diện để quốc tế hóa các ứng dụng sang ngôn ngữ địa phương. pylupdate5tạo và cập nhật .tscác tệp dịch ( ). Sau đó, Qt Linguist cập nhật các .tstệp đã tạo với bản dịch của các chuỗi. Nó cũng phát hành các .tstệp dưới dạng .qmtệp. Các .qmtệp này là các tệp tương đương nhị phân nhỏ gọn có thể được sử dụng trực tiếp bởi ứng dụng.

Cuối cùng, bạn có thể sử dụng hệ thống tài nguyên PyQt5 , đây là một cơ sở để nhúng các tài nguyên như biểu tượng và tệp dịch. Để sử dụng công cụ này, bạn cần tạo một .qrctệp. Đây là một tệp XML được sử dụng để chỉ định tệp tài nguyên nào sẽ được nhúng. Khi bạn đã có sẵn tệp này, bạn có thể sử dụng pyrcc5để tạo mô-đun Python có chứa các tài nguyên được nhúng.

Phần kết luận

Các ứng dụng máy tính để bàn Giao diện người dùng đồ họa (GUI) vẫn chiếm thị phần đáng kể trên thị trường phát triển phần mềm. Python cung cấp một số khung và thư viện có thể giúp bạn phát triển các ứng dụng GUI hiện đại và mạnh mẽ.

Trong hướng dẫn này, bạn đã học cách sử dụng PyQt , được cho là một trong những thư viện phổ biến và vững chắc nhất để phát triển ứng dụng GUI trên máy tính để bàn bằng Python. Bây giờ bạn đã biết cách sử dụng hiệu quả cả Python và PyQt để xây dựng các ứng dụng máy tính để bàn GUI hiện đại.

Bây giờ bạn có thể:

  • Tạo giao diện người dùng đồ họa với Python và PyQt
  • Kết nối các sự kiện của người dùng với các hành động cụ thể trong ứng dụng của bạn
  • Tạo các ứng dụng máy tính để bàn GUI đầy đủ chức năng để giải quyết các vấn đề trong thế giới thực

Giờ đây, bạn có thể sử dụng Python và PyQt để mang lại sức sống cho các ứng dụng GUI trên máy tính để bàn của mình! Bạn có thể lấy mã nguồn cho dự án máy tính và tất cả các ví dụ mã tại liên kết bên dưới:

Đọc thêm

Nếu bạn muốn tìm hiểu sâu hơn về PyQt và các công cụ liên quan của nó, thì bạn có thể xem qua một số tài nguyên sau:

  • Tài liệu PyQt5
  • Tài liệu PyQt4
  • Tài liệu Qt v5
  • PyQt Wiki
  • Lập trình GUI nhanh chóng với Python và Qt
  • Hướng dẫn sử dụng Qt Designer
  • Tài liệu Qt cho Python ( PySide2)

Mặc dù Tài liệu PyQt5 là tài nguyên đầu tiên được liệt kê ở đây, một số phần quan trọng vẫn còn thiếu hoặc chưa hoàn thiện. May mắn thay, bạn có thể sử dụng Tài liệu PyQt4 để điền vào chỗ trống. Các lớp tham khảo đặc biệt hữu ích để đạt được một sự hiểu biết đầy đủ về các widget và các lớp học.

Nếu bạn đang sử dụng tài liệu PyQt4 làm tài liệu tham khảo cho các lớp PyQt5, thì hãy nhớ rằng các lớp sẽ hơi khác nhau và cũng có thể hoạt động khác nhau. Một tùy chọn khác là sử dụng Tài liệu Qt v5 gốc và Tài liệu Tham khảo Lớp của nó để thay thế. Trong trường hợp này, bạn có thể cần một số kiến ​​thức nền tảng về C ++ để hiểu đúng các mẫu mã.

Hướng dẫn dùng pyqt python

Các khóa học qua video:
Lập trình C Java C# SQL Server PHP HTML5-CSS3-JavaScript
« Prev: Python: Các kiểu dữ liệu cơ bản trong Python
» Next: Python: Bố cục PyQt: Tạo các ứng dụng GUI chuyên nghiệp

Copied !!!