跟535一起从零开始学QT

跟535一起从零开始学QT-安装与环境配置

QT?啥是QT?

Qt/ˈkjuːt/,发音同“cute”[4][5][6])是一个跨平台C++应用程序开发框架。广泛用于开发GUI程序,这种情况下又被称为部件工具箱。也可用于开发非GUI程序,比如控制台工具和服务器。Qt被用于OPIESkypeVLC media playerAdobe Photoshop ElementsVirtualBoxMathematica[7]以及被Autodesk [8][9]欧洲空间局[10]梦工厂[11][12]GoogleHP[13]KDE卢卡斯影业[14]西门子公司[15]沃尔沃集团[16], 华特迪士尼动画制作公司[17]三星集团[18]飞利浦[19]Panasonic [20]所使用。

它是Digia公司的产品。Qt使用标准的C++和特殊的代码生成扩展(称为元对象编译器(Meta Object Compiler, moc))以及一些。通过语言绑定,其他的编程语言也可以使用Qt。

Qt是自由且开放源代码的软件,在GNU宽通用公共许可证(LGPL)条款下发布。所有版本都支持广泛的编译器,包括GCC的C++编译器和Visual Studio。

–摘自维基百科

通俗来讲,QT就是让我们的程序告别黑框框,变成一个真正的有脸面的程序。如此有用有排面的东西,该怎么去开始学习呢?

QT的安装

QT当然要从官网上安装了!QT官网:https://www.qt.io/cn

然后这里给一个简单的链接:QT下载:http://download.qt.io/archive/qt/

选择上,根据需要选择吧!不过这里我们要选择5.X,例如5.12。在5.12子界面,选择最高的版本。然后根据你的电脑系统进行选择。

在这里插入图片描述

比如你是windows,就选择那个windows-x86的版本即可。

QT安装的细节

最前面的是协议,读一下然后点已阅读就可以。

然后确定安装位置,注意最下面那个框框,意思是对已有文件后缀自动QT打开,通俗来讲,如果你选了,那么以后.cpp,.h这种文件默认打开方式都是QT Creator

下一步选择组件。Developer and Designer Tools这个建议选,有一些实用的工具。但是上面那个Qt 5.XX.X 一定要打开选择一个!,不然你就没有编译器,没法编译文件。这里以Qt 5.11.3举例(图源网络,侵权删~~,其实是忘了截~~)

在这里插入图片描述

这里上面的选择框中各名称含义:

  1. MinGW,编译器模块之一,建议选这个!
  2. UWP,编译器模块之一。
  3. MSVC,编译器模块之一。
  4. ARM和Android是用于Android平台的模块。
  5. Sources,QT的源码
  6. Qt Charts,二维画图模块
  7. Qt Data Visualization,三位画图模块。
  8. 其他都是拓展模块

怎么选?编译器模块至少选择一个,其他根据需要选择(任选)

下面的含义:

  1. Qt Creator,Qt自己的IDE。Debugger(调试用的)
  2. MinGW,MinGW编译工具链
  3. Strawberry,一个Perl语言工具。

怎么选?我选的是Qt Creator(包含Debugger)与MinGW。

QT安装完之后

当你下载完成,安装完成之后,你的开始菜单会多这些东西:
在这里插入图片描述
为啥这么多?这些都是啥?

  1. Qt Creator 4.11.2 这个是一个IDE(集成开发环境),可以认为是Qt官方给的写代码软件。
  2. 剩下的,每一个相同名的(例如Assistant 5.12.8)分为好几个C/C++的编译器,即MinGW与MSVC,编译器又分了好几个版本,按需选择?(我选择的是MSVC的最新版本)

如果你没有Kits,这边建议你重装QT。或者可以按照https://doc.qt.io/qtcreator/creator-targets.html,QT,Adding Kits查找手动安装Kits的方法。

*QT的VS环境搭建

为什么不用QT Creator?

非必选,Qt Creator挺好用的,VS如果你有自己配置过,坚持要用VS,可以按照以下步骤搭建。

  1. 安装插件:VS,拓展->管理拓展->联机->搜索:“Qt Visual Studio Tools”,然后下载(用梯子更丝滑)。下载完成后要重启VS才能安装的。
  2. 配置插件:VS,拓展->Qt VS Tools->Qt Options->Add,然后填写上你的版本,选择你的路径(注意,此处要选择到MSVC2017_64这个文件夹级别)
  3. 使用Qt:记得把对应的项目中“属性/链接器/输入”里面输入加上一个“shell32.lib”

然后我们就做好了QT的安装。可以根据Qt Creator上面的教程学习,同时更欢迎大家与我们535一起从零开始学QT!

Qt手册:https://wiki.qt.io/Main/zh

跟535一起从零开始学QT-我的第一个QT程序

本文将会做一个文本显示框,点击按钮之后会更改文本框中的内容。

如何简单地做一个QT项目

新建一个项目

文件-新建文件或项目。 或 Ctrl + N。

选择模板

直接选Qt Widgets Application. 右下角 choose

相关配置

Location:自定,存文件的地方

Build System: qmake,暂时不需要研究这东西

Details: 可以直接默认走起。然后各个的简单介绍在下图。

在这里插入图片描述

Translation: 多语言翻译,暂时没用,默认即可。

Kits: 你选择的编译系统,具体有MSVC、MinGW两种,选一个前面的图标是小电脑的即可,带叹号的是不可用。

Summary: 直接默认走即可。

文件结构

在这里插入图片描述

.pro: 这个是Qt编译器保存的项目信息,例如你的项目的文档目录之类的。如果要打开一个下载的Qt项目,只需要打开其相应的 .pro 文件即可。

Headers: 通常存放 .h 文件,文件内写相关类的声明,函数声明(但不实现),变量声明etc. 作用:简化函数的查找与结构的查找,避免打开一个类翻半天翻不到下一个函数。

Sources: 源文件,一般为 .cpp 文件。其中要有对应 .h 的 .cpp 文件,对应实现 .h 中的一些函数。main.cpp 一般包含 main() 函数,为程序执行的入口函数。

补,Sources 文件中的 include 关系:同名 .cpp 要包含 同名 .h 文件。例如mainwindow.cpp 中需要加 #include "mainwindow.h",注意要用双引号包含(双引号会优先搜索同目录下的文件,而尖括号搜索系统基础库)。如果想要在其他文件中用mainwindow的类与函数,需要#include "mianwindow.h"

Forms: Ui文件,也就是界面布局设计文件。如果你直接点它的话,会用Qt Designer打开一个页面文件,支持拖动设计。如果你用文本方式打开的话,会是xml文件。

补,Ui文件与对应的.h/.cpp文件引用方法: 每个ui界面文件都会有个名称,例如上述的mainwindow.ui,在需要用的时候要在 .cpp 文件中#include "ui_mainwindow.h",并且在对应 .h 文件中写

namespace Ui{
    class MainWindow;
    //这里名称对应你要用这个ui的类名,这个案例中是MainWindow
}

如果不这么写的话,你将无法正确绑定类与ui。原理这里不再细究(关系到.ui文件的编译过程)。

拖动设计Ui

点开ui文件,然后在这个页面(指左边侧边栏第三个,“设计”)显示

在这里插入图片描述

然后我们需要啥部件,只需要拖动到指定位置,然后用鼠标拉到合适大小即可。如果需要设计该部件的其他属性,可以找到图片的右下方,“属性”一栏,将其对应的值更改即可。

如果想要通过代码来达到更改的效果,一般每个可以更改的属性会对应一个 set....()函数来更改,使用参数详见IDE中的补全提示。当然,也可以放在对应的函数上,按下’ ‘F2’ 寻找函数定义,详细了解该函数的声明与实现

这里,我们设计一个点击更改文本的界面。

第一步,把界面中的模块填充完整。

在这里插入图片描述

选中Line Edit,在属性一栏找到QWidget属性中font,该属性为显示字体的属性。调成你需要的(我这里调的为“楷体”,“20”号)。

然后对应调Label组件的属性。这里你会发现他们有相同的QObject,QWidget属性,原因是类的继承。找到 QLabel 属性中的 text,即该TextLabel默认显示的文本,这里改成“Hello World!”

选中PushButton,调字体大小,然后找到 QAbstractButton 属性中的 text,可以改变按钮上的字,这里我设置为“更改”。

最后的界面为这样的:

在这里插入图片描述

设计信号与槽

通俗来讲,信号是部件状态改变时,系统会调用的函数,槽为程序员定义,并且当系统调用该槽对应的信号函数时,自动调用的函数。

这里,我们需要实现的功能为:当按下 “更改” 时,将 LineEdit中的内容显示到Label中。我们需要设计 “更改” 的响应函数,使得当他被点击时,做出相应的动作。

最简单的创建方式

右键你所相应的模块,然后选择 “转到槽…” ,选择一个你所需要它相应的信号函数(点击的信号函数为clicked()与clicked(bool))。这时,系统就自动为你创建好了槽函数。这里我们选择创建一个clicked()的槽函数。

这里说明一下两个信号函数的区别。调用上,他们没有区别,即当“更改”按钮被点击时,两个信号函数都会被调用。参数传递上,他们有区别,后一个带一个参数,也就是bool checked,这个参数的值为当前按钮的状态。

然后会自动转到mainwindow.cpp文件里,你会发现多了一个函数
在这里插入图片描述
这个就是对应的槽函数。实现的功能为:当你点击那个“更改”按钮的时候,clicked()信号函数会调用,继而on_pushButton_clicked()会被系统联动调用。

*使用代码创建

这里只给出代码,不做深入讲解(可能下节讲)。

mainwindow.h在类中增添了

class MainWindow : public QMainWindow
{
    //......
private slots:
    void labelChangeText();
    
    //......
}

mainwindow.cpp中增加了

MainWindow::MainWindow(QWidget *parent):
	:QMainWindow(parent),ui(new Ui::MainWindow)
{
    //...
    connect(ui->pushButton,SIGNAL(clicked()),
            this,SLOT(labelChangeText()));
    //...
}

注:有多种connect写法,这里只放一种。

设计槽

这里给出按照右键创建的方式的代码。

void MainWindow::on_pushButton_clicked()
{
    QString qs = ui->lineEdit->text();
    ui->label->setText(qs);
    //等价于ui->label->setText(ui->lineEdit->text());
}

tips:如何知道ui->lineEdit->text()的类型为QString?先把这个语句写出来,补全中会提示QString text() const,那么你就获得了这个text()的返回值QString

运行你的代码

左下角四个框框,如果你的有两个没亮(也就是点不了那个三角号),你需要点从上到下第一个图标去重新配置该项目的编译器(MSVC/MinGW)这样的。

然后三角号是按照你配置的编译器来编译。从上到下第三个带个甲壳虫的三角是以Debug模式编译(允许设置断点)。

And then,大功告成。

跟535一起从零开始学QT-信号与槽机制

QT中信号与槽机制简化了编程的过程。最简单的使用方式:右键点击操作部件,然后点击转到槽,就可以设计相关的槽函数了。
在这里插入图片描述

但是但是,这个过程是怎么来的呢?

这里就需要涉及到信号与槽了。

简单的引入

上述的这个过程如果用代码来写出,应该添加的代码为:

mainwindow.h

class MainWindow:public QMainWindow
{
    //....
private:
    void initSignalSlot();
private slots:
//这里的private与普通类里的private作用相同,都是限制只能内部访问。
    void btnCalculate_clicked();
    //命名规则,前面是部件的名称,后面是信号函数名
    //....
}

mainwindow.cpp

//下面这个是构造函数
MainWindow::MainWindow(QWeidget *parent):
	QMainWindow(parent),ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    initSignalSlot();
    //我们自己写的初始化 “信号与槽关系” 的函数
}

void MainWindow::initSignalSlot(){
    connect(ui->btnCalculate,SIGNAL(clicked()),
            this,SLOT(btnCalculate_clicked()));
    //connect((指针类型)sender,SIGNAL(信号函数,参数用类型代替),(指针类型)reciever,SLOT(reciever的相应函数,参数用类型代替));
}

void MainWindow::btnCalculate_clicked(){
    //.........你想要的响应
}

这里给出的connect函数形式为QT4语法,但是QT5兼容QT4,所以此处给出的这种可以在QT5里面写。

那么,如果你用右键转到槽的方式创建,你找不到这个connect函数,它内部实现原理是系统在编译的过程中,帮你创建了connect,规则是按照函数的名称。

虚拟的例子

案例:假设你遇到了一个陌生的异性,然后你亲了TA一下;这时候TA打了你一巴掌。

换成QT的信号与槽而讲,上述过程可以描述为如下的情况:

  1. 你发出信号:亲了TA一下
  2. TA做出相应:打了你一巴掌

这时候,假设你是变量you,TA是变量ta,亲是信号函数mua,打你一巴掌是槽函数hit。那么以下句子就可以完成该事件之间的连接

connect(&you,SIGNAL(mua()),&ta,SLOT(hit()));

创建信号函数与槽函数

  1. 槽函数

    槽函数可以看作是类的一个普通成员函数,它也有public, private, protected这三种属性,对应的含义与成员函数相同。不过创建时需要使用public slots / private slots / protected slots。以下是几种例子

    //mainwindow.h
    class MainWindow:public QMainWindow
    {
    	//...
    public slots:
        void hit();
        void publicSlot();
        void publicSlot1(int x);
        void publicSlot2(int x,int y);
    private slots:
        void privateSlot();
    protected slots:
        void protectedSlot();
        //...
    }
    

    不过槽函数除了定义之外,还需要在对应的.cpp文件中进行具体的实现。就类似于写那个函数。

  2. 信号函数

    信号函数不是一个普通的成员函数,它不需要你进行具体实现,只需要定义即可。实现是QT编译的事情。定义一个信号函数,需要使用signals标识符,用法类似public。而且,所有信号函数必须是void类型。以下是一个例子

    //mainwindow.h
    class MainWindow:public QMainWindow
    {
    	//...
    signals:
        void mua();
        void mySiganl();
        void mySignal1(int x);
        void mySignal2(int x,int y);
       	//...
    }
    

将信号与槽关联起来

有很多方式,有建立关联,也有取消关联。常见的是使用connect, disconnect这两个函数进行这项工作。由于取消关联并不是很必要,在结构体析构函数被调用的时候,所有东西就都没了,所以这里只给出如何建立关联。

正如最开始所引入的东西,connect的最简单用法如下

connect((指针类型)sender,SIGNAL(信号函数,参数用类型代替),(指针类型)reciever,SLOT(reciever的相应函数,参数用类型代替));

这里需要注意的是,如果你想连接到定义的地方,需要使用this指针。

以下实例表示我想从mua()连接到hit()的实现方式

//mainwindow.h
class MainWindow:public QMainWindow
{
	//...
public:
    MainWindow();
signals:
    void mua();
    void mua1(int x);
public slots:
    void hit();
   	//...
}
//mainwindow.cpp
MainWindow::MainWindow(){
    //...
    connect(this,SIGNAL(mua()),this,SLOT(hit()));
    connect(this,SIGNAL(mua1()),this,SLOT(hit()));
    //...
}

void MainWindow::hit(){
    bool have_been_hit = 0;
    have_been_hit = 1;
    return;
    //随便写的
}

其中一个信号连接到多个槽是可以的。作用是:当这个信号被发送的时候,所有槽都会执行,但顺序不可控。

多个信号连接到一个槽也是可以的。作用是:任何一个信号产生都会调用这个槽函数。也就是并联的关系。

有参数的时候只需要写那个参数的类型,而不需要写具体的名。

调用信号函数、槽函数

由于槽函数QT说它可以像一般的成员函数一样,所以它的调用就不细讲了。需要用的时候直接hit()就完事了。

信号函数:最标准的调用方法是emit mua()。当你有参数的时候需要在括号内填上相应的参数,也就是emit mySignal1(2)这样的。当然也可以用变量代替那个位置,就跟普通的传参一样。

信号与槽之间的参数传递

你看我们上面定义的那些信号函数和槽函数,它的参数是干啥的呢?

当我们使用这个参数的时候,需要有一个条件:connect的槽的参数要小于等于对应的信号的参数。

  1. 信号参数与槽参数对等(数据类型和个数均相同,名字不用)。则槽函数的那些参数就是信号函数对应的那些。
  2. 信号参数多于槽参数,但从前往后看都对等。则槽函数会依次接受信号函数的前面的参数。

举个例子:

//mainwindow.h
class MainWindow:public QMainWindow
{
	//...
signals:
    void mua0();
    void mua1(int x);
    void mua2(int x,int y);
public slots:
    void hit0();
    void hit1(int x);
    void hit2(int x,int y);
   	//...
}

下面开始分析其connect关系与参数传递情况。假设以下写的位置都合适。

connect(this,SIGNAL(mua0()),this,SLOT(hit0()));
connect(this,SIGNAL(mua1(int)),this,SLOT(hit1(int)));
connect(this,SIGNAL(mua2(int,int)),this,SLOT(hit2(int,int)));
//上面三个对应传参,就是信号函数第一个参数进槽函数第一个参数,第二个进第二个参数

connect(this,SIGNAL(mua0()),this,SLOT(hit1(int)));
connect(this,SIGNAL(mua0()),this,SLOT(hit2(int,int)));
connect(this,SIGNAL(mua1(int)),this,SLOT(hit2(int,int)));
//上面都是不合适的,因为槽函数参数多于信号函数了。

connect(this,SIGNAL(mua1(int)),this,SLOT(hit0()));
connect(this,SIGNAL(mua2(int,int)),this,SLOT(hit0()));
connect(this,SIGNAL(mua2(int,int)),this,SLOT(hit1(int)));
//上面三个是合适的,前两个并不会接受到参数。第三个hit1会接受到mua2的第一个int参数。

拓展阅读

Qt之信号signals和槽slots详解:(https://blog.csdn.net/bruce_0712/article/details/53694374)

Qt信号与槽机制详解:(http://c.biancheng.net/view/1823.html)

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值