Qt入门系列教程------02

·  阅读 476
Qt入门系列教程------02

1.概述

  • 上篇文章讲解了一个简单的Qt程序,主要为了帮助刚刚接触Qt程序的新手入门,本系列教程主要以纯代码的方式开始,后续根据进展情况可以讲述.ui界面的设计,这种方式比较简单易学,利用.ui界面可以快速的设计简单的界面,但是初学者还是应该以代码为主,为以后打下一个坚实的基础。

2.目标

  • 旨在了解一些类,比如QPushButton、QMenu等类的简单应用。废话少说,直接上代码,本文还是新建一个空工程,然后往里面添加main.cpp文件,编写.pro文件的代码如下:
1. QT       += core gui
2. 
3. greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
4. 
5. 
6. TARGET = demo_02
7. TEMPLATE = app
8. 
9. DEFINES += QT_DEPRECATED_WARNINGS
10. 
11. 
12. SOURCES += \
13.     main.cpp
复制代码
  • 上面这些代码就不过多解释了,上篇文章已经讲得很清楚了,这里就不再赘述了,有需要了解的朋友可以去翻一翻上篇文章,这里着重讲解main.cpp文件代码,main.cpp文件如下:
1. #include <QApplication>
2. //#include <QtWidgets>
3. #include <QPushButton> //添加QPushButton类的头文件
4. #include <QMenu> //添加QMenu类的头文件
5. #include <QWidget> //添加QWidget类的头文件
6. 
7. 
8. int main(int argc, char *argv[])
9. {
10.     QApplication a(argc, argv);
11.     QWidget *widget = new QWidget(); //创建一个QWidget对象指针widget,默认parent参数是0,所以它是个窗口
12.     widget->resize(450,300); //设置窗口的大小
13. 
14. 
15.     QPushButton *btn1 = new QPushButton(widget); //创建一个QPushButton对象指针btn1,并设置其父亲为对象widget窗口,也就是说该btn1是widget窗口上的控件
16.     btn1->setText(QObject::tr("&Quit")); //设置btn1的内容,指定了Alt+Q为加速键,这里只支持英文字母,将其首字母+Alt作为快捷键
17. 
18. 
19.     QPushButton *btn2 = new QPushButton(widget); //创建一个QPushButton对象指针btn2,并设置其父亲为对象widget窗口,也就是说该btn2是widget窗口上的控件
20.     btn2->setText(QObject::tr("关于Qt(&A)")); //设置btn2的内容,指定Alt+A为加速键,这里也就是提供了一种中文显示并设置快捷键的方法
21.     btn2->move(80,0); //移动该按钮,防止被遮挡
22. 
23. 
24.     QPushButton *btn3 = new QPushButton(widget); //创建一个QPushButton对象指针btn3,并设置其父亲为对象widget窗口,也就是说该btn3是widget窗口上的控件
25.     btn3->setText(QObject::tr("zoom")); //设置btn3的内容
26.     btn3->move(160,0); //移动该按钮,防止被遮挡
27. 
28.     QMenu *menu = new QMenu(); //创建一个QMenu对象的指针menu
29.     menu->addAction(QIcon("../demo_02/images/zoom-in.png"),QObject::tr("放大")); //设置图标,使用相对路径,对btn3设置了下拉菜单,这个菜单什么功能也没有实现
30.     btn3->setMenu(menu); //设置btn3的父亲为menu,也就是说给btn3设置了一个下拉菜单
31. 
32. 
33.     QPushButton *btn4 = new QPushButton(widget); //创建一个QPushButton对象指针btn4,并设置其父亲为对象widget窗口,也就是说该btn4是widget窗口上的控件
34.     btn4->setText(QObject::tr("帮助(&H)")); //设置btn4的内容
35.     btn4->setIcon(QIcon("../demo_02/images/help.png")); //设置图标,使用相对路径
36.     btn4->move(240,0); //移动该按钮,防止被遮挡
37. 
38. 
39.     QObject::connect(btn1,&QPushButton::clicked,&QApplication::quit); //连接btn1和关闭窗口的信号与槽函数
40.     QObject::connect(btn2,&QPushButton::clicked,&QApplication::aboutQt);  //连接btn2和关于Qt介绍的信号与槽函数
41. 
42.     widget->show(); //让QWidget创建的窗口对象widget显示出来
43. 
44.     int ret = a.exec();
45. 
46.     delete widget; //销毁父部件widget就会自动销毁其子部件
47. 
48. //    delete btn1; //销毁btn1,创建在堆上面的对象指针
49. //    delete btn2; //销毁btn2,创建在堆上面的对象指针
50. //    delete btn3; //销毁btn3,创建在堆上面的对象指针
51. //    delete btn4; //销毁btn4,创建在堆上面的对象指针
52. 
53. 
54.     Return ret; ////程序进入消息循环,等待对用户输入进行响应。这里main()把控制权转交给Qt,Qt完成事件处理工作,当应用程序退出的时候exec()的值就会返回。在exec()中,Qt接受并处理用户和系统的事件并且把它们传递给适当的窗口部件。
55. }
复制代码
  • 该程序主要实现的功能是:点击按钮Quit可以关闭窗口,点击按钮关于Qt(A),可以打开关于Qt介绍的窗口,点击按钮zoom,可以打开下拉菜单,下拉菜单为放大菜单项,帮助按钮没有设置功能,其中部分按钮有快捷键的设置以及图标的设置,以上就是这个小应用程序的主要功能,具体运行效果图如下:

02.png

3.代码分析

  • main.cpp文件中用到的几个类以及函数,通过查询帮助文档找到函数的用法如下,Qt软件的学习一定要充分的利用好帮助文档,这点很重要,会看帮助文档的人会进步的很快。代码块本人已经注释的很详细了,基本上每一段代码都有详细的中文注释,大家需要仔细看代码,其中我会讲解几处个人认为比较重要的地方,和大家分享一下我的理解,有不对的地方还望指正,大家一起交流学习,共同进步。以下是帮助文档中查到的几处函数原型:
  1. QWidget::QWidget(QWidget *parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags()) 构造一个没有父级和标志的装饰件,即QWidget。
  2. QPushButton::QPushButton(QWidget *parent = Q_NULLPTR) 构造一个没有文本和父级的按钮。
  3. QMenu::QMenu(QWidget *parent = Q_NULLPTR) 构造一个带有parent的菜单。
  4. QAction *QMenu::addAction(const QIcon &icon, const QString &text) 创建了一个带有图标和一些文本的新操作。该函数将新创建的操作添加到菜单的操作列表中,并返回它。

几点说明:

A.头文件包含的原则是:尽量包含较少的头文件,文中那四个头文件可以用注释掉的那个头文件代替,只需要那一个就可以包含整个模块的头文件,但是不建议这么做,本文只是给出读者知道这样用也可以。

B.代码:delete widget;对QWidget窗口的销毁就会自动的销毁其子部件,也就是那四个按钮也会被销毁。具体为什么要销毁QWidget以及为什么那四个按钮也会被销毁,这就牵扯到Qt的对象模型(对象树)的知识点,下面具体讲解该知识点。

4.对象模型(对象树)

  • 在Qt中创建对象的时候会提供一个Parent对象指针,下面来解释这个parent到底是干什么的。QObject是以对象树的形式组织起来的。当你创建一个QObject对象时,会看到QObject的构造函数接收一个QObject指针作为参数,这个参数就是 parent,也就是父对象指针。也就是说,在创建QObject对象时,可以提供一个其父对象,我们创建的这个QObject对象会自动添加到其父对象的children()列表。当父对象析构的时候,这个列表中的所有对象也会被析构。(注意,这里的父对象并不是继承意义上的父类!)

  • QWidget是能够在屏幕上显示的一切组件的父类。QWidget继承自QObject,因此也继承了这种对象树关系。一个孩子自动地成为父组件的一个子组件。因此,它会显示在父组件的坐标系统中,被父组件的边界剪裁。例如,当用户关闭一个对话框的时候,应用程序将其删除,那么,我们希望属于这个对话框的按钮、图标等应该一起被删除。事实就是如此,因为这些都是对话框的子组件。

  • 当然,我们也可以自己删除子对象,它们会自动从其父对象列表中删除。比如,当我们删除了一个工具栏时,其所在的主窗口会自动将该工具栏从其子对象列表中删除,并且自动调整屏幕显示。

  • Qt 引入对象树的概念,在一定程度上解决了内存问题。当一个QObject对象在堆上创建的时候,Qt 会同时为其创建一个对象树。不过,对象树中对象的顺序是没有定义的。这意味着,销毁这些对象的顺序也是未定义的。任何对象树中的 QObject对象 delete 的时候,如果这个对象有 parent,则自动将其从 parent 的children()列表中删除;如果有孩子,则自动 delete 每一个孩子。Qt 保证没有QObject会被 delete 两次,这是由析构顺序决定的。

  • 我们文中用new创建的几个对象指针都是在堆上创建的,一般都需要程序员手动释放内存,关于堆栈的知识我们可以在以后专门讨论,这些都是C++的基础知识。最后,欢迎大家留言交流,有需要代码的可以关注微信公众号(简介中有介绍)给你发送,方便大家调试程序和移植代码。

分类:
代码人生
标签: