在上一篇 Qt 地址薄 (一) 界面設計 中,主要是實現了地址簿的界面,使用佈局管理器進行元素的佈局,並解釋了 「子類化」 和 「全部權」 的概念。html
本篇將在上面的基礎上,在界面中新加三個 QPushButton 按鈕,經過 「信號 - 槽函數」 機制,實現保存 Name 和 Address 內容的功能。ide
1 三個按鈕
以下所示,在 AddressBook 的右側,添加三個按鈕,分別命名爲 「Add」、「Submit」 和 "Cancel"函數
1.1 數據成員
這三個按鈕與 AddressBook 是 "包含" 關係 (has-a),所以,可聲明爲 AddressBook 的數據成員佈局
QPushButton *add_btn_; QPushButton *submit_btn_;
QPushButton *cancel_btn_;
爲了保存輸入的 Name 和 Address,聲明一個 QMap<QString, QString> 類型的數據成員this
QMap<QString, QString> contacts_;
爲了保存 Name 和 Address 以前的內容,再聲明兩個 QString 類型的數據成員spa
QString old_name_; QString old_addr_;
1.2 佈局
新建 QVBoxLayout 型 layout_btn,將這三個按鈕組合成一列,再將 layout_btn 加入到 主佈局管理器 layout 中設計
// three btn add_btn_ = new QPushButton(tr("Add")); submit_btn_ = new QPushButton(tr("Submit")); cancel_btn_ = new QPushButton(tr("Cancel")); // new layout_btn QVBoxLayout *layout_btn = new QVBoxLayout; layout_btn->addWidget(add_btn_, Qt::AlignTop); layout_btn->addWidget(submit_btn_); layout_btn->addWidget(cancel_btn_); layout_btn->addStretch(); // add layout_btn into layout layout->addLayout(layout_btn,1,2);
1.3 addStrech() 函數
下圖是佈局管理器,調用 addStretch() 函數和未調用的區別code
2 信號槽
2.1 功能描述
1) Add 功能orm
QLineEdit 和 QTextEdit 的默認爲只讀,若點擊 Add 按鈕,兩者狀態變爲可編輯。此時,用戶可輸入 Name 和 Address 的內容。同時,顯示出 Submit 和 Cancel 兩個按鈕htm
2) Submit 功能
點擊 Submit 按鈕,可將用戶輸入的 Name 和 Address 保存到程序中。若輸入爲空,則提示請輸入的信息;若該 Name 已經添加過,則提示已經添加
3) Cancel 功能
點擊 Cancel 按鈕,可將用戶輸入的 Name 和 Address 取消掉,不進行保存,同時顯示出以前的 Name 和 Address
2.2 信號槽機制
信號槽機制,主要用於 類對象之間的通訊,是 Qt 的精髓所在,與之相似的有:觀察者模式,回調機制等
當特定的事件發生後,相應的信號被髮出,則與該信號 connect 的槽函數,隨後被調用
2.3 connect 函數
使用 connect 函數,將發射信號的 類對象 + 信號,以及接收信號的 類對象 + 槽函數,鏈接起來
具體的實現代碼以下:
connect(add_btn_, SIGNAL(clicked()), this, SLOT(OnAdd())); connect(submit_btn_, SIGNAL(clicked()), this, SLOT(OnSubmit())); connect(cancel_btn_, SIGNAL(clicked()), this, SLOT(OnCancel()));
3 槽函數
頭文件中聲明瞭三個槽函數,以下所示:
public slots: void OnAdd(); void OnSubmit(); void OnCancel();
3.1 OnAdd() 函數
void AddressBook::OnAdd() { old_name_ = name_line_->text(); // 保存之前的 Name 和 Address old_addr_ = addr_text_->toPlainText(); name_line_->clear(); addr_text_->clear(); name_line_->setReadOnly(false); // 設置 QLineEdit 和 QTextEdit 可編輯 name_line_->setFocus(Qt::OtherFocusReason); addr_text_->setReadOnly(false); add_btn_->setEnabled(false); // 顯示 Submit 按鈕 和 Cancel 按鈕 submit_btn_->show(); cancel_btn_->show(); }
3.2 OnSubmit() 函數
void AddressBook::OnSubmit() { QString name = name_line_->text(); QString address = addr_text_->toPlainText(); if (name.isEmpty() || address.isEmpty()) { QMessageBox::information(this, tr("Empty Field"), tr("Please enter a name and address.")); return; } if (!contacts_.contains(name)) { contacts_.insert(name, address); QMessageBox::information(this, tr("Add Successful"), tr("\"%1\" has been added to your address book.").arg(name)); } else { QMessageBox::information(this, tr("Add Unsuccessful"), tr("Sorry, \"%1\" is already in your address book.").arg(name)); return; } if (contacts_.isEmpty()) { name_line_->clear(); addr_text_->clear(); } name_line_->setReadOnly(true); addr_text_->setReadOnly(true); add_btn_->setEnabled(true); submit_btn_->hide(); cancel_btn_->hide(); }
3.3 OnCancel() 函數
void AddressBook::OnCancel() { name_line_->setText(old_name_); name_line_->setReadOnly(true); addr_text_->setText(old_addr_); addr_text_->setReadOnly(true); add_btn_->setEnabled(true); // 設置 Add 按鈕使能 submit_btn_->hide(); // 隱藏 Submit 和 Cancel 按鈕 cancel_btn_->hide(); }
參考資料:
Qt 5.9 | Qt Widgets | Part 2 - Adding Addresses