1 基本规范:

无论是写什么样的代码,第一步都应该是创建一个程序对象

#include <QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);//创建对象并调用构造函数 return a.exec();//因为是gui界面开发,那么程序的生存周期应该是一直存在的
}

2 debug和release文件

debug中存放调试版本的可执行程序,release存放发布版本

3 窗口

在Qt中主要有三种顶层窗口:

  • QWidget:最基础的窗口,所有窗口及控件都继承QWidget。
  • QDialog:对话框窗口,可类比Windows中的对话框。
  • QMainWindow:主窗口,一般主窗口会包括标题栏,菜单栏,工具栏,中心部件,停靠窗口,状态栏等。可类比桌面应用程序。

父窗口,子窗口:当部件1嵌入到部件2中,就把部件2称作是部件1的父窗口,而部件1是部件2的子窗口。

如果一个窗口具有父类,则这个窗口被称为是次级窗口(部件),例如设置了父类的QDialog就是次级窗口,而这些窗口不会被列在任务栏中,而是在各自的父窗口之上。

对窗口的参数设置通常在构造函数中实现

4 控件

当一个窗口嵌入到其它窗口中,则它本身的标题栏会隐藏,那这些窗口就叫作控件,也可以叫作非顶层窗口或子窗口。

5 信号和槽

QT最明显区别于其它开发框架的特征就是信号和槽。

在面向对象的编程方法中,都会创建很多的实例,每个实例都是单独的,要想每个实例能够协同合作,那么就会需要一种对象间传递消息的机制,在很多框架中都采用回调函数来进行对象间信息传递。

回调是一个指向函数的指针,如果想要一个处理函数通知一些事件,你需要将这个指针传递给处理函数。处理函数在适当时间调用回调函数。但回调可能是不直观的,不易于理解的,并且也不能保证是类型安全的。

Qt为了消除回调函数等的弊端,从而开发了一种新的消息传递机制,即信号和槽。可以将信号和槽理解成“命令-执行”,即信号就是命令,槽就是执行命令。

例如,当我们要求鼠标点击某个按钮时,对应的窗口就需要关闭,那么这个按钮就会发出一个点击信号,而窗口接收到这个信号后执行关闭窗口。那么,这个信号就是按钮被点击,而槽就是窗口执行关闭函数。

6 信号

当一个对象的内部状态发生改变时,如果其它对象对它的状态需要有所反应,这时就应该让这个类发出状态改变的信号。

声明信号使用signals关键字

发送信号使用emit关键字

注意:

1.所有的信号声明都是公共的,所以Qt规定不能在signals前面加public,private, protected。

2.所有的信号都没有返回值,所以返回值都用void。

3.所有的信号都不需要定义。

4.必须直接或间接继承自QOBject类,并且开头私有声明包含Q_OBJECT。

5.当一个信号发出时,会立即执行其槽函数,等待槽函数执行完毕后,才会执行后面的代码,如果一个信号链接了多个槽,那么会等所有的槽函数执行完毕后才执行后面的代码,槽函数的执行顺序是按照它们链接时的顺序执行的。

6.在链接信号和槽时,可以设置链接方式为:在发出信号后,不需要等待槽函数执行完,而是直接执行后面的代码。

7.发出信号使用emit关键字。

8.信号参数的个数不得少于槽参数的个数。

7 槽

槽其实就是普通的C++函数,它唯一特点就是能和信号链接。当和它链接的信号被发出时,这个槽就会被调用。

声明槽可以使用:public/protected/private slots:

以上是Qt4的做法,在Qt5中也不需要使用这些声明,每个函数都可以被当作是槽函数,而且还可以使用Lambda表达式来作为槽。不过为了程序的可读性,还是推荐槽函数要声明一下。

8 连接函数

static QMetaObject::Connection connect(
const QObject *sender, //信号发送对象指针
const QMetaMethod &signal,//信号函数地址
const QObject *receiver, //槽函数对象指针
const QMetaMethod &method,//槽函数地址
Qt::ConnectionType type = Qt::AutoConnection//连接类型,一般默认即可);
//例如connect(pushButton, QPushButton::clicked, dialog, QDialog::close);

9 QSignalMapper

当我们想要点击一个按钮,并且想将预先定好的参数一同发送出去时,由于按钮的点击事件clicked()并没有参数,那么按照一般的做法就会先定义一个槽与clicked()信号关联,然后获取参数,再通过自定义的信号将该参数发送出去。

这个过程无疑是繁琐的,为此,Qt提供了QSignalMapper这个类来解决这个问题。同时,这个类可以连接多个按钮,匹配发送信号的对象对应的整数、字符串,窗口指针,继承于QObject的对象参数重新发送它们。

10 moc编译器

moc(Meta-Object Compiler)元对象预编译器。

moc读取一个c++头文件。如果它找到包含Q_OBJECT宏的一个或多个类声明,它会生成一个包含这些类的元对象代码的c++源文件,并且以moc_作为前缀。

信号和槽机制、运行时类型信息和动态属性系统需要元对象代码。

由moc生成的c++源文件必须编译并与类的实现联系起来。

通常,moc不是手工调用的,而是由构建系统自动调用的,因此它不需要程序员额外的工作。

11 信号槽的调用流程

  1. moc查找头文件中的signals,slots,标记出信号和槽
  2. 将信号槽信息存储到类静态变量staticMetaObject中,并且按声明顺序进行存放,建立索引。
  3. 当发现有connect连接时,将信号槽的索引信息放到一个map中,彼此配对。
  4. 当调用emit时,调用信号函数,并且传递发送信号的对象指针,元对象指针,信号索引,参数列表到active函数
  5. 通过active函数找到在map中找到所有与信号对应的槽索引
  6. 根据槽索引找到槽函数,执行槽函数。

以上,便是信号槽的整个流程,总的来说就是一个“注册-索引”机制,并不存在发送系统信号之类的事情。

初识QT、窗口以及信号槽的更多相关文章

  1. Qt开发之信号槽机制

    一.信号槽机制原理 1.如何声明信号槽 Qt头文件中一段的简化版: class Example: public QObject { Q_OBJECT signals: void customSigna ...

  2. 初识Qt窗口界面

    1.新建一个新的Qt Gui应用,项目名称随意,例如MyMainWindow,基类选择QMainWindow,类名为MainWindow. 2.项目建立后,双击mainwindow.ui文件,在界面的 ...

  3. Qt::浅谈信号槽连接,参数在多线程中的使用

    Qt的信号槽有五种连接方式定义在enum Qt::ConnectionType,下面简单介绍 Qt::AutoConnection:自动判断连接方式,如果信号发送对象和执行槽对象在同一线程,那么等于Q ...

  4. QT中的信号槽

    只有继承了QObject类的类,才具有信号槽的能力.所以,为了使用信号槽,必须继承QObject. 凡是QObject类(不管是直接子类还是间接子类),都应该在第一行代码写上Q_OBJECT. 不管是 ...

  5. 如何才能学到Qt的精髓——信号槽之间的无关性,提供了绝佳的对象间通讯方式,QT的GUI全是自己的一套,并且完全开源,提供了一个绝好机会窥视gui具体实现

    姚冬,中老年程序员 叶韵.KY Xu.赵奋强 等人赞同 被邀请了很久了,一直在思考,今天终于下决心开始写回答. 这个问题的确是够大的,Qt的代码规模在整个开源世界里也是名列前茅的,这么大的项目其中的精 ...

  6. 使用 C++11 编写类似 QT 的信号槽——上篇

    了解 QT 的应该知道,QT 有一个信号槽 Singla-Slot 这样的东西.信号槽是 QT 的核心机制,用来替代函数指针,将不相关的对象绑定在一起,实现对象间的通信. 考虑为 Simple2D 添 ...

  7. Qt 学习之路:深入 Qt5 信号槽新语法

    在前面的章节(信号槽和自定义信号槽)中,我们详细介绍了有关 Qt 5 的信号槽新语法.由于这次改动很大,许多以前看起来不是问题的问题接踵而来,因此,我们用单独的一章重新介绍一些 Qt 5 的信号槽新语 ...

  8. Qt 学习之路 :信号槽

    信号槽是 Qt 框架引以为豪的机制之一.熟练使用和理解信号槽,能够设计出解耦的非常漂亮的程序,有利于增强我们的技术设计能力. 所谓信号槽,实际就是观察者模式.当某个事件发生之后,比如,按钮检测到自己被 ...

  9. Qt信号槽连接在有默认形参下的情况思考

    写下这个给自己备忘,比如函数 ) 你在调用端如论是test(3)或者test(),都可以正确调用到这个函数. 但是,如果放到Qt中的信号槽的话,这个还是值得讲一讲的,不然的话,可能会引起相应的误会. ...

  10. Qt学习记录--02 Qt的信号槽机制介绍(含Qt5与Qt4的差异对比)

    一 闲谈: 熟悉Window下编程的小伙伴们,对其消息机制并不陌生, 话说:一切皆消息.它可以很方便实现不同窗体之间的通信,然而MFC库将很多底层的消息都屏蔽了,尽管使用户更加方便.简易地处理消息,但 ...

随机推荐

  1. DiscuzQ官方最新v3.0.220211源码编译搭建教程和官方部署教程,适合二开(已本地编译通过,无任何错误)

    经过长达半个月的研究! 完成这篇DiscuzQ官方最新版本v3.0.220211的源码编译和官方部署教程.适合喜欢二次开发的小伙伴们,已经通过本地编译测试,保证没有任何错误. 具体教程在我搭建的dzq ...

  2. 等保测评之主机测评——Windows Sever

    目录 (一)身份鉴别 (二)访问控制 (三)安全审计 (四)入侵防范 (五)恶意代码防范 (六)可信验证 (七)数据完整性 (八)数据保密性 (九)数据备份恢复 (十)剩余信息保护 在测评过程中最为常 ...

  3. STM32外设:专用定时器 IWDG、WWDG、RTC

    主要外设: IWDG:Independent Watch DoG 独立看门狗 WWDG:Window Watch DoG 窗口看门狗 RTC: Real-Time Clock 实时时钟 IWDG 主要 ...

  4. 踩坑:nacos启动报错提示需要设置JDK环境 ,报错:ERROR: Please set the JAVA_HOME variable in your environment, We need java(x64)! jdk8 or later is better! !!

    换了个Windows11的新电脑,因为个人工作.学习需要,就重新下载了Nacos并解压使用,结果就踩了个坑,使用下面命令启动Nacos服务端时: startup.cmd -m standalone 直 ...

  5. idea用不了 idea.bat文件闪退

    由于idea的智能,在破解之后会留下一些问题,根据网上搜出来的解决办法. 1.C:\Users\dell\AppData\Roaming\JetBrains\IntelliJIdea2022.2 在这 ...

  6. JWT简单使用

    创建一个Maven项目,并导入jar包 <?xml version="1.0" encoding="UTF-8"?> <project xml ...

  7. Spingboot整合Dubbo+zookeeper

    前言: 2023-12-26 19:38:05 最近学习分布式技术:Dubbo+zookeeper,准备写一个demo用springboot整合dubbo和zookeeper.但是看了网上一些教程都是 ...

  8. Kotlin委托属性(1)

    在Kotlin中,委托属性(Delegated Properties)是一种强大的语言特性,允许你将属性的 getter 和 setter 方法的实现委托给其他对象.这使得你能够通过委托来重用代码.将 ...

  9. 面试官:单例Bean一定不安全吗?实际工作中如何处理此问题?

    默认情况下,Spring Boot 中的 Bean 是非线程安全的.这是因为,默认情况下 Bean 的作用域是单例模式,那么此时,所有的请求都会共享同一个 Bean 实例,这意味着这个 Bean 实例 ...

  10. 以小博大外小内大,Db数据库SQL优化之小数据驱动大数据

    SQL优化中,有一条放之四海而皆准的既定方针,那就是:永远以小数据驱动大数据.其本质其实就是以小的数据样本作为驱动查询能够优化查询效率,在SQL中,涉及到不同表数据的连接.转移.或者合并,这些操作必须 ...