1.事件循环
Qt的主事件循环能够从事件队列中获取本地窗口系统事件,然后判断事件类型,并将事件分发给特定的接收对象。
主事件循环通过调用QCoreApplication::exec()启动,随着QCoreApplication::exit()结束,本地的事件循环可用利用QEventLoop构建。
2.多线程
第一种方法:
- 创建一个类从QThread类派生
- 在子线程类中重写 run 函数, 将处理操作写入该函数中
- 在主线程中创建子线程对象, 启动子线程, 调用start()函数
第二种方法: - 将业务处理抽象成一个业务类, 在该类中创建一个业务处理函数
- 在主线程中创建一QThread类对象
- 在主线程中创建一个业务类对象
- 将业务类对象移动到子线程中
- 在主线程中启动子线程
- 通过信号槽的方式, 执行业务类中的业务处理函数
多线程使用注意事项:
-
- 业务对象, 构造的时候不能指定父对象
-
- 子线程中不能处理ui窗口(ui相关的类)
-
- 子线程中只能处理一些数据相关的操作, 不能涉及窗口
3.多线程同步
1.临界区被初始化后,当程序进入临界区后便拥有临界区的所有权,其余线程无权进入只能等对方释放临界区之后,方可进入临界区拥有其所有权再对临界区进行操作临界区为依次访问,不能实现其中一个线程一释放临界区就会被另一个线程访问临界区!不能实现实时监听;
2.事件对象是指用户在程序中使用内核对象的有无信号状态实现线程的同步临界区被初始化后一旦事件对象被设置为有信号 立刻会被其余线程访问!能实现实时监听
3.互斥对象还可以在进程间使用,在实现线程同步时包含一个线程ID和一个计数器,
线程ID表示拥有互斥对象的线程,计数器表示该互斥对象被同一线程所使用次数
一旦互斥对象被释放 立刻会被其它正在等待的线程访问!能实现实时监听;
- 子线程中只能处理一些数据相关的操作, 不能涉及窗口
答:一般是指把指针封装到一个类中,这个类中还封装了一个计数器,
对指针的复制等操作将导致该计数器加1,对指针delete会减1,直到为0,
指针为NULL。
智能指针有:
shared_ptr、weak_ptr、unique_ptr和auto_ptr(c++11摒弃);
分别有:
1.auto_ptr定一对象可以将new到的地址赋给这一对象,当智能指针过期时
析构函数会调用delete函数,对象被销毁,由此内存可以自动被释放;
2.shared_ptr允许多个指针指向同一个对象,每多一个指针指向,
计数就会加1,释放的时候,当值减为0即最后一个指针过期才会delete函数11
3.unique_ptr唯一的,只能一个指针指向一个对象。
4.weak_ptr为配合shared_ptr而引入的用于协助shared_ptr工作.
5.qt信号槽是什么?
答:信号槽实际就是观察者模式,当某个事件发生之后,它就会发出一个信号(signal),
这个信号类似广播, 想要处理的信号和自己的一个函数(槽函数(slot))绑定处理这个信号
当信号发出时,被链接的槽函数会自动被回调;
信号和槽是qt特有的信息传回机制,是QT设计程序的重要基础,它可以让互不相干扰的对象建立一种联系;
槽本质是类的成员函数,其参数可以是任意类型。
和函数唯一区别是:槽可以与信号连接在一起,每当和槽连接的信号被发射的时候,就会调用这个槽。
优缺点:
a QT信号槽机制的引用精简了程序员的代码量;
b QT的信号可以对应多个槽(但他们的调用顺序是随机),也可以多个槽映射一个信号;
c QT的信号槽的建立和解除绑定十分自由;
d信号槽同真正的回调函数比起来时间的耗损还是很大的,所有在嵌入式实时系统中应当慎用;
e信号槽的参数限定很多例如不能携带模板类参数,不能出现宏定义等等;
6.信号槽的四种写法和五种连接方式?
connect(信号发出者,信号,信号接收者,槽,连接方式(隐藏默认自动连接))//五个参数
四种写法:
1.用宏:
connect(this,SIGNAL(clicked()),this,SLOT(colse())); //连接方式(隐藏默认自动连接))
2.用函数指针: connect(this,&mainwindow::my_signal,this,&mainwindow::my_slot);
3.用重载函数指针Qoverload
connect(this,Qoverload<参数>::of(&mainwindow::my_signal),this,Qoverload<参数>::of(&mainwindow::my_slot));
4.lambda表达式(匿名函数) 匿名函数代替槽
connect(this,&mainwindow::my_signal,this,[=]{qDebug()<<100; });
连接方式:自动连接(默认连接方式)
直接连接(用于单线程,自动匹配)
队列(用于多线程也可用于单线程,自动匹配)
阻塞队列(跨线程,多线程)
唯一连接(跨线程,多线程)
7.Lambda表达式
答:lambda表达式主要分五部分:[函数对象参数]、(操作符重载函数参数)、mutable或 声明、->返回值类型、{函数体} [捕获列表] (参数列表) 函数选项 -> 返回值类型 {函数体}
[&]:以引用的方式捕获外部的所有变量,如果在函数体内改变外部变量值,外部变量值就会随之改变;
[=]:以值的方式捕获外部的所有变量,如果在函数体内改变“外部变量值”,外部变量值不会改变;
【QT|QT面试】8.q、d指针干什么用的?为了解决什么问题?
答:q子类获取父类私有成员指针
d在父类获取子类私有成员指针
为解决二进制兼容
所谓二进制兼容动态库,指的是一个在老版本库下运行的程序,在不经过编译的情况下,仍然能够在新的版本库下运行;
需要经过编译才能在新版本下运行,而不需要修改该程序源代码,我们就说该动态库是源代码兼容的;
9.qt模型
答:Qt中的View主要有三种QListView,QTreeView, QTabelView
而对应的Model是:QStringListModel, QAbstractItemModel , QStandardItemModel。
抽象 标准
10.自定义控件?
答:qt本身的控件不能满足需求将原控件功能提升达到要求,此时控件为自定义控件;
11.qt跨平台:程序在编译前会先使用元对象编译器(moc)分析c++源文件然后确定方向
12.自动分辨率、使用布局中的rsizeEvent函数可实现自动调整分辨率,可能会失真,尽量使用原图大小QML作为Qt中为UI而生的,使用QML一定要解决适配的问题。
在QML中使用 anchors 进行相对的布局时,其是以像素为单位。
13.设置字体 颜色
QLabel *label = new QLabel(“Hello World!”); //新建一个显示"Hello World"的Label
//使用setPalette()方法改变颜色
QPalette pt; //调色板
pt.setColor(QPalette::WindowText, Qt::red); //设置为红色
label->setPalette(pt);
//使用setFont()方法改变字体样式
QFont font(“Microsoft YaHei”, 12,75); //设置为微软雅黑,字体12号,加粗
/常见权重(第三个参数):
QFont::Light - 25 高亮
QFont::Normal - 50 正常
QFont::DemiBold - 63 半粗体
QFont::Bold - 75 粗体
QFont::Black - 87 黑体/
label->setFont(font);
//使用样式表改变颜色
label->setStyleSheet(“color:blue; ”); //设置为蓝色
//使用简单的HTML样式改变颜色和样式
QLabel *label2 = new QLabel(“
Hello”
“World!”)
推荐阅读
- 个人日记|K8s中Pod生命周期和重启策略
- 学习分享|【C语言函数基础】
- C++|C++浇水装置问题
- 数据结构|C++技巧(用class类实现链表)
- C++|从零开始学C++之基本知识
- 步履拾级杂记|VS2019的各种使用问题及解决方法
- leetcode题解|leetcode#106. 从中序与后序遍历序列构造二叉树
- 动态规划|暴力递归经典问题
- 麦克算法|4指针与队列
- 遇见蓝桥遇见你|小唐开始刷蓝桥(一)2020年第十一届C/C++ B组第二场蓝桥杯省赛真题