在上一篇 Qt 地址薄 (一) 界面设计 中,主要是实现了地址簿的界面,使用布局管理器进行元素的布局,并解释了 “子类化” 和 “所有权” 的概念。

本篇将在上面的基础上,在界面中新加三个 QPushButton 按钮,通过 “信号 - 槽函数” 机制,实现保存 Name 和 Address 内容的功能。

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> 类型的数据成员

QMap<QString, QString>  contacts_;

为了保存 Name 和 Address 之前的内容,再声明两个 QString 类型的数据成员

 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.3  addStrech() 函数

下图是布局管理器,调用 addStretch() 函数和未调用的区别

2  信号槽

2.1  功能描述

1)  Add 功能

QLineEdit 和 QTextEdit 的默认为只读,若点击 Add 按钮,二者状态变为可编辑。此时,用户可输入 Name 和 Address 的内容。同时,显示出 Submit 和 Cancel 两个按钮

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

Qt 地址薄 (二) 添加地址的更多相关文章

  1. Qt 地址薄 (一) 界面设计

    实现一个简单的地址薄,功能包括:地址的添加.浏览.编辑.查找.输出文件等. 1  界面和元素 整个地址薄界面,可视为一个 AddressBook 类.其中的 Name.Address 以及两个编辑栏, ...

  2. wex5 实战 省市县三级联动与地址薄同步

    无论是商城,还是快递,都要用到省市县三级联动,和地址薄,今天就以实战来制作,难点有3个: 1:三级联动,有wex5组件实现,相对简单,实战里对行数据进行了拼接 2:  地址薄选项,利用inputSel ...

  3. iOS:访问地址薄

    地址簿的访问 介绍: 地址簿(Address Book)是一个共享的联系人信息数据库.任何iOS应用程序都可以使用.通过提供常用联系人信息,而不是让每一个应用程序管理独立的联系人列表,可改善用户体验. ...

  4. ios开发——实用技术篇Swift篇&地址薄、短信、邮件

    //返回按钮事件 @IBAction func backButtonClick() { self.navigationController?.popViewControllerAnimated(tru ...

  5. 批量屏蔽符合条件的IP地址,支持添加白名单,IP段,增量,大于指定次数的IP

    批量屏蔽符合条件的IP地址,支持添加白名单,IP段,增量 大概的思路是利用sh,从日志中提取出来对应的IP地址,然后再交由python进行对比,判断,最终将需要添加至iptables列表中的IP写入到 ...

  6. 如何从OA系统批量整理出邮箱地址,并导入到Foxmail 地址薄中?

    一.打开某位leader的OA,点击查看“下属” a. 将所有的下属信息 --- 全选 --- 复制 --- 粘贴到 excel 表格中 b. 分别提取“姓名” 和 “邮箱”地址信息,结合notepa ...

  7. 【Qt】QT5 获取IP地址

    QT获取本机IP地址 #include <QtNetwork/QHostAddress> #include <QtNetwork/QNetworkInterface> #inc ...

  8. NodeJS中resolve添加地址无效

    今天一个朋友在群里问了这样一个问题,他使用url.resolve()添加地址无效,我看了一下,发现是他没有注意细节, resolve可以在二级目录下增加,他使用的时候只是一级目录,所以添加会有问题.他 ...

  9. Qt获取本机IP地址

    Qt获取本机IP地址: Qt版本:4.8.6 #include <QtNetwork/QNetworkInterface.h> QString ipAddr; QList<QHost ...

随机推荐

  1. 如何在华为云软件开发云上搭建JavaWeb,Maven项目

    本文将使用华为云软件开发云向大家演示如何搭建JavaWeb,Maven项目. 一.相关信息 1.华为云软件开发云简介 华为云软件开发云(DevCloud)是集华为近30年研发实践,前沿研发理念,先进研 ...

  2. jvm系列(十一):JVM演讲PPT分享

    JVM PPT的演进文稿分享 此PPT长达46页,不方便在页面中全部展示,文中只展示了文稿的前十二页. 获取完整版请在公众号内回复"JVM".

  3. 《TCP-IP详解卷2:实现》【PDF】下载

    <TCP-IP详解卷2:实现>[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230062539 内容简介 <TCP/IP详解·卷2 ...

  4. Angular 非父子组件间的service数据通信

    完成思路:以service.ts(主题subject---订阅sbuscribe模式)为数据中转中间件,通过sku.ts的数据更改监测机制,同步更改service.ts中的数据,同时buy.ts组件实 ...

  5. scala写算法-List、Stream、以及剑指Offer里部分题目基于scala解法

    Stream(immutable) Stream是惰性列表.实现细节涉及到lazy懒惰求值.传名参数等等技术(具体细节详见维基百科-求值策略). Stream和List是scala中严格求值和非严格求 ...

  6. androidSD卡操作

    1.获取SD卡目录:File file = Environment.getExternalStorageDirectory(); 2.获取SD卡路径:String path = Environment ...

  7. ArcGIS API for JavaScript 4.2学习笔记[9] 同一种视图不同数据(Map)同步

    本例子核心:对MapView对象的map属性值进行替换即可达到更改地图数据的效果. 这个例子用的不是Map对象了,而是用的发布在服务器上的专题地图(WebMap)来加载到MapView上进行显示. 在 ...

  8. Python学习(五):易忘知识点

    1.列表比较函数cmp >>> a = [1,2,3,4] >>> b = [1,2,3,4,5] >>> c = [1,2,3,4] >& ...

  9. 获取SpringMVC的映射路径

    public String init(HttpServletRequest request, HttpServletResponse response){ List<String> uLi ...

  10. Jmeter3.2版本中Generating Report Dashboard功能浅析

    自从投入到Jmeter怀抱,一直想找到一个比较不错的测试结果报告模板用于展示,类似于Loadrunner中导出html那种,但是苦苦的寻找始终没有一款让我看上眼的,包括Jmeter自带的xsl,虽然展 ...