一、创建项目
1.点击左上角文件->新建项目或文件,之后会弹出如下对话框。选中蓝框后点击choose。
2.项目命名,该名称就是你所创建的应用程序的默认名称。
3.到Details步骤时,Qt会要求你创建一个类,这个类有三种选法。
这三个类的关系是:QWidget是基类,QMainWindow和QDialog是QWidget的子类,他们之间是继承的关系。QWidget默认生成空窗口,QMainWindow派生了状态栏,QDialog派生了对话框。
一般的项目,我们使用QWidget就够了。
4.完成所有步骤后,Qt工程就创建好了,如下图所示,Qt会自动写好初始代码。
我们应该大致了解初始代码的含义,以更加理解代码运行的过程,具体代码含义说明如下注释:
这里额外做两点补充解释:
1.argc和argv:在c语言中,argc和argv负责接收命令,像是鼠标敲击、键盘输入都是命令。利用这两个参数来实现程序与用户之间的交互。
2.消息循环:正常的程序main函数从头执行到结尾程序就终止了。可是我们实际使用程序时,程序必须持续运转,并且在程序运行的过程中必须时刻能接收用户输入的命令,因此,我们这里不会return 0,而是进入到消息循环,消息循环可以通俗理解为死循环。
二、设计图形界面
Qt内置了非常丰富的组件库,我们可以通过类的实例化来创建各种组件(像是按钮,下拉框等等)到我们自己的程序中。但有种更为直观且更为方便的方法可供我们使用:图形界面编程。
图形界面编程可以通俗理解为直接将程序的组成部分和布局ppt化了,你完全可以通过拖拽组件来直观地编辑你的应用程序界面,在你的界面设计好之后再通过代码实现相应的逻辑功能。往下看你就明白我在说什么了。
1.进入图形界面编辑界面
双击ui文件即可进入编辑界面:
2.一张图介绍ui界面设计方法
下面以label为例简要介绍组件的使用方法:
1.标签 Label:Qt 提供给我们的一种文本控件,它的基础功能是显示一串文本。如下所示:
编译后呈现的效果如下:
【参数调整】在设计界面的右半部分,可以编辑属性。通过调整属性,可以改变显示样貌,如字体、大小等各类参数。更深层次的理解是,这里所编辑的属性,和类的属性是一一对应的,也就是说,我们可以在图形界面中设置某个具体类的实例的属性值,也可以在编写代码的
我们不可能也没必要对每一个组件都一一学习。事实上,想要熟练使用组件更应该根据你自己的实际需求慢慢摸索调整。
提示:如果编译后的程序图形界面中文字显示不全,是由于显示分辨率的问题,在主函数开头部分添加以下代码即可
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);//解决文字显示不全的问题
3.布局
拖拽式的ui界面设计可以让你肆意为实现你的应用增添合适的组件,但难以保证你的界面精美。布局能帮助你解决一些结构性的难题,说白了,就是能让你的各个组件对齐。
具体而言,有三种布局(对齐)方式
- 水平布局
布局前:
布局后:
- 垂直布局
- 栅格布局
布局前:
布局后:
三、逻辑功能设计
3.1信号和槽
下面以按钮为例,介绍信号和槽。
通过上一节的学习,我们可以做到在窗口上创建一个按钮,但是,该按钮还未实现任何的逻辑功能。下面我们就要利用信号和槽机制来设计逻辑功能。
大家不妨试想以下应用实现的过程,无非是:当用户在图形界面上按下一个按钮后,程序执行预先设计好的一段函数,完成相应的逻辑功能。
这个过程有两个关键点:
3.1.1 信号:用户触发
比如上述描述的 “当用户在图形界面上按下一个按钮后” ,按下一个按钮就相当于触发信号,换言之,如果用户没按下按钮,信号就没触发,相应的一段逻辑功能(函数)就不会被执行。到这里,信号的概念就已经呼之欲出了。
上面触发信号的过程我一直描述为按下按钮,实际上信号不仅仅是按下一种,还包括点击,释放,转换(这个转换可以类比于电灯开关,每按下一次灯的亮暗状态就转换一次),信号可以在官方文档中查找。
顺便提一嘴:在我使用的qt中,官方文档中的QPushButton是没有关于Signals的说明的,这是因为,相关的说明写到父类里面了,我们知道子类的实例是可以调用父类的函数的。所以提醒大家如果有些函数没找到,记得顺藤摸瓜,去父类(以及父类的父类)找找看。
3.1.2 槽:程序执行逻辑功能
槽,其全称是槽函数,所谓函数就是一段逻辑功能的意思。槽函数中的代码只有在信号触发时才会执行。槽函数中的逻辑功能可以自己实现,也可以借助官方文档,使用库函数。
上图截取的是QWidget类的槽函数,QPushButton是QWidget的孙子,QWidget的槽函数QPushButton都是可以使用的。
3.1.3connect连接:利用信号和槽机制,完成应用功能的实现
光是知道信号和槽,还是不足以实现逻辑功能,这是因为我们还差了主体和客体,通俗来说,就是信号发出者和信号接收者。信号发出者发出信号,信号接收者接收信号,执行槽函数。这才是完整的逻辑实现过程。
信号发出者和接收者的指定,或者说,信号到槽函数的连接,通过connect函数来实现。
connect的使用方法如上图所示。
3.2 自定义信号和槽
前面所介绍的信号和槽都是qt已经编写好的,有时qt中的信号和槽不能满足我们的编程需求,这时我们可以自己编写适合自己项目的信号和槽函数。
3.2.1自定义信号
自定义信号的编写要注意以下三个规则:
- 自定义信号写在signals下:如图所示,signals是直接声明在类下的,但要注意,signals是qt在c++的基础上额外增加的规则,因此普通的类是没有signals的。允许signals的类一定要继承自QObject.
- 返回值是void。只需声明,不用实现
- 可以含参,可以重载
3.2.2自定义槽函数
- 槽函数可以直接写在public下,也可以写在public slots下
- 返回值为void;既要声明,又要实现。
3.2.3关于重载信号和槽引起的connect冲突问题以及解决方法
当你编写了多个重载的信号和槽时,在connect时会发现存在问题。就拿上述两个图片中的信号和槽举例,无论使用哪个信号和哪个槽,你会发现他们的connect函数竟然是相同的,都是:
connect(tc,&teacher::hungry,st,&student::treat);
这是因为编译器是通过返回值类型和参数来辨析使用哪个重载函数的,而在信号和槽的连接中,这两个维度的信息都被隐藏了,使得重载函数的使用无从确定,进而引发冲突。
解决的办法是使用函数指针:
图示中的代码就是在connect之前提前告诉编译器我要连接的信号和槽是这两个,并用变量指向对应的函数 ,从而利用函数指针解决了重载冲突。
3.3 QMainWindow
3.3.1菜单栏
图中红框部分就是菜单栏,现在我们要给我们自己的程序窗口设置菜单栏。
以下是常见操作
3.3.2工具栏
更多API请参考帮助手册
3.4对话框
3.4.1 模态和非模态对话框的创建
dlg是对话框类的一个实例,在程序中,也就是对话框本身。我们的需求是希望点击一个菜单项后触发这个对话框,因此需要用到信号和槽。模态和非模态的含义在图中已有解释,其本质是两种不同的打开方式,因此对应着两种不同的槽函数。
在程序中,点击对应的菜单项,就会弹出对话框。
3.4.2 标准对话框
标准对话框就是调用Qt设计好的常用的对话框,这些对话框在QMessageBox库中,下图为提问对话框的具体创建代码。
QMessageBox::question是需要设定参数的,然而SLOT()要求槽函数不能带参数,这里就遇到了麻烦。笔者的解决方法是自己写一个槽函数qmessageBox,里面包含了 QMessageBox::question,这样就规避了矛盾。这里需要额外注意的是上图红框部分,没有这句声明编译器会找不到槽函数。
此外使用Lambda表达式也可以很方便的调用,这里不再赘述。
除了question还有其他的标准对话框,具体详见官方文档:
3.4.3 其他对话框
颜色对话框
文件对话框
四、Windows下的项目部署与发布
进入这一部分,我会默认各位已经设计好了自己的一个应用程序。
首先我们要明白在这一步我们要做的是什么?
在我们日常使用app的过程中,从来没有一个app像我们自己的这个程序一样先进入到源码,再点击编译,之后程序才能启动。所以接下来我们要做的就是生成“exe”文件,用户点击后直接就启动我们的应用程序,而不是先看我们的源码!
首先,我们先切换为release模式,debug模式会生成很多调试信息,这是在产品测试时使用的,行将发布的产品没必要用debug模式。
在该模式下编译一次,之后会在主文件夹下多出这样一个文件
我们打开该文件夹,进入到release目录下,把exe文件单独复制到一个你新创建的文件夹中,注意,这个文件夹将包含你部署和发布的应用程序,因此你要知悉该文件夹的位置,并且这个文件夹不能用中文命名。
接着我们会使用到qt控制台,直接在Windows下搜索打开就可以了
在控制台中进行如下操作,部署和打包就完成了:
完成之后,系统为我们的应用程序配置好了依赖,这样我们的应用程序就能直接使用了!
版权归原作者 金拱门板烧堡 所有, 如有侵权,请联系我们删除。