课程咨询 : 020-87532245 24小时热线:15622781509 咨询QQ:3061057839

广州C++培训 > 达内新闻 > Qt地址薄的界面设计
  • Qt地址薄的界面设计

    发布:广州C++培训      来源:达内新闻      时间:2017-01-22

  • 广州C++培训机构的老师这一期给大家讲Qt地址薄的界面设计。

    实现一个简单的地址薄,功能包括:地址的添加、浏览、编辑、查找、输出文件等。

    1 界面和元素

    整个地址薄界面,可视为一个AddressBook类。其中的Name、Address以及两个编辑栏,视为AddressBook中的元素,也即“包含”关系(has-a)。因此,可以将它们声明为AddressBook的成员数据。

    Name和Address不涉及与用户的交互,只显示文本,因此,可用QLabel来实现,其描述为”QLabel is used for displaying text or an image. No user interaction functionality is provided“

    单行编辑框,可用QLineEdit来实现,其描述为”The QLineEdit widget is a one-line text editor“

    多行编辑框,可用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,使用Qt Creator创建工程,会自动生成如下的代码框架(除绿色标记的代码外,其余的都是自动生成的)

    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 class QLineEdit;

    4 class QTextEdit;

    5

    6 class AddressBook : public QWidget

    7 {

    8    Q_OBJECT

    9

    10 public:

    11    AddressBook(QWidget *parent = 0);

    12    ~AddressBook();

    13

    14 private:

    15    QLineEdit *m_nameLine;

    16    QTextEdit *m_addrText;

    17 };

    2.2 所有权(ownership)

    在AddressBook的构造函数中,明明new了QLineEdit和QTextEdit型指针,但是在析构函数中,并没有delete相应的指针,难道没有内存泄露么?这要从Qt的内存管理说起。

    #11构造函数声明中,它有一个QWidget*类型的参数parent,该参数会传给其基类的构造函数(QWidget)。这样,当实例化一个AddressBook对象时,如果为其指定了一个父类,则该父类便拥有了这个子类的”所有权“(ownership)。

    当进行资源管理时,只需要销毁这个父类,则它所拥有的所有子类,都会被自动删除,这是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是如何获得m_nameLine和m_addrText所有权的,会在“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 *nameLabel = new QLabel("Name:");

    12    m_nameLine = new QLineEdit;

    13    QLabel *addressLabel = new QLabel("Address:");

    14    m_addrText = new QTextEdit;

    15

    16    ... ... ...

    17

    22    setWindowTitle("Address Book");

    23 }

    24

    25 AddressBook::~AddressBook()

    26 {

    27 }

    2.3 main.cpp

    #include "addressbook.h"

    #include <QApplication>

    int main(int argc, char *argv[])

    {

    QApplication a(argc, argv);

    AddressBook w;

    w.show();

    return a.exec();

    }

    3 布局管理

    Qt中有三个布局管理类,可以处理窗口部件的位置摆放,分别是QHBoxLayout、QVBoxLayout和QGridLayout

    其中QGridLayout可以通过指定窗口部件的行数和列数,来控制各个窗口部件的布局,如下所示:

    按照上面的行数和列号,在AddressBook的构造函数中,添加如下代码:

    16    QGridLayout *layout = new QGridLayout;

    17

    18    layout->addWidget(nameLabel, 0, 0);

    19    layout->addWidget(m_nameLine, 0, 1);

    20    layout->addWidget(addressLabel, 1, 0, Qt::AlignTop);

    21    layout->addWidget(m_addrText, 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地址薄(一)界面设计

    实现一个简单的地址薄,功能包括:地址的添加、浏览、编辑、查找、输出文件等。

    1 界面和元素

    整个地址薄界面,可视为一个AddressBook类。其中的Name、Address以及两个编辑栏,视为AddressBook中的元素,也即“包含”关系(has-a)。因此,可以将它们声明为AddressBook的成员数据。

    Name和Address不涉及与用户的交互,只显示文本,因此,可用QLabel来实现,其描述为”QLabel is used for displaying text or an image. No user interaction functionality is provided“

    单行编辑框,可用QLineEdit来实现,其描述为”The QLineEdit widget is a one-line text editor“

    多行编辑框,可用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,使用Qt Creator创建工程,会自动生成如下的代码框架(除绿色标记的代码外,其余的都是自动生成的)

    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 class QLineEdit;

    4 class QTextEdit;

    5

    6 class AddressBook : public QWidget

    7 {

    8    Q_OBJECT

    9

    10 public:

    11    AddressBook(QWidget *parent = 0);

    12    ~AddressBook();

    13

    14 private:

    15    QLineEdit *m_nameLine;

    16    QTextEdit *m_addrText;

    17 };

    2.2 所有权(ownership)

    在AddressBook的构造函数中,明明new了QLineEdit和QTextEdit型指针,但是在析构函数中,并没有delete相应的指针,难道没有内存泄露么?这要从Qt的内存管理说起。

    #11构造函数声明中,它有一个QWidget*类型的参数parent,该参数会传给其基类的构造函数(QWidget)。这样,当实例化一个AddressBook对象时,如果为其指定了一个父类,则该父类便拥有了这个子类的”所有权“(ownership)。

    当进行资源管理时,只需要销毁这个父类,则它所拥有的所有子类,都会被自动删除,这是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是如何获得m_nameLine和m_addrText所有权的,会在“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 *nameLabel = new QLabel("Name:");

    12    m_nameLine = new QLineEdit;

    13    QLabel *addressLabel = new QLabel("Address:");

    14    m_addrText = new QTextEdit;

    15

    16    ... ... ...

    17

    22    setWindowTitle("Address Book");

    23 }

    24

    25 AddressBook::~AddressBook()

    26 {

    27 }

    2.3 main.cpp

    #include "addressbook.h"

    #include <QApplication>

    int main(int argc, char *argv[])

    {

    QApplication a(argc, argv);

    AddressBook w;

    w.show();

    return a.exec();

    }

    3 布局管理

    Qt中有三个布局管理类,可以处理窗口部件的位置摆放,分别是QHBoxLayout、QVBoxLayout和QGridLayout

    其中QGridLayout可以通过指定窗口部件的行数和列数,来控制各个窗口部件的布局,如下所示:

    按照上面的行数和列号,在AddressBook的构造函数中,添加如下代码:

    16    QGridLayout *layout = new QGridLayout;

    17

    18    layout->addWidget(nameLabel, 0, 0);

    19    layout->addWidget(m_nameLine, 0, 1);

    20    layout->addWidget(addressLabel, 1, 0, Qt::AlignTop);

    21    layout->addWidget(m_addrText, 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的拥有权。

    推荐文章

上一篇:GCC与G++的区别

下一篇:【广州C++培训机构】洛谷P1177快速排序

最新开班日期  |  更多

c++--零基础周末班

c++--零基础周末班

开班日期:4月15日

c++--零基础全日制班

c++--零基础全日制班

开班日期:4月15日

c++--免费训练营

c++--免费训练营

开班日期:4月15日

c++--高薪就业班

c++--高薪就业班

开班日期:4月15日

  • 网址:http://gz.c.tedu.cn     地址:广州市天河北五山路 141 号尚德大厦 627
  • 课程培训电话: 020-87532245 24小时热线:15622781509 咨询QQ:3061057839     全国服务监督电话:400-827-0010
  • 服务邮箱 ts@tedu.cn
  • 2001-2016 达内时代科技集团有限公司 版权所有 京ICP证8000853号-56