Qt题目知多少-3

news2024/12/26 11:49:06

1.事件与信号的区别

        使用场合和时机不同 一般情况下,在“使用”窗口部件时,我们经常需要使用信号,并且会遵循信号与槽的机制;而在“实现”窗口部件时,我们就不得不考虑如何处理事件了。举个例子,当使用 QPushButton 时,我们对于它的 clicked()信号往往更为关注,而很少关心促成发射该信号的底层的鼠标或者键盘事件。但是,如果要实现一个类似于 QPushButton 的类,我们就需要编写一定的处理鼠标和键盘事件的代码,而且在必要的时候,仍然需要发射和接收 clicked()信号。

        使用的机制和原理不同 事件类似于 Windows 里的消息,它的发出者一般是窗口系统。相对信号和槽机制,它比较“底层”,它同时支持异步和同步的通信机制,一个事件产生时将被放到事件队列 里,然后我们就可以继续执行该事件 “后面”的代码。事件的机制是非阻塞的。信号和槽机制相对而言比较“高层”,它的发出者一般是对象。从本质上看,它类似于传统的回调机制。

2.信号与槽机制需要注意的问题

信号与槽机制是比较灵活的,但有些局限性我们必须了解,这样在实际的使用过程中才能够做到有的放矢,避免产生一些错误。下面就介绍一下这方面的情况。

1)信号与槽的效率是非常高的,但是同真正的回调函数比较起来,由于增加了灵活 性,因此在速度上还是有所损失,当然这种损失相对来说是比较小的,通过在一台 i586- 133 的机器上测试是 10 微秒(运行 Linux),可见这种机制所提供的简洁性、灵活性还是值得的。但如果我们要追求高效率的话,比如在实时系统中就要尽可能的少用这种机制。

2)信号与槽机制与普通函数的调用一样,如果使用不当的话,在程序执行时也有可能产生死循环。因此,在定义槽函数时一定要注意避免间接形成无限循环,即在槽中再次发射所接收到的同样信号。

3)宏定义不能用在 signal 和 slot 的参数中。

4)构造函数不能用在 signals 或者 slots 声明区域内。

5)函数指针不能作为信号或槽的参数。

6)信号与槽也不能携带模板类参数。

3.信号的注意点

1)所有的信号声明都是公有的,所以Qt规定不能在signals前面加public,private, protected。

2)必须直接或间接继承自QOBject类,并且开头私有声明包含Q_OBJECT。

3)在同一个线程中,当一个信号被emit发出时,会立即执行其槽函数,等槽函数执行完毕后,才会执行emit后面的代码,如果一个信号链接了多个槽,那么会等所有的槽函数执行完毕后才执行后面的代码,槽函数的执行顺序是按照它们链接时的顺序执行的。不同线程中(即跨线程时),槽函数的执行顺序是随机的。

4)在链接信号和槽时,可以设置链接方式为:在发出信号后,不需要等待槽函数执行完,而是直接执行后面的代码,是通过connect的第5个参数。

5) 信号与槽机制要求信号和槽的参数一致,所谓一致,是参数类型一致。如果不一致,允许的情况是,信号的参数可以比槽函数的参数多,即便如此,槽函数存在的那些参数的顺序也必须和信号的前面几个一致起来。这是因为,你可以在槽函数中选择忽略信号传来的数据(也就是槽函数的参数比信号的少),但是不能说信号根本没有这个数据,你就要在槽函数中使用(就是槽函数的参数比信号的多,这是不允许的)。

4.Qt 实现多线程

        QtConcurrent运行一个线程池,它是一个更高级别的API,不适合运行大量的阻塞操作:如果你做了很多阻塞操作,你很快就会耗尽池并让其他请求排队.在那种情况下,QThread(较低级别的构造)可能更适合于操作(每个代表一个线程).

5.描述Qt中的文件流(QTextStream)和数据流(QDataStream)的区别

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

        数据流(QDataStream):通过数据流可以操作各种数据类型,包括对象,存储到文件中数据为二进制。

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

6.Qt 如何保证多线程安全

1)互斥量(QMutex) QMutex m_Mutex; m_Mutex.lock(); m_Mutex.unlock();

2)互斥锁(QMutexLocker) QMutexLocker mutexLocker(&m_Mutex);

        从声明处开始(在构造函数中加锁),出了作用域自动解锁(在析构函数中解锁)。等待条件(QWaitCondition)QWaitCondtion m_WaitCondition; m_WaitConditon.wait(&m_muxtex, time); m_WaitCondition.wakeAll();

3)QReadWriteLock 是 Qt 框架中提供的一种同步机制,用于控制对共享资源的并发访问。它允许多个线程同时读取资源,但写入资源时则需要独占访问权。这在多线程编程中非常有用,尤其是在读多写少的场景下,可以提高程序的效率。

  QReadLocker 是 Qt 框架中提供的一种 RAII(Resource Acquisition Is Initialization)风格的锁定机制,用于在多线程环境中自动获取和释放读锁。它通常与 QReadWriteLock 一起使用,以确保对共享资源的安全读取访问。

      QWriteLocker 是 Qt 中用于自动管理写锁的 RAII(Resource Acquisition Is Initialization)风格的锁定机制。它与 QReadWriteLock 一起使用,确保在多线程环境中对共享资源进行独占访问。

4)QSemaphore 是 Qt 框架中提供的一种基本同步对象,用于控制对共享资源的访问。它维护了一个信号量,该信号量可以被增加或减少。通常,信号量的增加操作称为 release(),减少操作称为 acquire()。当信号量的值为正时,线程可以成功 acquire() 信号量;当值为零时,线程将等待直到信号量增加。

7.详解Qt中的内存管理机制

        所有继承自QOBJECT类的类,如果在new的时候指定了父亲,那么它在清理时在父亲被delete的时候delete的,所以如果一个程序中,所有的QOBJECT类都指定了父亲,那么他们是会一级级的在最上面的父亲清理时被清理,而不用自己清理;

        程序通常最上层会有一个根的QOBJECT,就是放在setCentralWidget()中的那个QOBJECT,这个QOBJECT在 new的时候不必指定它的父亲,因为这个语句将设定它的父亲为总的QAPPLICATION,当整个QAPPLICATION没有时它就自动清理,所以也无需清理。这里QT4和QT3有不同,QT3中用的是setmainwidget函数,但是这个函数不作为里面QOBJECT的父亲,所以QT3中这个顶层的QOBJECT要自行销毁)。

        这是有人可能会问那如果我自行delete掉这些Qt接管负责销毁的指针了会出现什么情况呢,如果时这样的话,正常情况下Qt的拥有这个对象的那个父亲会知道这件事情,它会直到它的儿子被你直接delete了,这样它会将这个儿子移出它的列表,并且重新构建显示内容,但是直接这样做是有风险的!

        当一个QOBJECT正在接受事件队列时如果中途被你delete掉了,就是出现问题了,所以Qt中建议家不要直接delete掉一个 QOBJECT,如果一定要这样做,要使用QOBJECT的deleteLater()函数,它会让所有事件都发送完一切处理好后马上清除这片内存,而且就算调用多次的deletelater也不会有问题。

        Qt不建议在一个QOBJECT 的父亲的范围之外持有对这个QOBJECT的指针,因为如果这样外面的指针很可能不会察觉这个QOBJECT被释放,会出现错误,如果一定要这样,就要记住你在哪这样做了,然后抓住那个被你违规使用的QOBJECT的destroyed()信号,当它没有时赶快置零你的外部指针。当然我认为这样做是极其麻烦也不符合高效率编程规范的,所以如果要这样在外部持有QOBJECT的指针,建议使用引用或者用智能指针,如Qt就提供了智能指针针对这些情况。

        Qt中的智能指针封装为QPointer类,所有QOBJECT的子类都可以用这个智能指针来包装,很多用法与普通指针一样,可以详见Qt assistant 通过调查这个Qt的内存管理功能,发现了很多东西,现在觉得虽然这个Qt弄的有点小复杂,但是使用起来还是很方便的,要说的是某些内存泄露的检测工具会认为Qt的程序因为这种方式存在内存泄露,发现时大可不必理会。

8.描述QT的TCP通讯流程

服务端:(QTcpServer)

①创建QTcpServer对象

②监听listen需要的参数是地址和端口号

③当有新的客户端连接成功回发送newConnect信号

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

⑤连接QTcpSocket对象的readyRead信号

⑥在readyRead信号的槽函数使用read接收数据

⑦调用write成员函数发送数据

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    tcpServer = new QTcpServer;
    tcpServer->listen(QHostAddress("192.168.0.111"),1234);
    connect(tcpServer,SIGNAL(newConnection()),this,SLOT(new_connect()));
}
 
Widget::~Widget()
{
    delete ui;
}
 
void Widget::new_connect()
{
    qDebug("--new connect--");
    QTcpSocket* tcpSocket = tcpServer->nextPendingConnection();
    connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(read_data()));
    socketArr.push_back(tcpSocket);
 
}
 
void Widget::read_data()
{
    for(int i=0; i<socketArr.size(); i++)
    {
        if(socketArr[i]->bytesAvailable())
        {
            char buf[256] = {};
            socketArr[i]->read(buf,sizeof(buf));
            qDebug("---read:%s---",buf);
        }
    }
}

客户端:(QTcpSocket)

①创建QTcpSocket对象

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

③调用成员函数connectToHost连接服务器,需要的参数是地址和端口号

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

⑤使用write发送数据,read接收数据

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    tcpSocket = new QTcpSocket;
    connect(tcpSocket,SIGNAL(connected()),this,SLOT(connect_success()));
    tcpSocket->connectToHost("172.20.10.3",1234);
}
Widget::~Widget()
{
    delete ui;
}
void Widget::on_send_clicked()
{
    std::string msg = ui->msg->text().toStdString();
    int ret = tcpSocket->write(msg.c_str(),msg.size()+1);
    qDebug("--send:%d--",ret);
} 
void Widget::connect_success()
{
    ui->send->setEnabled(true);
}

9.描述UDP 之 UdpSocket通讯

        UDP(User Datagram Protocol即用户数据报协议)是一个轻量级的,不可靠的,面向数据报的无连接协议。在网络质量令人十分不满意的环境下,UDP协议数据包丢失严重。由于UDP的特性:它不属于连接型协议,因而具有资源消耗小,处理速度快的优点,所以通常音频、视频和普通数据在传送时使用UDP较多,因为它们即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。所以QQ这种对保密要求并不太高的聊天程序就是使用的UDP协议。

在Qt中提供了QUdpSocket 类来进行UDP数据报(datagrams)的发送和接收。Socket简单地说,就是一个IP地址加一个port端口 。

流程:

①创建QUdpSocket套接字对象

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

③发送数据用writeDatagram,接收数据用 readDatagram 。

10.多线程使用方法

方法一:①创建一个类从QThread类派生②在子线程类中重写 run 函数, 将处理操作写入该函数中 ③在主线程中创建子线程对象, 启动子线程, 调用start()函数

方法二:①将业务处理抽象成一个业务类, 在该类中创建一个业务处理函数②在主线程中创建一QThread类对象 ③在主线程中创建一个业务类对象 ④将业务类对象移动到子线程中 ⑤在主线程中启动子线程 ⑥通过信号槽的方式, 执行业务类中的业务处理函数

多线程使用注意事项:

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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1991641.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

界面组件Kendo UI for Vue 2024 Q2亮点 - 发布一系列新组件

随着最新的2024年第二季度发布&#xff0c;Kendo UI for Vue为应用程序开发设定了标准&#xff0c;包括生成式AI集成、增强的设计系统功能和可访问的数据可视化。新的2024年第二季度版本为应用程序界面提供了人工智能(AI)提示&#xff0c;从设计到代码的生产力增强、可访问性改…

算法23:寻找旋转排序数组中的最小值

寻找旋转排序数组中的最小值. - 备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/find-minimum-in-rotated-sorted-array/ 这个题乍一看可以用二分查找&#xff0c;并且…

C#——使用S7netplus包实现西门子s7协议

使用S7netplus包实现西门子s7协议 S7netplus是一个用于与Siemens S7 PLC进行通信的C#库。它提供了一种简单的方式来读取和写入PLC中的数据。 安装 可以通过NuGet包管理器来安装。 S7netplus的使用 一、连接 // CpuType&#xff1a;PLC的CPU型号&#xff0c;咱用的这个设备…

write_sdc和write_script区别

文章目录 一、set_disable_clock_gating_check二、write_sdc和write_script区别1. write_sdc2. write_script 一、set_disable_clock_gating_check set_disable_clock_gating_check对指定的cell/pin/lib_cell/lib_pin设置是否进行clock gating的时序检查。 对于工具插入或者…

C语言——计算1-1/2+1/3-...+1/99-1/100+...相似题目集合

题目一&#xff1a; #include<stdio.h> #include<math.h>int main() {int n 1;float sum 0, term 1, sign 1;while (fabs(term) > 1e-4){term sign / n;sum term;sign -sign;n;}printf("sum%f", sum);return 0; } 题目二&#xff1a; #include…

服务器数据恢复—Raid故障导致存储中数据库数据丢失的数据恢复案例

服务器存储数据恢复环境&故障情况&#xff1a; 一台光纤存储中有一组由16块硬盘组成的raid。 该存储出现故障导致数据丢失。RAID中2块盘掉线&#xff0c;还有1块盘smart状态为“警告”。 服务器存储数据恢复过程&#xff1a; 1、通过该存储自带的存储管理软件将当前存储的完…

关于之前写的一篇“快速构建MES系统”引发的争议,后续来了~~

之前因写了一篇用低代码开发平台快速搭建MES系统&#xff0c;结果被大量的网友骂得体无完肤&#xff0c;不过&#xff0c;默默点赞、默默收藏、默默分享的用户还是大有人在。 在某些方面&#xff0c;或许在语言表达上不够精确&#xff0c;不够准确&#xff0c;这里也给各位看官…

免费微博批量取关工具

下载地址&#xff1a;https://pan.quark.cn/s/1d507dcfffe9 软件功能 批量删除微博批量取消关注批量移除粉丝批量取消收藏批量取消赞批量删除评论

<数据集>停车场空位识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;12416张 标注数量(xml文件个数)&#xff1a;12416 标注数量(txt文件个数)&#xff1a;12416 标注类别数&#xff1a;2 标注类别名称&#xff1a;[space-empty, space-occupied] 序号类别名称图片数框数1space-occ…

科技驱动健康,景联文科技提供高质量高血压数据采集

当前&#xff0c;穿戴手表市场呈现出快速发展趋势&#xff0c;已成为可穿戴设备领域的一个重要组成部分。市场上智能手表的厂商包括小米、华为、苹果、步步高、vivo、努比亚、三六零、科大讯飞、等。 高血压数据采集可为高血压的预防提供支持&#xff0c;持续监测可以帮助用户及…

云原生课程-k8s基础系列-k8s实战之pod详解

pod是可以在k8s中创建和管理的&#xff0c;最小的可部署的计算单元&#xff0c;pod(就像在豌豆荚中&#xff09;是一组&#xff08;一个或多个&#xff09;容器&#xff1b;这些容器共享存储&#xff0c;网络&#xff0c;以及怎样运行这些容器的声明。 创建pod kubectl run my…

【VScode编辑器】VScode基本使用全面讲解

1&#xff0c;VScode是什么&#xff1f; Visual Studio Code 简称 VS Code&#xff0c;是一款跨平台的、免费且开源的现代轻量级代码编辑器。它功能强大&#xff0c;提供了丰富的功能和扩展性&#xff0c;几乎支持主流开发的特性。 VSCode里面有对应的插件安装功能&#xff0c;…

基于51单片机的智能车库系统proteus仿真

地址&#xff1a; https://pan.baidu.com/s/1Pw9pbytbYqCoecGxSFNqpg 提取码&#xff1a;1234 仿真图&#xff1a; 芯片/模块的特点&#xff1a; AT89C52/AT89C51简介&#xff1a; AT89C52/AT89C51是一款经典的8位单片机&#xff0c;是意法半导体&#xff08;STMicroelectro…

【网络爬虫篇】逆向实战—某东:滑块验证码(逆向登录)2024.8.7最新发布,包干货,包详细

【网络爬虫篇】更多优秀文章借鉴&#xff1a; 1. 使用Selenium实现黑马头条滑块自动登录 2. 使用多线程采集爬取豆瓣top250电影榜 3. 使用Scrapy爬取去哪儿网游记数据 4. 数据采集技术综合项目实战1&#xff1a;国家水稻网数据采集与分析 5. 数据采集技术综合项目实战2&#x…

电子画册设计源码系统:轻松制作各行各业在线画册展示 带完整的安装代码包以及搭建教程

在信息化时代&#xff0c;传统的纸质画册已经无法满足现代人的阅读需求。而电子画册具有信息更新迅速、展示方式多样、交互性强等优点&#xff0c;能够更好地满足用户对于信息的获取和展示需求。同时&#xff0c;随着移动互联网的普及&#xff0c;用户对于在线浏览和分享的需求…

GEE:设置自定义风格底图

作者&#xff1a;CSDN _养乐多_ 本文将介绍如何在 Google Earth Engine &#xff08;GEE&#xff09;平台上&#xff0c;设置底图风格。结果如下图所示&#xff0c; 文章目录 一、代码二、完整代码链接 一、代码 以下代码将GEE的底图根据自己的需求设置风格。 var land { …

为啥https比http慢

Https有ssl的握手 HTTP没有 HTTPS TCP 和HTTP 的TCP 时间差不是很大 HTTPS请求中,ssl所占的时间比例是请求时间总和93.37%, HTTPS请求中,ssl的请求会是tcp请求的14倍,而HTTP中没有这个问题 建议:对安全要求不是很高的,不要使用https请求 图例

【漏洞复现】PowerPMS——APPGetUser——SQL注入

声明&#xff1a;本文档或演示材料仅供教育和教学目的使用&#xff0c;任何个人或组织使用本文档中的信息进行非法活动&#xff0c;均与本文档的作者或发布者无关。 文章目录 漏洞描述漏洞复现测试工具 漏洞描述 PowerPMS 是一个集成的企业管理系统,涵盖了财务管理、销售管理、…

常见八股面试题:Dubbo 和 Spring Cloud Gateway 有什么区别?

大家好&#xff0c;我是鸭鸭&#xff01; 此答案节选自鸭鸭最近弄的面试刷题神器面试鸭&#xff0c;更多大厂常问面试题&#xff0c;可以点击进行阅读哈&#xff01; 目前这个面试刷题神器刚出&#xff0c;有网页和小程序双端可以阅读&#xff01; 回归面试题&#xff01; …

Android中的Binder

binder是Android平台的一种跨进程通信&#xff08;IPC&#xff09;机制&#xff0c;从应用层角度来说&#xff0c;binder是客户端和服务端进行通信的媒介。 ipc原理 ipc通信指的是两个进程之间交换数据&#xff0c;如图中的client进程和server进程。 Android为每个进程提供了…