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. 记一次 .NET 某工控电池检测系统 卡死分析

    一:背景 1. 讲故事 前几天有位朋友找到我,说他的窗体程序有卡死现象,让我帮忙看下怎么回事,解决这种问题就需要在卡死的时候抓一个dump下来,拿到dump之后就可以分析了. 二:为什么会卡死 1. ...

  2. 在Window系统中安装VMware虚拟机搭建Linux服务器

    1.什么是VMware Workstation VMware Workstation Pro是一款桌面虚拟化软件.我们可以通过Workstation Pro在Windows或Linux PC上运行多个 ...

  3. Java基础知识(纯干货)

    基础篇 IDEA 开发 Java项目 卸载JDK 删除Java的安装目录 删除JAVA_HOME 删除path下关于java的目录 java -version 安装JDK17 下载链接:https:/ ...

  4. 七天.NET 8操作SQLite入门到实战 - 第二天 在 Windows 上配置 SQLite环境

    前言 SQLite的一个重要的特性是零配置的.无需服务器,这意味着不需要复杂的安装或管理.它跟微软的Access差不多,只是一个.db格式的文件.但是与Access不同的是,它不需要安装任何软件,非常 ...

  5. H.264 和 H.265对比

    前言 H.264标准正式发布于2003年3月,距今已经20多年了,但它仍然是当下最流行的视频编解码标准. H.265正式发布于2013年4月.虽然H.265标准是围绕着H.264进行制定的,也保留了原 ...

  6. Linux机器自建账号并赋予sudo权限,同时修改远程端口

    默认使用root账号来操作Linux有一定风险,因此需要自建账号并赋予sudo权限,方便使用 登录为root用户后,创建账号 adduser <username> Ubuntu系统会同时要 ...

  7. 2. Shell 条件测试

    重点: 条件测试. read. Shell 环境配置. case. for. find. xargs. gzip,bzip2,xz. tar. sed. 1)位置 变量 位置变量:在 bash She ...

  8. 什么是cursor?怎么使用cursor?

    Cursor 在Android查询数据时就是通过Cursor类来实现的.当我们使用SQLiteDatabase.query()方法时,就会得到Cursor对象,Cursor所指向的就是每一条数据. 举 ...

  9. 基于WPSOffice+Pywpsrpc构建Docker镜像,实现文档转换和在线预览服务

    背景 产品功能需要实现标准文档的在线预览功能,由于DOC文档没办法直接通过浏览器打开预览,需要提前转换为PDF文档或者HTML页面. 经过测试发现DOC转为HTML页面后文件提交较大,而且生成的静态资 ...

  10. 浅析 ArrayList

    by emanjusaka from https://www.emanjusaka.top/2023/12/java-arrayList 彼岸花开可奈何 本文欢迎分享与聚合,全文转载请留下原文地址. ...