讲述Qt信号槽机制的优势与不足
优点
(一)类型安全。需要关联的信号槽的签名必须是等同的。即信号的参数类型和参数个数同接受该信号的槽的参数类型和参数个数相同。若信号和槽签名不一致,编译器会报错。
(二)松散耦合。信号和槽机制减弱了Qt对象的耦合度。激发信号的Qt对象无需知道是那个对象的那个信号槽接收它发出的信号,它只需在适当的时间发送适当的信号即可,而不需要关心是否被接受和那个对象接受了。Qt就保证了适当的槽得到了调用,即使关联的对象在运行时被删除。程序也不会奔溃。
(三)灵活性。一个信号可以关联多个槽,或多个信号关联同一个槽。
不足
速度较慢。与回调函数相比,信号和槽机制运行速度比直接调用非虚函数慢10倍。
原因:(一)需要定位接收信号的对象。(二)安全地遍历所有关联槽。(三)编组、解组传递参数。(四)多线程的时候,信号需要排队等待。
Qt信号和槽的本质是什么
Qt信号和槽是一种用于实现对象间通信的机制。其本质是一种事件驱动的机制,通过信号和槽的连接,当信号被触发时,槽函数会被自动调用,从而实现对象间的通信和交互。
- 信号是一种特殊的函数,用于表示某种事件的发生,当事件发生时,信号会被自动发送出去,通知所有连接到该信号的槽函数。
- 槽是一种特殊的函数,用于处理信号的触发事件,当槽函数被连接到某个信号时,当该信号被触发时,槽函数会自动被调用,从而实现对信号的响应。
信号和槽的连接是通过Qt的元对象系统实现的,每个QObject派生类都有一个元对象,用于存储该类的属性、方法和信号槽信息。通过元对象系统,可以在运行时动态地连接信号和槽,从而实现对象间的通信。
总之,Qt信号和槽是一种事件驱动的机制,通过信号和槽的连接,实现了对象间的通信和交互。
描述Qt的TCP通讯流程
服务端:(QTcpServer)
(一)创建QTcpServer对象
(二)监听list需要的参数是地址和端口号
(三)当有新的客户端连接成功回发送newConnect信号
(四)在newConnection信号槽函数中,调用nextPendingConnection函数获取新连接QTcpSocket对象
(五)连接QTcpSocket对象的readRead信号
(六)在readRead信号的槽函数使用read接收数据
(七)调用write成员函数发送数据
客户端:(QTcpSocket)
(一)创建QTcpSocket对象
(二)当对象与Server连接成功时会发送connected 信号
(三)调用成员函数connectToHost连接服务器,需要的参数是地址和端口号
(四)connected信号的槽函数开启发送数据
(五)使用write发送数据,read接收数据
多线程使用使用方法
方法一:(一)创建一个类从QThread类派生(二)在子线程类中重写 run 函数,将处理操作写入该函数中 (三)在主线程中创建子线程对象,启动子线程,调用start()函数
方法二:(一)将业务处理抽象成一个业务类,在该类中创建一个业务处理函数(二)在主线程中创建一QThread类对象 (三)在主线程中创建一个业务类对象 (四)将业务类对象移动到子线程中 (五)在主线程中启动子线程 (六)通过信号槽的方式,执行业务类中的业务处理函数
自定义控件流程
继承需要自定义的控件类,如QPushButton。
- 从外观设计上:QSS、继承绘制函数重绘、继承QStyle相关类重绘、组合拼装等等。
- 从功能行为上:重写事件函数、添加或者修改信号和槽等等。
对QObject的理解
QObject 类是Qt所有类的基类。
QObject是Qt对象模型的核心。这个模型的中心要素就是一种强大的叫做信号与槽无缝对象沟通机制。
Qt 三大核心机制
信号槽
元对象系统
事件模型
Qt对象树
QT提供了对象树机制,能够自动、有效的组织和管理继承自QObject的对象。
信号槽的四种写法和五种连接方式
四种写法
- 宏
- 用函数指针
- 用重载函数指针
- lambda表达式(匿名函数) 匿名函数代替槽
连接方式
- 自动连接(默认连接方式)
- 直接连接(用于单线程,自动匹配)
- 队列(用于多线程也可用于单线程,自动匹配)
- 阻塞队列(跨线程,多线程)
- 唯一连接(跨线程,多线程)
说说经常使用到哪些Qt事件
常见的QT事件类型如下:
- 键盘事件: 按键按下和松开
- 鼠标事件: 鼠标移动,鼠标按键的按下和松开
- 拖放事件: 用鼠标进行拖放
- 滚轮事件: 鼠标滚轮滚动
- 绘屏事件: 重绘屏幕的某些部分
- 定时事件: 定时器到时
- 焦点事件: 键盘焦点移动
- 进入和离开事件: 鼠标移入widget之内,或是移出
- 移动事件: widget的位置改变
- 大小改变事件: widget的大小改变
- 显示和隐藏事件: widget显示和隐藏
- 窗口事件: 窗口是否为当前窗口
Qt事件机制有几种级别的事件过滤
根据对Qt事件机制的分析,我们可以得到5种级别的事件过滤。
- 重载特定事件处理函数
- 重载event()函数
- 在Qt对象上安装事件过滤器
- 给QAppliction对象安装事件过滤器
- 继承QApplication类,并重载notify()函数
Qt线程同步的方法有哪些
- 互斥量(QMutex)
- 互斥锁(QMutexLocker)
- 等待条件(QWaitCondition)
- QReadWriteLock类
- 信号量QSemaphore
Qt事件循环
Qt的主事件循环能够从事件队列中获取本地窗口系统事件,然后判断事件类型,并将事件分发给特定的接收对象。
主事件循环通过调用QCoreApplication::exec()启动,随着QCoreApplication::exit()结束,本地的事件循环可用利用QEventLoop构建。
描述Qt中的文件流和数据流
QTextStream – 文本流,操作轻量级数据(int,double,QString),数据写入文件中之后以文本的方式呈现。
QDataStream – 数据流,通过数据流可以操作各种数据类型,包括类对象,存储到文件中数据可以还原到内存。
QTextStream,QDataStream可以操作磁盘文件,也可以操作内存数据,通过流对象可以将数据打包到内存,进行数据的传输。
Qt中的内存管理机制
所有继承自QOBJECT类的类,如果在new的时候指定了父亲,那么它的清理时在父亲被delete的时候delete的。
所以如果一个程序中,所有的QOBJECT类都指定了父亲,那么他们是会一级级的在最上面的父亲清理时被清理,而不用自己清理。
描述Qt中消息从触发到处理的整个路由过程
应用程序启动,操作系统为程序创建一个对应的消息队列,用户对创建进行操作,产生一系列消息,操作系统首先捕捉到这些消息,将消息投递到对应的消息队列中,在应用程序中对应一个消息循环 。
消息循环每次从消息队列中取出消息,取出的消息如果是虚拟键消息,会将其转换成标准消息,将转换的消息再次投递到消息队列,如果取出的是标准消息,会将该消息发送给操作系统,操作系统会调用对应的窗口过程函数,下窗口过程函数中对对用的消息进程处理。
QApplication的主要作用是什么
QApplication对象管理QtGui应用程序的控制流程和主要的设置参数。
QMainForm是从哪里派生的
QMainWindow::QWidget::QObject
Qt设计界面有哪些方式
手工编写创建界面的代码:此方法比较复杂,不够直观。
使用Qt Designer界面编辑器设计:可直接拖放控件、设置控件的属性,简单、直观、易于操作。
动态加载UI文件并生成界面:此方法很灵活,当需要更改界面时只需更改.UI文件即可,无需重新编译程序。
Qt 中的容器类包括
QList:动态数组,支持随机访问和快速插入、删除操作。
QVector:类似 QList,但具有更好的性能。
QLinkedList:双向链表,支持快速插入、删除操作。
QHash:哈希表,支持快速查找、插入、删除操作。
QMap:基于红黑树的映射表,支持快速查找、插入、删除操作。
Qt中的模型视图框架是什么
模型视图框架是Qt中用于显示数据的一种机制。
该框架将数据模型和视图分离,使得数据的表示和显示可以独立地进行管理。数据模型提供了数据的接口,视图则负责绘制和交互。
Qt中的插件是什么
插件是Qt中用于扩展应用程序功能的一种机制。插件可以是动态链接库或静态链接库,包含了一些特定的功能。
通过插件,可以将应用程序的功能分解为多个独立的部分,方便开发和维护。
Qt中的样式表是什么
样式表是Qt中用于定制界面风格的一种机制。
样式表使用CSS语法,可以定义界面元素的属性、颜色、字体等。
Qt中的样式表可以应用于整个应用程序或特定的控件,使得应用程序的界面可以与众不同。
什么是Qt的MVC架构
Qt的MVC架构是一种基于模型、视图和控制器的设计模式,它将应用程序的数据、用户界面和业务逻辑分离开来,使得各个部分之间的耦合度更低,易于维护和扩展。
Qt中的指针
在Qt中,指针是一个很重要的概念,Qt提供了多种指针类来帮助我们管理内存和避免内存泄漏。下面是对常见的指针类进行简要介绍:
- QPointer
QPointer是Qt中的智能指针,它可以自动管理指针的生命周期,并且可以检测被管理的对象是否已经被销毁。如果被管理的对象已经被销毁,QPointer会自动将指针置为nullptr。QPointer通常用于管理QWidget对象等需要在程序运行期间动态创建和销毁的对象。
- QScopedPointer
QScopedPointer是Qt中的局部智能指针,它可以自动管理指针的生命周期,并且可以在指针超出作用域时自动释放指针指向的内存。QScopedPointer通常用于管理局部变量和堆内存对象等需要在作用域结束时自动释放的对象。
- QSharedPointer
QSharedPointer是Qt中的共享智能指针,它可以在多个指针之间共享同一个对象,并且可以自动管理指针的生命周期。当最后一个指向对象的QSharedPointer被销毁时,QSharedPointer会自动释放对象的内存。QSharedPointer通常用于管理需要在多个地方使用同一个对象的情况。
- QWeakPointer
QWeakPointer是Qt中的弱智能指针,它类似于QSharedPointer,但是不会增加对象的引用计数。QWeakPointer通常用于在多个指针之间共享同一个对象时,避免产生循环引用问题。
- std::weak_ptr
std::weak_ptr是C++11标准库中的弱智能指针,它类似于QWeakPointer,但是不是Qt所提供的。std::weak_ptr可以用于在多个指针之间共享同一个对象时,避免产生循环引用问题。
- QSharedDataPointer
QSharedDataPointer是Qt中的共享数据指针,它可以在多个对象之间共享同一个数据,而不需要共享整个对象。QSharedDataPointer通常用于实现copy-on-write(COW)技术,避免不必要的复制操作。
QString与基本数据类型如何转换
在Qt中,QString与基本数据类型之间可以进行方便的相互转换。下面是常见的转换方法:
(一)将QString转换为基本数据类型
通过QString的各种转换函数,可以将QString转换为int、float、double等基本数据类型。例如:
QString str = "123";
int num = str.toInt(); // 将QString转换为int类型
float f = str.toFloat(); // 将QString转换为float类型
double d = str.toDouble(); // 将QString转换为double类型
(二)将基本数据类型转换为QString
通过QString的静态函数,可以将int、float、double等基本数据类型转换为QString。例如:
int num = 123;
QString str = QString::number(num); // 将int类型转换为QString
float f = 3.14;
QString str2 = QString::number(f); // 将float类型转换为QString
请说出Qt常用控件
Qt中常用的8个控件包括:
- QLabel(标签控件):用于显示文本或图像。
- QPushButton(按钮控件):用于接收用户的点击事件。
- QLineEdit(单行编辑框控件):用于接收用户输入的单行文本。
- QTextEdit(多行编辑框控件):用于接收用户输入的多行文本。
- QComboBox(下拉框控件):用于在预定义的选项中进行选择。
- QCheckBox(复选框控件):用于允许用户选择一个或多个选项。
- QRadioButton(单选按钮控件):用于允许用户从多个选项中选择一个。
- QSpinBox/QDoubleSpinBox(数值输入框控件):用于接收用户输入的数值。 这些控件是Qt中非常常用的控件,常常用于创建用户界面。需要根据实际需求进行选择和使用。
Qt绘制原理双缓冲机制
Qt绘制原理中的双缓冲机制是指在绘制过程中使用两个缓冲区,一个用于绘制,一个用于显示,从而避免了绘制过程中的闪烁等问题。