Qt 地址薄 (一) 界面設計


  用 Qt 實現一個地址薄,功能包括:地址的添加、瀏覽、編輯、查找、輸出文件等。

1  界面和元素

  整個地址薄界面,為 AddressBook 類。其中的兩個文本框和兩個編輯欄,與 AddressBook 是 “包含” 關系 (has-a),故可將它們聲明為類成員數據。

   

1) 文本框

    Name 和 Address 只 顯示文本,可用 QLabel 實現,Qt 中其描述為 ”QLabel is used for displaying text or an image. No user interaction functionality is provided“

2) 單行編輯框

    用 QLineEdit 實現,其描述為 ”The QLineEdit widget is a one-line text editor“

3) 多行編輯框

    用 QTextEdit 實現,其描述為 ”The QTextEdit class provides a widget that is used to edit and display both plain and rich text“

 

2  子類化 (Subclassing)

  地址薄 屬於 自定義窗口部件 (custom widget),在 Qt 中並沒有對應的標准類。常用方法是:子類化 Qt 中的標准類。

  另外,當一個窗口部件的功能,兼有多個標准窗口部件的功能時也常用該方法。子類化的優點如下:

  1)  只需重寫基類中的虛函數,來實現所需要的功能,體現了 "面向對象" 的 多態性

  2)  將 UI 界面封裝在一個類中,隱藏了實現的細節,體現了 “面向對象” 的 封裝性

  3)  實現的子類可被多個程序或庫調用,體現了設計的 可復用 原則 (reusable)

  因此,可以通過子類化 QWidget 來實現地址薄類 AddressBook

2.1  Q_OBJECT

  #8 的 Q_OBJECT 宏時,可簡單理解為,Qt 中允許該類使用 tr() 和 connect() 函數。

  #15 和 #16 處,聲明了兩個私有成員數據,QLineEdit 型 和 QTextEdit 型指針,分別代表地址薄中的 Name 和 Address 右側的編輯框。

  那么,在析構函數 ~AddressBook() 中,是不是需要 delete 這兩個指針呢?

 1 #include <QWidget>  // addressbook.h 
 2 
 3 #include <QLineEdit>
 4 #include <QTextEdit>
 5 
 6 class AddressBook : public QWidget
 7 {
 8     Q_OBJECT
 9 
10 public:
11     AddressBook(QWidget *parent = nullptr);
12     ~AddressBook();
13 
14 private:
15     QLineEdit  *name_line_;
16     QTextEdit  *addr_text_;
17 };

  2.2  所有權 (ownership)

  在 AddressBook 構造函數中,明明 new 了 QLineEdit 和 QTextEdit 型指針,但在析構函數中,並沒有 delete 相應指針,難道沒有內存泄露么?這要從 Qt 的內存管理說起。

  #11 構造函數聲明中,有一個 QWidget* 參數 parent,該參數會傳給其基類的構造函數 (QWidget)。這樣,當實例化一個 AddressBook 對象時,如果為其指定了一個父類,則該父類便擁有了

這個子類的 “所有權”。當進行資源管理時,只需要銷毀這個父類,則它所擁有的所有子類,都會被自動刪除,這是 Qt 中的一個重要概念 -- “所有權”。

  Qt 中的描述為:“The constructor of AddressBook accepts a QWidget parameter.  By convention, we pass this parameter to the base class's constructor.  This concept of ownership, where a parent can have one or more children, is useful for grouping widgets.  For example, if you delete a parent, all of its children will be deleted as well.

  具體 AddressBook 是如何獲得 name_line_addr_text_ 所有權的,會在 “3  布局管理中” 詳細闡述。

 1 #include <QtWidgets/QLabel>
 2 #include <QtWidgets/QLineEdit>
 3 #include <QtWidgets/QTextEdit>
 4 #include <QtWidgets/QGridLayout>
 5 
 6 #include "addressbook.h"
 7 
 8 AddressBook::AddressBook(QWidget *parent)
 9     : QWidget(parent)
10 {
11     QLabel *name_label = new QLabel("Name:");
12     name_line = new QLineEdit;
13     QLabel *addr_label = new QLabel("Address:");
14     addr_text = new QTextEdit;
15 
16     ... ... ...
17 
22     setWindowTitle("Address Book");
23 }
24 
25 AddressBook::~AddressBook()
26 {
27 }

 

3  布局管理

  Qt 中有三種布局管理類,可以處理窗口部件的位置擺放,分別是 QHBoxLayout、QVBoxLayout 和 QGridLayout

  其中 QGridLayout 可以通過指定窗口部件的行數和列數,來控制各個窗口部件的布局,如下所示:

   

  按照上面的行數和列號,在 AddressBook 的構造函數中,添加如下代碼:

16     QGridLayout *layout = new QGridLayout;
17 
18     layout->addWidget(name_label, 0, 0);
19     layout->addWidget(name_line_, 0, 1);
20     layout->addWidget(addr_label, 1, 0, Qt::AlignTop);
21     layout->addWidget(addr_text_, 1, 1);
21 setLayout(layout);

   Qt 中 setLayout() 函數的原型為:

void QWidget::setLayout(QLayout *layout);

  具體描述為 “Sets the layout manager for this widget to layout. The QWidget will take ownership of layout.

  通過 #21,可以將 AddressBook 的布局管理器設置為 layout, 同時 AddressBook 獲得了 layout 的擁有權。

 

參考資料:

   Qt 5.9 | Qt Widgets | Part 1 - Designing the User Interface

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM