1.在Qt中,多线程环境下,信号槽分别在什么样的线程中执行,如何控制?
(1)信号槽的执行线程
- 如果信号和槽都在同一个线程,就它们就在这个线程中执行
- 如果信号和槽不在同一个线程:
- Qt::DirectConnection:信号槽会在信号发射的线程中直接执行。(可能导致线程安全问题)
- Qt::QueuedConnection:信号槽的执行将被放入接收槽所在线程的事件队列中,然后在该线程的事件循环中执行。(可以在不同线程中安全的传递信号)
- Qt::AutoConnection:这个连接方式会根据信号和槽所在的线程选择合适的连接方式,当两者在一个线程中选择 Qt::DirectConnection ,不在一个线程中选择 Qt::QueuedConnection 。
(2)控制信号槽的执行线程
- QObject :: moveToThread:可以使用这个函数将一个 QObject 派生类的对象移到目标线程中,从而使其信号槽在目标线程中执行。
cpp
MyObject *myObject = new MyObject;
QThread *thread = new QThread;
myObject->moveToThread(thread);
connect(sender, SIGNAL(someSignal()), myObject, SLOT(someSlot()));
thread->start();
- Qt::QueuedConnection**:** 在连接信号槽时,明确指定使用队列连接方式,可以确保信号槽在接收信号的线程的事件循环中执行(无论事件和槽是否位于不同线程中)。
cpp
connect(sender, SIGNAL(someSignal()), myObject, SLOT(someSlot()), Qt::QueuedConnection);
- Qt::AutoConnection:自动选择适应的连接方式。
cpp
connect(sender, SIGNAL(someSignal()), myObject, SLOT(someSlot()), Qt::AutoConnection);
2.在Qt开发中,UDP协议当中的UdpSocket 通讯流程?
- 第一步,创建UDP 套接字(QUdpSocket)
- 第二步,服务器端进行绑定IP地址和端口号(bind)
- 第三步,发送数据(接收数据)(writeDatagram、readDatagram(readyRead信号->相应槽函数))
- 第四步,关闭套接字
3.在Qt开发当中,TCP协议通讯流程?
- 第一步,创建服务器端或客户端对象(服务器:QTcpServer 客户端:QTcpSocket)
- 第二步,服务器端进行 listen 监听
- 第二步,连接信号和槽
- 服务器端连接 QTcpServer 的 newConnection 信号
- 客户端连接 QTcpSocket 的信号,如 connected、readyRead(当有数据可读时触发)、disconnected 等
- 第三步,建立连接
- 服务器端:在 newConnection 槽内创建新的 QTcpSocket 来处理客户端连接
- 客户端:使用 connecToHost 连接到服务器
- 第四步,双方都可以通过 QTcpSocket 发送和接收数据
- 第五步,使用 close 关闭套接字连接,服务器端在 disconnected 槽内移除连接。
4.Qt信号槽机制优点与缺点?
优点:
- 松耦合:信号槽机制将信号发送和信号接收解耦,使得各个组件依赖关系比较松散。
- 事件驱动:可以在两个对象中通过信号触发自定义操作,使得事件驱动变得简单。
- 多线程支持:因为信号和槽可以在多线程环境中正常运行。
- 可读性:直观的描述了对象之间的交互关系。
缺点:
- 性能开销:信号槽机制有一定性能开销,某些性能敏感的应用中可能需要考虑。(速度相对比较慢)
- 运行时错误检查:信号槽连接的错误只在运行时捕获,当出现错误,无法在编译时知道
- 不适用所有场景:信号和槽机制更适合事件驱动和异步编程,简单的同步操作可以直接函数调用。
5.Qt 中文件流 QTextStream 和数据流 QDataStream 有什么区别?
- QTextStream 适用于处理文本文件,它处理文本数据的编码和换行符等细节,提供文本 I/O 操作。
- QDataStream 适用于处理二进制数据,它可以操作各种数据类型。
6.Qt中的智能指针?
- QSharedPointer:共享指针
- QScopedPointer:弱引用指针
- QWeakPointer:独占指针