TCP/IP通信(即SOCKET通信)是通过网线将服务器Server端和客户机Client端进行连接,在遵循ISO/OSI模型的四层层级构架的基础上通过TCP/IP协议建立的通讯。控制器可以设置为服务器端或客户端。
关于TCP/IP协议可详看:TCP/IP协议详解 - 知乎 (zhihu.com)
总的来说,TCP/IP通讯有两个部分:
客户端和服务器
QTcpServer(监听套接字)和QTcpSocket(通讯套接字)
监听套接字,顾名思义,监听关于各种通讯的状态,一旦进行通讯,监听套接字会启动通讯套接字,进行通讯
客户端使用connectToHost函数主动连接服务器后,服务器会触发newConnectio这个槽函数,并进行取出QTcpServer(监听套接字),将相关内容取出并赋给QTcpSocket(通讯套接字)。客户端向服务器发送数据,触发readyRead(),进行处理,彼此传递时,原理都是这样的。
对双方来说都起作用的部分:
一旦建立连接,就会触发connected,服务器特殊一点,触发的是newCon ...
打包整体思路:
将编译后的exe可执行文件及其各种依赖dll、lib、图标、配置文件等先打包放到一个目录中
对其进行打包发布(两种方式):
利用VS的插件Microsoft Visual Studio Installer Projects安装程序打包插件进行打包
利用Enigma Virtual Box(单文件封装工具) 进行打包
一,将编译后的exe可执行文件及其各种依赖dll、lib、图标、配置文件等先打包放到一个目录中(1)dumpbin指令查看可执行文件的dll依赖包
在VS开发人员命令提示符(vs界面->工具->命令行->开发者命令提示)中执行dumpbin /dependents 程序路径 :dumpbin/dependents C:\Users\WFD\Desktop\GCtest\Debug\GCtest
(2)windeployqt.exe指令自动将qt依赖包复制过来
1️⃣先打开 Qt 的命令行(用的32位)
2️⃣使用“cd/d 路径” 命令进入到包含.exe 文件的文件夹。
3️⃣ Qt 命令行执行 ...
个人认为,事件机制是Qt最难以理解且最为精妙的一部分。事件主要分为两种:
在与用户交互时发生。比如按下鼠标(mousePressEvent),敲击键盘(keyPressEvent)等。
系统自动发生,比如计时器事件(timerEvent)等。
在发生事件时(比如说上面说的按下鼠标),就会产生一个QEvent对象(这里是QMouseEvent,为QEvent的子类),这个QEvent对象会传给当前组件的event函数。如果当前组件没有安装事件过滤器(这个后面会提到),则会被event函数发放到相应的xxxEvent函数中(这里是mousePressEvent函数)。
需要区分的是:事件与信号并不相同。
比如:鼠标单击按钮,鼠标事件(QMouseEvent),而按钮本身发射clicked()信号。一般而言我们只需要关注单击信号,不用考虑鼠标事件。但是当我们要对该按钮做额外操作,不想通过信号处理,此时事件就是一个很好的选择。关闭事件(QCloseEvent)是一个常用的事件。
一,事件Qt 中所有事件类都继承于 QEvent。在事件对象创建完毕后,Qt 将这个事件对象传递给 QObje ...
Qt中有两种方法来使用定时器,一种是定时器事件,另一种是使用信号和槽。
常使用信号和槽(代码看起来比较整洁)但是当使用多个定时器的时候最好用定时器事件来处理。
定时器方式一:定时器事件需要: #include
方式:
利用对void timerEvent(QTimerEvent* e)事件的重写。
启动定时器 int QObject::startTimer ( int interval ) ;
开启一个定时器,返回值为int类型。他的参数interval是毫秒级别。当开启成功后会返回这个定时器的ID, 并且每隔interval 时间后会进入timerEvent 函数。直到定时器被杀死(killTimer)
timerEvent的返回值是定时器的唯一标识。可以和e->timerId比较
void killTimer(int id); //停止 ID 为 id 的计时器,ID 由 startTimer()函数返回
实例:在两个label中自动计数,一个间隔为1秒,一个为2秒。
在头文件中先声明void timerEvent(QTimerEvent* ...
一, 最简单的多线程QtConcurrent::run()
其函数原型如下:
12QFuture<T> QtConcurrent::run(Function function, ...)QFuture<T> QtConcurrent::run(QThreadPool *pool, Function function, ...)
参数function需要外部函数:(或者lambda函数),后面也可跟外部函数的参数。
1extern void func(QString str);
QtConcurrent :: run()也接受指向成员函数的指针。第一个参数必须是一个const引用或一个指向该类实例的指针。const成员函数一般传递 常量引用 (const reference),而非常量成员函数一般传递 指针 (pointer)
在VS环境中需要引用: #include”QtConcurrent/qtconcurrentrun.h”
简单的说,QtConcurrent::run()函数会在一个单独的线程中执行,并且该线程取自全局QThreadP ...
一、知识回顾1,为什么需要多线程?
从计算机底层来说: 线程可以比作是轻量级的进程,是程序执行的最小单位,线程间的切换和调度的成本远远小于进程。另外,多核 CPU 时代意味着多个线程可以同时运行,这减少了线程上下文切换的开销。
从当代互联网发展趋势来说: 现在的系统动不动就要求百万级甚至千万级的并发量,而多线程并发编程正是开发高并发系统的基础,利用好多线程机制可以大大提高系统整体的并发能力以及性能。
再深入到计算机底层来探讨:
单核时代:在单核时代多线程主要是为了提高 CPU 和 IO 设备的综合利用率。举个例子:当只有一个线程的时候会导致 CPU 计算时,IO 设备空闲;进行 IO 操作时,CPU 空闲。我们可以简单地说这两者的利用率目前都是 50%左右。但是当有两个线程的时候就不一样了,当一个线程执行 CPU 计算时,另外一个线程可以进行 IO 操作,这样两个的利用率就可以在理想情况下达到 100%了。
多核时代: 多核时代多线程主要是为了提高 CPU 利用率。举个例子:假如我们要计算一个复杂的任务,我们只用一个线程的话,CPU 只会一个 CPU 核心被利用到,而创建多个 ...
Qt 提供了两种读写纯文本文件的基本方法:
用 QFile 类的 IODevice 读写功能直接进行读写
利用 QFile 和 QTextStream 结合起来,用流(Stream)的方法进行文件读写。
一、文件读操作(1)使用QFile类
Qt封装了QFile类,方便我们对文件进行操作,可以按照如下的步骤进行:
使用QFile加载文件对象
打开文件 file.open(打开方式)
操作文件
关闭文件 file.close()
实例:点击读写文件按钮,读取文件内容到textEdit中
1️⃣设置 ui 界面
2️⃣在widget.cpp中编辑代码(QFileDialog类是打开文件)
1234567891011121314151617//点击选取文件按钮,弹出文件对话框 connect(ui->pushButton,&QPushButton::clicked,[=](){ QString path = QFileDialog::getOpenFileName(this,"打开文件","C:/Users/WFD/Deskto ...
一、信号和槽机制分析 信号(Signal)就是在特定情况下被发射的事件,例如PushButton 最常见的信号就是鼠标单击时发射的 clicked() 信号,一个 ComboBox 最常见的信号是选择的列表项变化时发射的 CurrentIndexChanged() 信号。
GUI 程序设计的主要内容就是对界面上各组件的信号的响应,只需要知道什么情况下发射哪些信号,合理地去响应和处理这些信号就可以了。
槽(Slot)就是对信号响应的函数。槽就是一个函数,与一般的C++函数是一样的,可以定义在类的任何部分(public、private 或 protected),可以具有任何参数,也可以被直接调用。槽函数与一般的函数不同的是:槽函数可以与一个信号关联,当信号被发射时,关联的槽函数被自动执行。
信号与槽关联是用 QObject::connect() 函数实现的,其基本格式是:
12QObject::connect(sender, SIGNAL(signal()), receiver, SLOT(slot()));connect(发出信号的对象,发出的信号,接收信号的对象,接收到信 ...
一、QT基本框架创建一个项目,先看下main.cpp这个文件
注意:
每个Qt程序有且只能有一个QApplication对象,没有会报错。
Qt里面的头文件和类名是一致的,知道头文件就知道类名,反之亦然
Qt头文件是没有.h的,基本都是以大写的Q开头
根据以上的分析,我们可以得出Qt的程序框架代码:
123456789#include <QApplication> int main(int argc, char *argv[]){ QApplication a(argc, argv); /* 在这里写你的代码 */ return a.exec(); }
widget.h和widget.cpp分析
打开头文件里面的widget.h,和sources里面的widget.app,可以看到以下代码:
最上面的MyfirstQt.pro,是管理项目的文件,用来存储项目设置。
后缀为“.pro”的文件是项目的管理文件,文件名就是项目的名称,如本项目中的 MyfirstQt.pr ...
多模态学习(Multimodal Learning)是一种通过整合多种数据模态(如文本、图像、音频、视频等)来提升模型对复杂信息的理解能力的技术。其核心目标是利用不同模态的互补性与冗余性,突破单一模态的信息局限,模拟人类多感官协同认知的能力。
多模态融合和跨模态对齐是多模态学习的两个核心方面。多模态融合通过整合不同模态的数据来提高模型的感知和理解能力;而跨模态对齐则确保不同模态数据之间的准确对应,为融合提供可靠的基础。
什么是多模态融合?模态融合能够充分利用各模态之间的互补优势,将来自不同模态的信息整合成一个稳定且全面的多模态表征。
表征学习通过从原始数据中自动提取各模态有效特征,生成稳定全面的多模态表征。
表征学习(Representation Learning) ≈ 向量化(Embedding)
从数据处理的层次角度来划分,多模态融合可分为数据级融合、特征级融合和目标级融合。
一、数据级融合(Data-Level Fusion):数据级融合是在预处理阶段将不同模态的原始数据直接合并,适用于高度相关和互补的数据场景。
二、特征级融合(Feature-Level Fusion):特 ...