Qt基础面试题

目录

一、QT的特点和优势:

二、Qt的缺点:

三、QT中的信号和槽是什么?如何使用?

四、QT中的文件流(QTextStream)和数据流(QDataStream)的区别

五、描述Qt下Tcp通信的整个流程 

六、描述QT下udp通信的整个流程 

七、QT如何使用HTTP协议

八、自定义控件的实现方法:

九、QSS使用方法:

十、QT的常见事件机制:

十一、QT事件机制的五种级别的事件过滤

十二、描述QT下多线程的两种使用方法, 以及注意事项 

十三、线程同步的方法

十四、多线程编程中,常见的锁:

十五、死锁,以及死锁如何产生


一、QT的特点和优势:

  • 跨平台性:QT支持多种操作系统,包括Windows、MacOS、Linux、Android和iOS等,具有很好的跨平台性。
  • 开放源代码:QT是开源的,任何人都可以免费使用和修改QT的源代码。
  • 丰富的组件库:QT提供了丰富的组件库,包括GUI组件、多媒体组件、网络组件、数据库组件等,开发者可以轻松地构建复杂的应用程序。
  • 可视化开发:QT提供了强大的可视化开发工具Qt Designer,开发者可以通过拖拽组件的方式快速构建界面,提高开发效率。
  • 高效的C++编程:QT是用C++编写的,提供了一套高效的类库和API,可以大大简化开发工作。
  • 丰富的社区支持:QT拥有庞大的社区支持,开发者可以通过QT官网和各种社区论坛获取帮助和交流经验。
  • 商业支持:QT的开发公司Digia提供了商业支持和服务,包括技术支持、培训、咨询等,可以帮助企业开发出高质量的应用程序。

二、Qt的缺点:

  • 复杂性:QT 是一个庞大的软件库,使用它需要学习大量的API和类。这使得QT的学习曲线较陡峭,尤其对于初学者来说。
  • 依赖性:QT 库需要依赖一些第三方库,如OpenGL、OpenSSL、DBus等,这会增加代码的复杂度和安装的难度。
  • 学习成本:由于QT使用C++编写,对于没有C++基础的开发者来说,学习成本较高。
  • 部署难度:QT的部署难度比较大,需要将QT库打包到应用程序中,这会增加应用程序的大小和安装难度。
  • 性能问题:QT的性能相对较低,与其他GUI框架相比,QT的性能可能会有所下降。
  • 商业许可证:QT有一个商业许可证,如果你想在商业应用中使用QT,你需要购买QT的商业许可证。

三、QT中的信号和槽是什么?如何使用?

1、信号槽是什么:

        信号和槽是QT中的一个重要机制,用于对象之间的通信。信号是对象发出的事件,槽是对象接收事件的方法。

2、信号槽的优缺点:

(1)优点:

  • 降低了模块之间的耦合度,使得模块之间的通信更加灵活。
  • 可以实现多对多的信号槽连接,方便了多模块间的交互。
  • 信号槽机制可以将信号和槽连接在一起,使得信号发生时,槽可以自动接收到信号,从而实现了自动化的事件响应。
  • 信号槽机制可以避免了回调函数的使用,从而使得代码更加简洁易读。

(2)缺点:

  • 由于信号槽机制是在运行时动态连接的,因此在连接时需要进行类型检查和转换,会带来一定的性能损失(在嵌入式实时系统中应当慎用),也会容易出现类型不匹配的问题。
  • 信号槽机制只能在Qt框架中使用,无法在其他框架中使用,因此会增加代码的依赖性。
  • 信号槽的参数限定很多例如不能携带模板类参数,不能出现宏定义等等

3、信号槽如何使用—步骤:

  • 在类中定义信号和槽方法,使用signals和slots关键字进行声明。
  • 在类的构造函数中,使用connect方法将信号连接到对应的槽方法。
  • 当对象发出信号时,槽方法会被自动调用。

4、信号槽的第五个参数,如何控制:

(1)Qt::AutoConnection: 默认值,使用这个值则连接类型会在信号发送时决定。如果接收者和发送者在同一个线程,则自动使用Qt::DirectConnection类型。如果接收者和发送者不在一个线程,则自动使用Qt::QueuedConnection类型。

(2)Qt::DirectConnection:槽函数会在信号发送的时候直接被调用,槽函数运行于信号发送者所在线程。效果看上去就像是直接在信号发送位置调用了槽函数。这个在多线程环境下比较危险,可能会造成奔溃。

(3)Qt::QueuedConnection:槽函数在控制回到接收者所在线程的事件循环时被调用,槽函数运行于信号接收者所在线程。发送信号之后,槽函数不会立刻被调用,等到接收者的当前函数执行完,进入事件循环之后,槽函数才会被调用。多线程环境下一般用这个。

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

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

四、QT中的文件流(QTextStream)和数据流(QDataStream)的区别

        他们都能帮助我们完成一些什么事情.:

(1)QTextStream – 文本流, 操作轻量级数据(int, double, QString), 数据写入文件中之后以文本的方式呈现。 

(2)QDataStream – 数据流, 通过数据流可以操作各种数据类型, 包括类对象, 存储到文件中数据可以还原到内存。 

QTextStream, QDataStream可以操作磁盘文件, 也可以操作内存数据, 通过流对象可以将数据打包到内存, 进行数据的传输。

五、描述Qt下Tcp通信的整个流程 

QT如果要进行网络编程首先需要在.pro中添加如下代码:QT += network 

1、服务器端: 

(1)创建用于监听的套接字 

(2)给套接字设置监听 

(3)如果有连接到来, 监听的套接字会发出信号newConnected 

(4)接收连接, 通过nextPendingConnection()函数, 返回一个QTcpSocket类型的套接字对象(用于通信) 

(5)使用用于通信的套接字对象通信 

        1>. 发送数据: write 

        2>. 接收数据: readAll/read 

2、客户端: 

(1)创建用于通信的套接字 

(2)连接服务器: connectToHost 

(3)连接成功与服务器通信 

        1>. 发送数据: write 

        2>. 接收数据: readAll/read

六、描述QT下udp通信的整个流程 

QT下udp通信服务器端和客户端的关系是对等的, 做的处理也是一样的. 

1. 创建套接字对象 

2. 如果需要接收数据, 必须绑定端口 

3. 发送数据: writeDatagram 

4. 接收数据: readDatagram 

七、QT如何使用HTTP协议

1、HTTP协议,QT5中使用的相关联的主要的几个类:

(1)QNetworkAccessManager

(2)QNetworkRequest

(3)QNetworkReply。

八、自定义控件的实现方法:

1、从外观设计上:QSS、继承绘制函数重绘、继承QStyle相关类重绘、组合拼装等等;

2、从功能行为上:重写事件函数、添加或者修改信号和槽等等

九、QSS使用方法:

1、QSS统一写在一个文件中,通过程序给主窗口加载;

2、写成一个字符串中,通过程序给主窗口加载;

3、需要使用的地方,写一个字符串,加载给对象;

4、QT Designer中填写;

十、QT的常见事件机制:

1、键盘事件按键按下和松开

2、鼠标事件鼠标移动,鼠标按键的按下和松开

3、拖放事件用鼠标进行拖放    

4、滚轮事件: 鼠标滚轮滚动

5、绘屏事件重绘屏幕的某些部分    

6、定时事件定时器到时

7、焦点事件键盘焦点移动   

8、进入和离开事件鼠标移入widget之内,或是移出

9、移动事件: widget的位置改变    

10、大小改变事件: widget的大小改变

11、显示和隐藏事件: widget显示和隐藏    

12、窗口事件窗口是否为当前窗口

十一、QT事件机制的五种级别的事件过滤

根据对Qt事件机制的分析我们可以得到5种级别的事件过滤,处理办法以功能从弱到强排列如下:

1、重载特定事件处理函数.

最常见的事件处理办法就是重载象mousePressEvent(), keyPressEvent(), paintEvent() 这样的特定事件处理函数.

2、重载event()函数.

通过重载event()函数,我们可以在事件被特定的事件处理函数处理之前(keyPressEvent())处理它比如当我们想改变tab键的默认动作时,一般要重载这个函数在处理一些不常见的事件(比如:LayoutDirectionChange),evnet()也很有用,因为这些函数没有相应的特定事件处理函数当我们重载event()函数时需要调用父类的event()函数来处理我们不需要处理或是不清楚如何处理的事件.

3、在Qt对象上安装事件过滤器.

安装事件过滤器有两个步骤: (假设要用A来监视过滤B的事件)

首先调用BinstallEventFilter( const QOject *obj ), A的指针作为参数这样所有发往B的事件都将先由AeventFilter()处理.

然后, A要重载QObject::eventFilter()函数eventFilter() 中书写对事件进行处理的代码.

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

一旦我们给qApp(每个程序中唯一的QApplication对象)装上过滤器,那么所有的事件在发往任何其他的过滤器时,都要先经过当前这个 eventFilter(). debug的时候,这个办法就非常有用也常常被用来处理失效了的widget的鼠标事件,通常这些事件会被QApplication::notify()丢掉. ( QApplication::notify() 是先调用qApp的过滤器再对事件进行分析以决定是否合并或丢弃)

5、继承QApplication,并重载notify()函数.

Qt是用QApplication::notify()函数来分发事件的.想要在任何事件过滤器查看任何事件之前先得到这些事件,重载这个函数是唯一的办法通常来说事件过滤器更好用一些因为不需要去继承QApplication而且可以给QApplication对象安装任意个数的事件。

十二、描述QT下多线程的两种使用方法, 以及注意事项 

1、第一种方法: 

(1)创建一个类从QThread类派生 

(2)在子线程类中重写 run 函数, 将处理操作写入该函数中 

(3)在主线程中创建子线程对象, 启动子线程, 调用start()函数 

2、第二种方法: 

(1)将业务处理抽象成一个业务类, 在该类中创建一个业务处理函数 

(2)在主线程中创建一QThread类对象 

(3)在主线程中创建一个业务类对象 

(4)将业务类对象移动到子线程中 

(5)在主线程中启动子线程 

(6)通过信号槽的方式, 执行业务类中的业务处理函数 

多线程使用注意事项: 

(1)业务对象, 构造的时候不能指定父对象 

(2)子线程中不能处理ui窗口(ui相关的类) 

(3)子线程中只能处理一些数据相关的操作, 不能涉及窗口

十三、线程同步的方法

1、互斥量(QMutex

 QMutex m_Mutex;  m_Mutex.lock(); m_Mutex.unlock();

2、互斥锁(QMutexLocker

  QMutexLocker mutexLocker(&m_Mutex);

 从声明处开始(在构造函数中加锁),出了作用域自动解锁(在析构函数中解锁)。

3、等待条件(QWaitCondition

QWaitCondtion m_WaitCondition;

m_WaitConditon.wait(&m_muxtex, time); 

m_WaitCondition.wakeAll();

4、 QReadWriteLock

(1)一个线程试图对一个加了读锁的互斥量进行上读锁,允许;

(2)一个线程试图对一个加了读锁的互斥量进行上写锁,阻塞;

(3)一个线程试图对一个加了写锁的互斥量进行上读锁,阻塞;、

(4)一个线程试图对一个加了写锁的互斥量进行上写锁,阻塞。

读写锁比较适用的情况是:需要多次对共享的数据进行读操作的阅读线程。

QReadWriterLock QMutex相似,除了它对 "read","write"访问进行区别对待。它使得多个读者可以共时访问数据。使用QReadWriteLock而不是QMutex,可以使得多线程程序更具有并发性。

5、信号量QSemaphore

但是还有些互斥量(资源)的数量并不止一个,比如一个电脑安装了2个打印机,我已经申请了一个,但是我不能霸占这两个,你来访问的时候如果发现还有空闲的仍然可以申请到的。于是这个互斥量可以分为两部分,已使用和未使用。

6、QReadLocker便利类和QWriteLocker便利类对QReadWriteLock进行加解锁

十四、多线程编程中,常见的锁:

1、 互斥锁(Mutex):用于保护临界区,同一时间只允许一个线程访问临界区。

2、 读写锁(Reader-Writer Lock):用于读多写少的场景,允许多个线程同时读取共享数据,但只允许一个线程写入共享数据。

3、 自旋锁(Spin Lock):使用忙等待的方式来实现锁,适用于锁的持有时间非常短暂的场景。

4. 条件变量(Condition Variable):用于线程间的通信,允许线程在特定条件下等待或唤醒。

5、 信号量(Semaphore):用于控制并发访问数量的锁,可以限制同时访问某个资源的线程数量。

6、屏障(Barrier):用于同步多个线程的执行,当所有线程都到达屏障时才能继续执行。

7、递归锁(Recursive Lock):允许同一个线程多次获取同一个锁,避免死锁的发生。

注意:windows里边还有一种是临界区

十五、死锁,以及死锁如何产生

死锁的产生有如下四个必要条件

1、资源是互斥的,同一时刻只能有一个进程占有该资源

2、资源的释放只能有该进程自己完成

3、线程在获取到需要资源之前,不会释放已有资源

4、存在这么一条循环等待的队列,线程T1,T2,T3, Tn

T1持有自己的资源请求T2的资源,.Tn持有自己的资源请求T1的资源

  • 2
    点赞
  • 91
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
选择Qt组件还是Qt源代码,应根据项目的具体需求进行评估和决策。 Qt组件是指Qt平台提供的一系列高度封装、易用的组件,可以有效地提升开发效率和代码质量。这些组件已经经过充分的测试和验证,具有稳定性和可靠性。选择Qt组件可以快速地构建应用程序,减少重复性的工作,提高开发效率。特别是对于一些常见的功能需求,例如图形界面、网络通信、数据库操作等,Qt组件提供了丰富的选项,可以满足各种开发需求。 Qt源代码则是指Qt平台的开源代码,具有高度灵活性和可定制性。选择Qt源代码可以在有特定需求的情况下,深入了解和定制Qt框架的内部实现,以满足项目的特殊要求。特别是在需要进行底层功能扩展、优化或者修复bug时,Qt源代码可以提供更直接的操作方式。同时,通过对源代码的研究和调试,也可以加深对Qt框架的理解和掌握。 综上所述,选择Qt组件还是Qt源代码应根据项目的需求来决策。如果项目对开发效率和稳定性要求较高,且需要的功能在Qt组件已经有完备的实现,可以优先选择Qt组件。如果项目对灵活性和定制性要求较高,或者需要做一些底层的功能扩展或者调优,可以选择Qt源代码进行开发。当然,根据具体情况,也可以在使用Qt组件的同时,辅以对Qt源代码的研究和定制来满足项目的特殊需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值