3.6. Cách sử dụng tài liệu Qt

Theo 1 khía cạnh nào đó, đây là bài học quan trọng nhất trong cả chương thảo luận của chúng ta về Qt bởi chính nó sẽ hướng dẫn cách sử dụng tài liệu kỹ thuật của thư viện này.

Tại sao lại nói là biết cách sử dụng bộ tài liệu kiểu như này là quan trọng ? Đơn giản là bởi vì sự tồn tại của chúng đối với các lập trình viên giống như là sự tồn tại của các quyển thánh kinh vậy. Những tài liệu này có thể giải thích tất cả khả năng mà 1 ngôn ngữ hay 1 thư viện có thể cung cấp cho chúng ta.

Ví như tài liệu của Qt thì đương nhiên là chứa tất cả các chức năng của Qt. Tôi xin nhấn mạnh là tất cả.

Bộ tài liệu này có thể coi là hướng dẫn đầy đủ nhất về thư viện chúng ta đang tìm hiểu. Tuy nhiên, giống như đa phần các bộ tài liệu của các ngôn ngữ lập trình, tài liệu này được trình bày theo bố cục khá đặc biệt.

Trước tiên thì các bạn cần chuẩn bị tinh thần là tài liệu này được viết hoàn toàn bằng tiếng Anh (như hầu hết các tài liệu tin học khác). Vậy nên dù muốn dù không, các bạn cũng cần phải có 1 số kiến thức tối thiểu về tiếng Anh kỹ thuật.

Như đã nói, tài liệu được trình bày theo cách khá đặc biệt, có thể nói là khá định hướng. Vậy nên chúng ta sẽ cần biết tìm đến thông tin cần thiết 1 cách hiệu quả nhất trong tổng thể thông tin khổng lồ đó.

Bài học này sẽ là chỗ chúng ta cùng thảo luận về vấn đề trên.

Nơi lưu trữ tài liệu

Tôi đã nói với các bạn là Qt cung cấp cho chúng ta 1 bộ tài liệu hướng dẫn vô cùng đầy đủ. Tuy nhiên trước khi sử dụng thì chúng ta cần phải biết đi đâu để tìm được nó đã.

Chúng ta có 2 nơi có thể tìm thấy tài liệu này :

  • Nếu các bạn có thể truy cập vào Internet : tài liệu có thể tìm được trong trang web chính thức của Qt.
  • Nếu các bạn không thể truy cập vào mạng : chương trình QtCreator có chứa 1 phiên bản của tài liệu này .

Cá nhân tôi thì tôi thường truy cập trực tiếp vào tài liệu trực tuyến trong trang web chính thức của thư viện theo địa chỉ : http://doc.qt.io/

! Các bạn có thể thêm đường dẫn trên vào danh sách đánh dấu của trình duyệt. Điều này giúp các bạn truy cập tới trang này dễ dàng hơn cũng như dễ tạo thói quen sử dụng tài liệu này.

1 trong những ưu điểm của tài liệu trực tuyến là chúng ta có thể đảm bảo là nó luôn được cập nhật nội dung mới nhất. Ưu điểm này sẽ được thể hiện rõ nhất khi thư viện thêm vào những tính năng mới hay cập nhật các sửa lỗi.

Dưới đây là hình ảnh khi các bạn truy cập vào địa chỉ bên trên.  

Chúng ta sẽ cùng đề cập tới các mảng khác nhau của trang web trên trong phần tiếp theo.

! Nếu các bạn không có mạng Internet thì cũng không cần hoảng loạn. Các bạn có thể truy cập vào tài liệu này nhờ nút « Help » trong giao diện của QtCreator. Đương nhiên là tôi không dám đảm bảo là nó được cập nhật bản mới nhất.

Các mảng của tài liệu

Trong trang web của tài liệu thì chúng ta có thể thấy 6 mảng lớn. Cái mà chúng ta cần quan tâm sẽ  là mảng « Advanced Topics », trong đó có chứa :

  • Qt Reference Documentation
  • Development Topics

Ngoài ra chúng ta cũng có thể tham khảo phần « Getting Started ». Trong đó có chứa 1 số ví dụ khá hữu ích khi chúng ta mới học dùng Qt.

Dưới đây là những kiến thức mà chúng ta quan tâm.

Qt Reference Documentation

Đây là phần miêu tả tất cả các tính năng của Qt. Không dễ dàng cho những người mới bắt đầu sử dụng, thế nhưng đây là phần quan trọng nhất của tài liệu.

  • Các lớp C++ : danh sách tất cả các lớp của Qt. Chúng ta có thể thấy rất nhiều lớp. Đây là phần mà chúng ta hay sử dụng nhất.
  • Các module của Qt : chúng ta có tên các module của Qt cũng như các lớp chứa trong nó. Các bạn đại khái có thể nhận ra 1 chút cấu trúc tổng thể của thư viện mà chúng ta đang thao tác.
  • QML : tài liệu của ngôn ngữ QML giúp tạo ra các cửa sổ 1 cách nhanh chóng. Chúng ta sẽ không đề cập nhiều đến nó ở đây.
  • QtCreator : hướng dẫn sử dụng hiệu quả QtCreator.

Ngoài ra, chức năng mà chúng ta sẽ thường xuyên sử dụng chính là khung tìm kiếm ở phía trên bên phải của trang web. Khi mà chúng ta có thắc mắc về 1 tính năng hay 1 phương thức  của lớp nào đó, chỉ cần gõ vào khung tìm kiếm và chúng ta sẽ dễ dàng nhận được những kết quả định hướng đến câu trả lời đang tìm kiếm.

Development Topics

Đây là tập hợp các trang hướng dẫn, không chỉ để giới thiệu về Qt, mà còn giúp cho người dùng như chúng ta có thể tận dụng mọi tính năng mà thư viện cung cấp. Các trang này được phân chia theo những đề tài thảo luận khác nhau. Các bạn sẽ cần đến 1 vốn tiếng Anh kha khá để sử dụng được chúng.

Nội dung của phần này khá thú vị dành cho những bạn nào muốn tìm hiểu sau và nắm rõ về thư viện. Tuy nhiên chúng ta sẽ không đề cập nhiều hơn trong bài học này vì ở đây, tôi chỉ muốn đưa ra cho các bạn cái nhìn khái quát nhất. Nếu thấy hứng thú thì vẫn cần chính các bạn tự đi tìm hiểu.

Nội dung tài liệu về các lớp

Thế là chúng ta đã đến phần quan trọng cũng như hấp dẫn nhất của bài học này : tìm hiểu cách tài liệu mô tả 1 lớp bất kỳ trong Qt.

Mỗi lớp trong Qt đều có 1 trang riêng trong tài liệu này, ngắn hay dài tùy vào độ phức tạp của lớp. Các bạn có thể tìm thấy tất cả những gì mình cần trên lớp mục tiêu trong trang này.

Trong ví dụ tiếp đây, chúng ta sẽ cùng nghiên cứu lớp QLineEdit.

! Khi các bạn đã biết tên lớp và muốn tìm hiểu thông tin về lớp đó, hãy dùng khung tìm kiếm hoặc sử dụng đường dẫn “All Classes” trong mục lục để tới trang mô tả lớp.

Trên đây là hình ảnh trang tư liệu của lớp QLineEdit. Tất cả các trang tài liệu đều sẽ tuân theo bố cục giống hệt nhau. Tiếp theo đây chúng ta sẽ nghiên cứu lần lượt từng phần.

Giới thiệu

Ngay đầu trang, chúng ta có thể dễ dàng thấy được 1 đoạn giới thiệu nho nhỏ về công dụng của lớp. Với QLineEdit, chúng ta có “The QLineEdit widget is a one-line text editor”, nghĩa là widget này là 1 ô nằm trên 1 dòng dùng để nhập văn bản.

Đường dẫn “More …” sẽ dẫn chúng ta tới 1 phần mô tả chi tiết hơn về lớp. Các bạn có thể coi đây là 1 bản hướng dẫn nho nhỏ về cách sử dụng lớp này. Tôi khuyên các bạn nên đọc nó mỗi khi các bạn cần thao tác với 1 lớp mà các bạn chưa từng động tới trước đây và không biết phải bắt đầu từ đâu để tìm hiểu nó.

Tiếp đó sẽ là những dòng tiêu đề chúng ta cần thêm vào mã nguồn khi chúng ta muốn sử dụng lớp.

#include <QLineEdit>

Ngay tiếp theo, chúng ta sẽ có thông tin về các lớp mà lớp chúng ta đang nghiên cứu kế thừa. Trong ví dụ của chúng ta thì QLineEdit kế thừa từ lớp QWidget nên nó sẽ sở hữu tất cả thuộc tính cũng như phương thức của QWidget.

Public Types

Trong một số trường hợp, các lớp tự định nghĩa một số kiểu dữ liệu riêng để sử dụng. Chúng ta gọi đó là kiểu liệt kê.

Với QLineEdit, chúng ta 2 kiểu liệt kê đó là EchoModeActionPosition. Mỗi kiểu dữ liệu này đều có các giá trị riêng của nó.

! 1 kiểu liệt kê thực chất chỉ là 1 tập hợp các giá trị mà chúng ta có thể dùng trong 1 số phương thức đặc biệt. Trong ví dụ của chúng ta thì phương thức đặc biệt đó là setEchoMode(EchoMode) của QLineEdit vì phương thức này chỉ nhận tham số kiểu EchoMode. Để truyền 1 giá trị EchoMode như Password cho phương thức này, chúng ta cần sử dụng cú pháp : setEchoMode(QLineEdit::Password).

Properties

Phần tiếp theo liệt kê ra tất cả các tính chất của lớp mà chúng ta có thể truy cập để đọc và thay đổi.

? Các tính chất này khác gì các thuộc tính của lớp ?

Thực ra thì chúng chính là các thuộc tính. Tuy nhiên, trong tài liệu sẽ chỉ liệt kê ra các thuộc tính mà người dùng có thể tác động thông qua các phương thức truy cập (“lấy” và “đặt”). Ngoài ra, lớp có thể sở hữu rất nhiều thuộc tính khác mà tài liệu không đề cập tới, đơn giản vì chúng chả liên quan gì tới chúng ta cả.

Tóm lại là các tính chất chính là các thuộc tính mà chúng ta có thể tiếp xúc được. Như tôi đã từng nhắc đến trong bài học trước, Qt tuân thủ 1 số quy tắc đặt tên khi tạo ra các phương thức truy cập.

  • thuocTinh() : phương thức lấy cho phép đọc giá trị của thuộc tính.
  • setThuocTinh() : phương thức đặt cho phép thay đổi giá trị của thuộc tính.

Hãy thử áp dụng quy tắc này cho thuộc tính text của lớp. Thuộc tính này lưu trữ giá trị văn bản dược người dùng nhập vào.

Như trong tài liệu đã nói, text là 1 đối tượng kiểu QString nên các thao tác của chúng ta sẽ xoay quanh đối tượng thuộc kiểu này.

Dưới đây là đoạn mã để lấy giá trị của thuộc tính này.

QLineEdit vanBan("Xin chào");
QString noiDung = vanBan.text();

… và cách để thay đổi nó.

QLineEdit vanBan;
vanBan.setText("Nhập tên bạn vào đây");

Các bạn hãy để ý rằng trong trang tài liệu chúng ta đang tham khảo, « text » là 1 đường dẫn. Nếu các bạn ấn vào đường dẫn trên, chúng ta sẽ được đưa tới phần giới thiệu chi tiết về thuộc tính, nằm ở bên dưới của trang tài liệu. Ở đây, tài liệu sẽ đưa ra cho chúng ta nguyên mẫu của các phương thức truy cập.

  • QString text () const
  • void setText ( const QString & )

Cuối cùng, đôi khi chúng ta sẽ bắt gặp ghi chú “See also” (nghĩa là Xem thêm) đề xuất cho chúng ta 1 số thuộc tính hoặc phương thức có liên quan ít nhiều đến thuộc tính chúng ta đang tra cứu. Ở trong ví dụ của chúng ta thì có thể thấy 2 phương thức insert()clear(). Lấy ví dụ trường hợp của phương thức clear() thì liên quan ở đây là phương thức cho phép xóa nội dung được lưu trong thuộc tính text đang xét.

! Rất quan trọng, cần chú ý là ở trong phần liệt kê các thuộc tính, chúng ta sẽ thấy có nhắc đến “59 properties inherited from QWidget” và “1 property inherited from QObject”. Bởi vì QLineEdit vốn là lớp con của QWidget, cũng có nghĩa là lớp cháu của QObject, vậy nên lớp này sẽ sở hữu tất cả thuộc tính và phương thức của các lớp tổ tiên.

Cụ thể hơn thì chúng ta có thể hiểu là những thuộc tính được nêu trong danh sách chỉ là 1 phần những tính năng mà QLineEdit cung cấp cho chúng ta. Nếu chúng ta theo đường dẫn tới lớp QWidget thì chúng ta cũng sẽ có danh sách các thuộc tính có thể sử dụng được cung cấp bởi QWidget. Chúng ta cũng có thể tác động đến các thuộc tính này ở QLineEdit vì tuân thủ theo nguyên tắc kế thừa.

Điều này cũng đồng nghĩa với việc không gì ngăn cản chúng ta sử dụng những thuộc tính như width (chiều rộng) hay height (chiều cao) vốn là các thuộc tính chung của tất cả các widget. Đến đây thì các bạn đã cảm nhận thấy sức mạnh của tính kế thừa rồi chứ.

 Dù đã nói nhiều lần nhưng tôi xin phép được nhắc lại, luôn đảm bảo rằng những xử lý các bạn không tìm thấy trong 1 lớp cũng sẽ không thể được tìm thấy trong các lớp tổ tiên của nó trước khi tự mình viết những xử lý này bởi có thể các bạn sẽ tốn thời gian vô ích. Tất cả là nhờ tính chất của tính kế thừa đã được áp dụng triệt để trong Qt.

Public Functions

Đây lại cũng là 1 phần quan trọng mà chúng ta thường xuyên sử dụng đến. Ở đây, chúng ta sẽ tìm thấy tất cả các phương thức của lớp mà quyền truy cập là “public”, trong đó bao gồm :

  • Các phương thức khởi tạo, rất thiết thực để biết làm sao tạo ra các đối tượng
  • Các phương thức truy cập của lớp (như text()setText() đã nói ở trên)
  • Các phương thức thực hiện 1 số xử lý hay gặp liên quan tới lớp

Hãy ấn vào đường dẫn của từng phương thức để có thể hiểu rõ hơn nhiệm vụ cũng như cách hoạt động của từng phương thức.

Phân tích các nguyên mẫu

Mỗi nguyên mẫu của phương thức đều cung cấp cho chúng ta rất nhiều thông tin. Vậy nên mỗi khi muốn sử dụng 1 phương thức nào đó, các bạn trước hết hãy chú ý kỹ nguyên mẫu của nó.

Lấy ví dụ về phương thức khởi tạo của lớp.

  • QLineEdit ( QWidget * parent = 0 )
  • QLineEdit ( const QString & contents, QWidget * parent = 0 )

Chúng ta có thể dễ dàng thấy rằng 1 số tham số không phải bắt buộc. Nếu ấn vào đường dẫn của 1 trong số những phương thức khởi tạo này, trang web sẽ đưa chúng ta tới phần giải thích ý nghĩa của từng tham số cần sử dụng.

Chỉ cần dựa vào các nguyên mẫu này, chúng ta cũng có thể thấy được là bởi vì có sự tồn tại của các tham số không bắt buộc nên chúng ta có đến 4 cách khác nhau để tạo ra 1 đối tượng.

QLineEdit vanBan();
QLineEdit vanBan(cuaSo);
QLineEdit vanBan("Nhập văn bản");
QLineEdit vanBan("Nhập văn bản", cuaSo);

Cung cấp thông tin về các tham số mà chúng ta không hiểu

? Trong danh sách tôi có thấy những phương thức như setAlignement() cần những tham số với kiểu dữ liệu mà tôi không biết thì phải làm sao ?

Các bạn không cần quá lo lắng bởi trong rất nhiều trường hợp các phương thức đòi hỏi kiểu tham số mà chúng ta không biết. Thế nhưng chỉ cần ấn vào đường dẫn (vâng, lại là 1 đường dẫn) đi kèm trong tên kiểu dữ liệu đó, chúng ta sẽ được chuyển đến trang giải thích rõ kiểu dữ liệu mà chúng ta đang cần thực sự là gì.

Thông thường thì có 2 khả năng có thể xảy ra :

  • Kiểu liệt kê : như setAlignement() trong câu hỏi cần tham số kiểu Qt::Alignment là 1 kiểu như thế. Kiểu này đơn giản là 1 dãy giá trị. Chúng ta chỉ chọn ra giá trị cần sử dụng trong các giá trị được ghi trong trang của Qt::Alignment như Qt::AlignCenter chẳng hạn.
vanBan.setAlignment(Qt::AlignCenter);
  • Các lớp : đôi khi các phương thức lại yêu cầu tham số là 1 đối tượng thuộc 1 lớp mới lạ. Trường hợp này phức tạp hơn, cần chúng ta đi tìm hiểu lớp đó và học cách tạo ra các đối tượng để có thể truyền như là tham số của phương thức.

Để phân tích trường hợp thứ 2, chúng ta hãy cùng xem xét phương thức setValidator() dùng để xác nhận xem người dùng nhập có phải là văn bản hợp lệ không. Nó sẽ giúp chúng ta đảm bảo người dùng điền 1 số chứ không phải 1 ký tự khi được yêu cầu nhập số tuổi chẳng hạn. Phương thức này cần tham số kiểu QValidator.

Nếu đi theo đường dẫn QValidator, chúng ta sẽ được hướng đến trang tài liệu của lớp QValidator. Hãy đọc giới thiệu để hiểu sơ qua về lớp rồi quan sát các phương thức để có thể tạo ra 1 đối tượng của lớp này.

Đôi khi, mọi việc trở nên thật rắc rối vì lớp được yêu cầu lại là 1 lớp trừu tượng nên không thể thực thể hóa được. QValidator chính là rơi vào tình huống này. Vậy nên chúng ta sẽ cần phải tạo ra đối tượng thuộc 1 lớp con của nó để giải quyết vấn đề.

Ở đầu trang tài liệu của QValidator, chúng ta có thể dễ dàng thấy “Inherited by QDoubleValidator, QIntValidator, and QRegExpValidator”. Điều này có nghĩa là các lớp đó đều là lớp con của QValidator nên chúng ta đều có thể sử dụng.

Bây giờ giả dụ chúng ta muốn là người dùng chỉ nhập vào 1 số nguyên, vậy chúng ta sẽ cần tạo ra 1 đối tượng QIntValidator. Hãy tùy ý chọn ra 1 phương thức khởi tạo mà các bạn thấy hợp và tạo ra 1 đối tượng làm tham số.

Tóm tắt lại, để gọi phương thức setValidator(), chúng ta sẽ phải làm như sau :

QValidator *validator = new QIntValidator(0, 150, this);
vanBan.setValidator(validator);

Đoạn mã trên sẽ đảm bảo là người dùng chỉ có thể nhập vào 1 số nguyên nằm giữa 0 và 150.

Tất cả chỉ để nói lên rằng các bạn đừng ngại tra cứu tài liệu về 1 lớp mới khi mà bạn chưa sử dụng bao giờ. Đôi khi, chúng ta thậm chí còn phải đọc cả về các lớp con của nó mới đủ.

Tôi đảm bảo rằng khi đã quen thuộc với tài liệu này, các bạn sẽ thấy thật dễ dàng để sử dụng các lớp của Qt, dù đôi khi trả giá bằng thời gian để nghiên cứu 2 đến 3 trang tài liệu.

Public Slots

Các slot cũng là các phương thức của lớp, chỉ khác là chúng có liên kết với 1 tín hiệu. Chúng ta đã cùng tìm hiểu cơ chế này trong bài học trước. Chú ý là không ai cấm các bạn gọi sử dụng các slot này 1 cách thông thường như 1 phương thức.

Ví dụ như slot undo() dùng để hủy bỏ xử lý trước đó, chúng ta hoàn toàn có thể sử dụng như 1 phương thức cổ điển

vanBan.undo();

… hay kết nối nó với 1 widget để thực hiện những xử lý dây chuyền mong muốn.

! Những slot được trình bày trong danh sách hoàn toàn không phải là tất cả các slot được cung cấp bởi QLineEdit. Như các bạn có thể thấy, dòng chữ “19 public slots inherited from QWidget” thông báo cho chúng ta rằng có 1 số slot khác có thể được sử dụng được kế thừa từ lớp QWidget.

Signals

Đây là danh sách các tín hiệu có thể được gửi đi bởi QLineEdit. 1 tín hiệu thực chất là 1 sự kiện diễn ra và được kết nối với 1 slot.

Xin phép được nhắc lại 1 lần nữa, đừng quên những tín hiệu được kế thừa từ lớp mẹ QWidget. Càng nhắc nhiều hy vọng các bạn sẽ càng nhanh ghi nhớ được nguyên tắc này.

Protected Functions

Trong phần này là danh sách những phương thức với quyền truy cập protected. Nếu các bạn đã quên thì tôi sẽ nhắc lại, đây là quyền truy cập gần như private (nghĩa là người dùng bên ngoài không thể sử dụng được) nhưng khác là nếu chúng ta tạo ra 1 lớp con kế thừa từ lớp đang xét thì chúng ta vẫn có thể truy cập vào thành viên được bảo vệ bởi quyền truy cập này.

Vậy nên nếu bạn đang có ý định tạo ra 1 lớp con của QLineEdit thì các bạn có thể sử dụng các phương thức này từ bên trong lớp con đó.

Additional Inherited Members

Nếu đến lúc này vẫn còn các thành viên được kế thừa từ các lớp tổ tiên mà chưa được nhắc đến trong các phần trên thì chúng sẽ được đặt trong phần này.

Trong ví dụ thì lớp QLineEdit không định nghĩa bất cứ phương thức tĩnh nào. Thế nhưng lớp này lại thừa kế 1 số phương thức tĩnh từ QWidgetQObject. Vậy thì những phương thức đó sẽ được nêu ở đây.

Detailed description

Phần này là 1 bản mô tả chi tiết cách hoạt động của lớp. Đây chính là phần được kết nối bởi đường dẫn “Xem thêm” mà chúng ta đã nhắc đến trong phần đầu.

Tôi khuyên các bạn nên đọc phần này nếu lần đầu tiên tiếp xúc với 1 lớp là vì phần này giải thích khá rõ cách mà lớp cần được sử dụng.

Tóm tắt bài học :
  • Tài liệu của Qt là không thể thiếu nếu các bạn đang làm việc với thư viện này. Các bạn sẽ cần tra cứu đến nó thường xuyên
  • Tài liệu này ghi lại tất cả những tính năng Qt có thể cung cấp cho người dùng 1 cách chi tiết nhất.
  • 1 số khó khăn ban đầu khi tiếp xúc là ngôn ngữ dùng để viết tài liệu cũng như cấu trúc của tài liệu. Khi chúng ta quen dần thì sẽ không thấy nó quá phức tạp nữa.
  • 1 lớp của Qt được kế thừa từ nhiều lớp khác. Vậy nên khi tra cứu 1 lớp Qt thì chúng ta cũng nên tra cứu tất cả các tính chất được kế thừa từ các lớp tổ tiên.
  • Sử dụng các đường dẫn để khám phá tất cả các lớp liên quan khi muốn sử dụng 1 tính năng của 1 lớp nào đó.
  • Tốt nhất, hãy khiến việc tra cứu tài liệu trở thành thói quen. Như thế sẽ giúp chúng ta không bối rối khi bắt gặp những lớp mới.