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 这两个指针呢?
#include <QWidget> // addressbook.h 3 #include <QLineEdit>
4 #include <QTextEdit> class AddressBook : public QWidget
{
Q_OBJECT public:
AddressBook(QWidget *parent = nullptr);
~AddressBook(); 14 private:
15 QLineEdit *name_line_;
16 QTextEdit *addr_text_;
};
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 布局管理中” 详细阐述。
#include <QtWidgets/QLabel>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QTextEdit>
#include <QtWidgets/QGridLayout> #include "addressbook.h" AddressBook::AddressBook(QWidget *parent)
: QWidget(parent)
{
QLabel *name_label = new QLabel("Name:");
name_line = new QLineEdit;
QLabel *addr_label = new QLabel("Address:");
addr_text = new QTextEdit; ... ... ... setWindowTitle("Address Book");
} AddressBook::~AddressBook()
{
}
3 布局管理
Qt 中有三种布局管理类,可以处理窗口部件的位置摆放,分别是 QHBoxLayout、QVBoxLayout 和 QGridLayout
其中 QGridLayout 可以通过指定窗口部件的行数和列数,来控制各个窗口部件的布局,如下所示:

按照上面的行数和列号,在 AddressBook 的构造函数中,添加如下代码:
QGridLayout *layout = new QGridLayout;
layout->addWidget(name_label, , );
layout->addWidget(name_line_, , );
layout->addWidget(addr_label, , , Qt::AlignTop);
layout->addWidget(addr_text_, , );
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
Qt 地址薄 (一) 界面设计的更多相关文章
- Qt 地址薄 (二) 添加地址
在上一篇 Qt 地址薄 (一) 界面设计 中,主要是实现了地址簿的界面,使用布局管理器进行元素的布局,并解释了"子类化" 和"所有权"的概念. 本篇将在上面的基 ...
- Qt常用的登录界面设计
记录一下Qt常用的登录界面的设计 方便以后使用! 1.QpushButton改变一个按钮的颜色,当鼠标放上去和移开时显示不同的颜色.QPushButton { background-color: rg ...
- qt model--view-delegate模式的界面设计概念,ListView用法
最经典的界面设计模式,必须知道. 作为 一种经典到 不能 再 经典 的 架构 模式, qt的model--view-delegate大 行其 道 有其 必然 的 道理. 通过 把 职责. 性质相近的 ...
- Web界面设计(Designing Web Interfaces中文版) (美)斯科特 pdf扫描版
Web界面设计是由Bill Scott编著.电子工业出版社出版的一部图书,在Web已经进入崭新的时代的今天,界面的设计显得非常重要,本书就是基于独一无二的Web环境下.在创建丰富体验的过程中设计Web ...
- 第15.12节PyQt(Python+Qt)入门学习:可视化设计界面组件布局详解
一.引言 在Qt Designer中,在左边部件栏的提供了界面布局相关部件,如图: 可以看到共包含有四种布局部件,分别是垂直布局(Vertical Layout).水平布局(Horizontal La ...
- Qt与FFmpeg联合开发指南(二)——解码(2):封装和界面设计
与解码相关的主要代码在上一篇博客中已经做了介绍,本篇我们会先讨论一下如何控制解码速度再提供一个我个人的封装思路.最后回归到界面设计环节重点看一下如何保证播放器界面在缩放和拖动的过程中保证视频画面的宽高 ...
- Qt界面设计1
最近刚接触Qt 对于QML做界面感觉已经很轻松了,但是想尝试一下GUI..准备做一个理财的小软件 ....慢慢记录我的一点一滴的学习经历. 自己封装界面UI 遇到了好多新手级别的问题=_=!!! 1. ...
- python使用PyQt5,及QtCreator,qt-unified界面设计以及逻辑实现
1.环境安装: 1.安装pyQt5 pip3 install pyQt5 2.安装设计器 pip3 install pyQt5-tools (英文版的) 我是用的是自己Windows上安装的qt ...
- 简单的爬虫程序以及使用PYQT进行界面设计(包含源码解析)
由于这个是毕业设计的内容,而且还是跨专业的.爬虫程序肯定是很简单的,就是调用Yahoo的API进行爬取图片.这篇博客主要讲的是基础的界面设计. 放上源码,然后分部解析一下重要的地方.注:flickra ...
随机推荐
- 将ADS1.2的工程迁移到KEIL上-基于2440
裸机程序应该是一个很好的选择 1. 不拷贝启动代码,因为我们用自己的启动代码 2. 建立工程目录分级,建立完成后如下所示 拷贝相应代码到对应目录中 Option中拷贝 Core中拷贝 建立 ...
- Zynq和microblaze的区别
Zynq钩中PS端的外设之后不需要初始化过程,但是如果在microblaze中连接外设之后需要有初始化过程.
- js-权威指南学习笔记8
第8章 函数 1.参数有形参和实参的区别,形参相当于函数中定义的变量,实参是在运行时的函数调用时传入的参数. 2.函数表达式可以包含名称,这在递归时很有用. 3.函数定义表达式特别适合用来定义那些只会 ...
- IOS开发中UITableView(表视图)的滚动优化及自定义Cell
IOS开发中UITableView(表视图)的滚动优化及自定义Cell IOS 开发中UITableView是非常常用的一个控件,我们平时在手机上看到的联系人列表,微信好友列表等都是通过UITable ...
- UVa 10602 - Editor Nottoobad
题目大意:有一个编辑器,它有两种命令,“重复上一个单词” 和 “删除前一个字母”,给出一系列字符串,求最少的敲击键盘的次数. 题目中强调第一个敲的单词必须是给的第一个单词,于是就考虑按照单词与第一个单 ...
- windows(win10)下的mysql解压版安装
1. 到mysql官网 下载mysql : http://dev.mysql.com/downloads/mysql/ ,会提示登陆,注册一个就行了,公司名什么的随便填. 注意区分32,64位.我 ...
- db2 将原表列notnull属性修改为null属性的方法 (查看主键约束,唯一约束去syscat.tabconst)
好久没机会写点东西了,今天把自己遇到的一个小问题跟大家分享一下如何修改db2数据库表中列的属性--将列的非空属性改为允许空的属性,修改数据表的某一列属性其实很简单但是里面有需要细节需要dba注意,毕竟 ...
- Mac 安装Eclipse
1.下载 1.1.网址 http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/mar ...
- 在vue-cli项目中安装node-sass
1,使用save会在package.json中自动添加. ----npm install node-sass --save ----npm install sass-loader --save 2 ...
- Unity游戏开发——自动为动画剪辑添加事件 之 最后几帧的事件不能被调用的问题
最近在做一个根据配置表自动生成动画剪辑clip以及controller的功能.做法是根据配置表配置的动作以及每个动作的关键帧,自动为每个clip添加事件.这样做可以把动画的事件处理在游戏运行之前就计算 ...