Qt面试常见问题

2 篇文章 0 订阅

qt元对象系统

qt的元对象编译系统MOC是一个预处理器,当qt读取源文件时检测到类中包含有Q_OBJECT宏时,则会创建一个新的文件,将源码转换为C++编译器可以识别的代码写入moc开头的文件,然后C++编译器对其进行编译。使用moc系统的方法:1、继承QObject;2、类中添加Q_OBJECT宏

信号槽机制

信号和槽是用于对象之间进行通信的,是Qt的核心,为此Qt引入了一些关键字,slots,signals,emit。信号槽支持线程间通信,connect函数的第五个参数可以指定信号槽的连接方式

信号槽连接方式:

1、 Qt::AutoConnection:信号的发送者和接收者在同一个线程,默认使用Qt::DirectConnection,不在同一个线程,默认使用Qt::QueuedConnection

2、 Qt::DirectConnection:信号的发送者与信号的接收者在同一线程中执行,当发出信号后,会马上进入槽函数,看上去就像在信号  发送位置调用了槽函数,在多线程下会比较危险,容易造成崩溃。

3、 Qt::QueuedConnection:信号的发送者与信号的接收者不在同一线程中执行,槽函数运行于信号的接收者线程,当发送信号后,  槽函数不会马上被调用,等待信号的接收者把当前函数执行完,进

入事件循环之后,槽函数才会被调用。多线程环境下一般用这个。

4、 Qt::BlockingQueuedConnection:槽函数的调用时机与Qt::QueuedConnection一致,不过发送完信号后发送者所在线程会阻塞,直到槽函数运行完。接收者和发送者绝对不能在一个线程,否则程序会死锁。在多线程间需要同步的场合可能需要这个。

5、Qt::UniqueConnection:可以通过按位或(|)与以上四个结合在一起使用。当设置此参数时,当某个信号和槽已经连接时,再进行重复的连接就会失败,也就是避免了重复连接。

信号槽的优缺点

优点:

1、类型安全:需要关联的信号槽的签名必须是等同的,即信号的参数类型与槽的参数类型是一致的。

2、松散耦合:QT对象只需要在适当时间发送适当信号即可,不需要关心是否被接受。

3、灵活性:一个信号可以关联多个槽,或多个信号关联同一个槽

不足:

速度较慢:和回调函数比,信号槽机制比直接调用非虚函数的速度慢10倍

原因:需要定位接收信号的对象,2、安全遍历所有关联槽,3、编组、解组传递参数、4、多线程时候,信号需要排队。

信号和槽的本质

本质还是回调函数,信号或是传递值,或者是传递动作变化,槽函数响应信号或者接收值

MVD

Qt的MVD包含三个部分Model(模型),View(视图),代理(Delegate)。

model负责保存数据,view负责展示数据,delegate负责item样式绘制或者处理输入。这三部分通过信号槽进行通信。当modle中数据变化时会发送信号到view,在view中编辑数据,delegate负责将编辑的状态发送给model。基类分别为QAbstractItemModel、QAbstractItemView、QAbstractItemDelegate。Qt提供了默认的MVD类,QTableWidget、QListWiget、QTreeWiget

QGraphicsView。

Qt多线程

实现方法:

1、QThread,重写QThread类中的run方法。

优点:实现简单,可以用信号槽通信

缺点:自己管理线程,频繁创建释放的话 效率不高

2、QThread类与MoveToThread,创建对象继承QObject,将对象移动到子线程对象

优点:实现简单,适用于比较复杂的业务场景

缺点:只能通过信号槽的方式进行调用业务接口,且不能给此对象指定父对象

3、QThreadPool和QRunnable,继承QRunnable实现run方法完成业务类创建,由QThreadPool启动业务类

优点:无需关注线程资源管理,不会频繁创建销毁

4、QtConcurrent::run直接将任务丢进子线程执行

优点:调用简单,无需关注线程资源,不会频繁创建销毁

Qt事件处理机制

事件:键盘事件、鼠标事件、拖放事件、滚轮事件、焦点事件、移动事件。。。

QT将产生的消息转为事件,事件被封装为对象,所有的qt事件均继承抽象类QEvent,用于描述程序内部或者外部发生的动作,任意的QObject对象都具备处理QT事件的能力

QInputEvent、QDropEvent、QPaintEvent、QCloseEvent、QTimerEvent

1、QT事件的产生:

1、操作系统事件:鼠标、键盘事件等

2、Qt应用程序自己产生:调用QApplication::postEvent(配在堆上的事件对象)或sendEvent(支持分配在栈上和堆上的事件对象)

2、QT事件通知、派发

从QApplication::notify开发,因为QApplication继承于QObject,所以先检查QApplication对象,如果安装了事件过滤器,先调用事件过滤器,过滤或者合并一些事件,事件被发送到reciver::event上

在reciver::event上,先检查有没有安装事件过滤器,有则调用,然后根据QEvent的类型调用响应的事件处理函数。比如:mousePressEvent(), focusOutEvent(),  resizeEvent(), paintEvent(),

resizeEvent()等等。

3、事件的转发

对应某些类别的事件,如果在事件的派发过程后还没有被处理,那么这个事件将向上转发给他的父widget,直到最顶层窗口。

qt中事件通信交互函数有两种:一种是QApplication::notify---QObject::eventFilter---QObject::event 通过bool返回值来判断是否已处理

另一种:QEvent::ignore或QEvent::accept对事件进行标识,只用于event函数和特定事件处理函数之间的沟通,,而且只有用在某些类别事件上是有意义的, 这些事件就是上面提到的那些会被转发的事件,

包括: 鼠标, 滚轮, 按键等事件。

4、事件的处理和过滤

qt提供了5种不同级别的处理和过滤:

1、重写特定事件处理函数

2、重写event函数

3、在事件上安装事件过滤器

4、给QApplication对象安装事件过滤器

5、继承QApplication类,并重载notify函数

QT的TCP通讯流程

服务端(QTcpServer)

1、创建QTcpServer对象

2、监听list需要的参数是地址和端口号

3、当有新的客户端连接成功会发送newConnect信号

4、在newConnection信号槽函数中,调用nextPendingConnection函数获取新连接QTcpSocket对象

5、连接QTcpSocket对象的readRead信号

6、在readRead信号的槽函数使用read接收数据

7、调用write成员函数发送数据

客户端(QTcpSocket)

1、创建QTcpSocket对象

2、当对象与Server连接成功时会发送connected信号

3、调用成员函数connectToHost连接服务器,需要的参数是ip/port

4、connected信号的槽函数开启发送数据

5、使用write发送数据,read接收数据

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bussy-Lake

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值