一、事件分发器/事件过滤器
1.1返回值为bool类型
event函数为虚函数,可以重写
(1)virtual bool event(QEvent *e); --事件分发器 1.过滤事件 2.修改事件(不推荐)
(2)virtual bool eventFilter(); --事件进入窗口之前过滤事件
(1)给指定窗口安装事件过滤器
(2)在事件eventFilter 事件处理事件 e->type() == QEvent::MouseMove
return ture
1.2返回值
//true--事件被处理过,不继续向下分发
//flase--事件未被处理,继续向下分发
//大概的处理步骤
//switch (e->type())
//{
//case QEvent::MouseMove:
// mouseMoveEvent(e);
//break;
//case QEvent::Timer:
// timerEvent(e);
// break;
1.3过滤定时器事件
//过滤定时器事件
if(e->type() == QEvent::Timer)
{
return false;//不会再向下处理
}
else if (e->type() == QEvent::MouseMove)
{
//操作。。。。
return true;
}
//让父类执行默认的操作
return QLabel::event(e);
二、事件过滤器
写到其他文件中,让其他窗口代为处理
//给MyLabel 安装事件过滤器
//参数 谁来过滤Label事件
ui->label->installEventFilter(this);
ui->label_2->installEventFilter(this);
//判断对象,可能多个组件安装事件过滤器,有些需要事件过滤,有些不需要
//QLabel-->QWidget-->QObject
if (obj == ui->label)
{
//过滤事件
if (e->type() == QEvent::MouseMove)
{
return false;
}
}
//执行默认处理
return QWidget::eventFilter(obj, e);
三、文件操作
Qfile f(name);
1.f.setFileName(stringpathname);
2.打开文件open(QFile::ReadOnly);
3.读文件/写文件
char buf[111];
read(char *buf,int size)
QByteArry arry = readAll(); --atEnd == true(末尾)
while(file.atEnd() == false);
QbyteArry line =readLine();
int size = write(char8 buf,int size)
4.close(0
5.默认格式utf8
3.1简单窗口操作
打开文件夹窗口,选择打开文件,打开(只读、读写),默认格式utf8
connect(ui->selectFile, &QPushButton::clicked, this, [=]
{
QString FileName = QFileDialog::getOpenFileName(this, "open file", "d:\\");
if (FileName.isEmpty() == true)
{
QMessageBox::warning(this, "warning", "select file faild!");
return;
}
ui->filePath->setText(FileName);
//创建文件对象
//QFile默认读取 utf8格式
QFile file(FileName);
//QTextCodec *codec = QTextCodec
//指定打开方式
bool isOK = file.open(QFile::ReadOnly);
if (isOK == false)
{
QMessageBox::critical(this, "ERROR", "file open faild!");
return;
}
//读文件
//file.read(1); 但是不经常用,
QByteArray array;
while (false == file.atEnd())//取反,指针指到末尾
{
array += file.readLine();// readAll全部读取 file.readLine()读取一行
}
//显示到文本框
ui->lineEdit->setText(array);
//ui->lineEdit->append
char buf[128] = { "hi,word" };
file.write(QString("hello,word").toUtf8());
file.write(buf, strlen(buf));
//关闭文件
file.close();
});
上述代码利用槽函数、QFileDialog::getOpenFileName函数组件,在创建文件对象之后,进行一些列操作。
3.2 文本流 数据流
QFile f;
QTextStream stream(&f); //指定IO设备
//或者
QTextStream stream;
stream.setDeivce(&f);//指定IO设备
//读文件与文件操作相同
//写文件时,可以用操作符写入
stream<<"aaaf"//写入设备
stream>>str;//读到内存,从设备里边取或读数据放入stream
QFile f;
QDataStream ds(&f);
//或者
ds.setDevice(&f);//把f再次设置给IO设备
//写数据 注意写数据类型与读数据类型格式要统一
char *str = "string";
ds<<QString("ssss")<<1234<<image //写文件 转换成QString类型才能写入
ds>>string>>number>>QImage //读文件
//读文件 错误示例 数据格式不同
QString str;
int number;
ds >> str >> number;
//操作内存块
QPixmap pix
QByteArry arry; //创造内存地址
QDataStream sa(&arry,QIODevice::ReadWrite);//对内存地址进行操作,并规定权限
ds << pix;
sa << image;
//操作的数据类型:基础数据类型:int,float,string
include<QTextStream>
//QImage QPoint QRect 1,不依赖平台
include<QDataStream>
==文本流==
connect(ui->selectFile, &QPushButton::clicked, this, [=]
{
QString FileName = QFileDialog::getOpenFileName(this, "open file", "d:\\");
if (FileName.isEmpty() == true)
{
QMessageBox::warning(this, "warning", "select file faild!");
return;
}
ui->filePath->setText(FileName);
//创建文件对象
//QFile默认读取 utf8格式
QFile file(FileName);
//QTextCodec *codec = QTextCodec
//指定打开方式
bool isOK = file.open(QFile::ReadOnly);
if (isOK == false)
{
QMessageBox::critical(this, "ERROR", "file open faild!");
return;
}
//创建流对象
QTextStream stream(&file);//设置IO设备给流对象,文件地址作为IO设备传给stream ,默认按照本地编码格式读取
//QT5 setCoderC可以文件转码,可以QT6兼容QT5
//读文件
//file.read(1); 但是不经常用,
QString array;
//stream.readAll(); QString类型
while (false == stream.atEnd())//取反,指针指到末尾
{
array += stream.readLine();// readAll全部读取 file.readLine()读取一行
}
//显示到文本框
ui->lineEdit->setText(array);
//ui->lineEdit->append
char buf[128] = { "hi,word" };
file.write(QString("hello,word").toUtf8());
file.write(buf, strlen(buf));
//关闭文件
file.close();
});
==数据流使用QTextStream==
QFile f("aaa1.txt");
f.open(QFile::WriteOnly);
QTextStream txt(&f);
//写文件
txt<<QString("hello,world!")<<123456;
f.close();
QString buf1;
f.open(QFile::ReadOnly);
txt.setDevice(&f);
txt >> buf1;//读文件
qDebug()<<buf1;
==数据流使用QDataStream==
QFile f("aaa1.txt");
f.open(QFile::WriteOnly);
QDataStream ds(&f); //可以IO设备和内存进行操作
//写文件
ds << QString("hello,world!") << 123456; //不能读出123456,读取时候不同类型相对应
f.close();
QString buf1;
int number;
f.open(QFile::ReadOnly);
ds.setDevice(&f);//把f再次设置给IO设备
ds >> buf1>>number;//不能读出123456, 则必须需要一个int类型数据帮助读取,因为123456是整型,类型数据对齐
qDebug() << buf1<<number;
QImage image("");
QByteArray aaaa; //申请内存
QDataStream ss(&aaaa, QIODevice::ReadWrite); //对ss传地址,可以进行写入操作, 操作方式QIODevice
ss << image;//image图片数据写入ss中,几乎所有数据内存项都可以存到内存中
四、QFileInfo类提供了对文件的各种属性和方法的访问。
// 创建一个QFileInfo对象,该对象表示位于"E:\\Image\\face.png"的文件
QFileInfo info("E:\\Image\\face.png");
// 使用qDebug()函数输出文件的大小
qDebug() << "file.size:" << info.size();
// 使用qDebug()函数输出文件的路径
qDebug() << "file.path:" << info.fileName();
qDebug() << "modifu.date" << info.lastModified().toString("yyyy/MM/dd hh:mm:ss");// 获取文件的最后修改时间,并将其转换为字符串形式,格式为 "yyyy/MM/dd hh:mm:ss"
五、tcp通信
服务器端:需要两个类型套接字,属于network模块
1.listen: QTcpServer -- 不是IO设备,父类QObject, 只需要监听,不需要发送和接收数据,所以不是QIODevice子类
2.通信:QTcpSocket -- IO设备 父类QIODevice *conn
1>. 监听:server.listen(Any,port);
2>. 若客户端有链接,服务器端收到一个信号
newConnection();写一个槽函数
1.接受请求 -- 拿到client端的套接字对象的地址
conn = server.nextPendingConnection(); //指针被初始化(原本指针是野指针,有链接请求被初始化,指向有效存储空间)
3>. write --
4>. read() -- readyRead(知道有信号来)
客户端: QTcpSocket cl;(套接字类)
1. cl.connectToHost(IP,port);
QT中的TCP通信流程如下:
1. 创建QTcpServer对象。
2. 启动服务器(监听)调用成员方法listen(QHostAddress::Any,端口号)。
3. 当有客户端链接时候会发送newConnection()信号,我们通过绑定槽函数sendMsg()以实现发送消息的功能。
4. 当收到客户端发来的消息时,会发出readyRead()信号,我们通过绑定槽函数readMsg()以实现读取消息的功能。
5. 当客户端断开连接时,会发出disconnected()信号,我们可以通过调用close()方法来关闭套接字。
以上是一个简单的TCP服务器示例代码 。
所以需要服务端和通信端
服务端
//ui init
ui->sIP->setText("10.24.162.156");
ui->sPort->setText("9999");
//实例化 init
server = new QTcpServer(this);
//监听
server->listen(QHostAddress("10.24.162.156"),ui->sPort->text().toInt());
//新的链接
connect(server, &QTcpServer::newConnection, this, [=]()
{
//接受客户端的套接字对象accept
//sock_addr 结构体 == 类 QTcpSocket
conn = server->nextPendingConnection();
//发送数据
conn->write("小弟,你好,我是你的二大爷!!!"); //char*类型可以当作QBetyArry来用,Qt内部会做一个隐式转换,转为QBetyArry
//保证conn是一个有效对象 所以需要conn写到conn初始化内,写道该函数外部会因conn未初始化报错
connect(conn, &QTcpSocket::readyRead, this, [=]()
{
//接收数据
QByteArray array = conn->readAll();
ui->record->append(array);
});
});
//发送
connect(ui->send, &QPushButton::clicked, this, [=]()
{
//发送数据
//QTextEdit
conn->write(ui->msg->toPlainText().toUtf8());
ui->record->append("Me Say: " + ui->msg->toPlainText());
//clear
ui->msg->clear();
});
客户端
ui->sIP->setText("10.24.162.156");
ui->sPort->setText("9999");
//init
client = new QTcpSocket(this);
//链接服务器
client->connectToHost(QHostAddress(ui->sIP->text()),ui->sPort->text().toInt());
//接收数据
connect(client, &QTcpSocket::readyRead, this, [=]()
{
QByteArray array = client->readAll();
ui->record->append(array);
});
//
connect(ui->send, &QPushButton::clicked, this, [=]()
{
client->write(ui->msg->toPlainText().toUtf8());
ui->record->append("ME Say:" + ui->msg->toPlainText());
});
六、UDP通信
udp类: QUdpSocket -- IO设备
1.发数据: s.writedatagram(data,对方的IP,对方的port)
2.readyRead();
int size = s,pendingDatagramSize(); //即将读取到的数据报文的数据大小
QByteArray arry(size,0);//构造大小为size个字节,每个字节初始化为0
s.readDatagram(buf.data(),size);//buf缓冲区,缓冲区大小, 转换数据类型QByteArray->char*
3.要接受数据:绑定一个端口号(本地)
1.通信流程图
UDP传输效率较高但容易丢包,TCP传输效率较低但是不容易丢包,而且安全性、文档性较好。
七、广播与组播
7.1广播
广播地址:255.255.255.255
主要是QHostAddress::Broadcast函数,//The IPv4 broadcast address. Equivalent to QHostAddress("255.255.255.255").
7.2组播
组播地址:地址号段较多
接受组播消息:加入到组播地址:joinMuticastGroup
服务端
udp1->bind(QHostAddress::AnyIPv4,ui->SPort->text().toInt()); //bind重载函数
udp1->writeDatagram(ui->msg->toPlainText().toUtf8(), QHostAddress("224.0.0.10"), ui->CPort->text().toInt());
QHostAddress("224.0.0.10")//组播端口
客户端
//如果想要接收数据
udp2->bind(QHostAddress::AnyIPv4,ui->CPort->text().toInt());
//加入到组播的组中
udp2->joinMulticastGroup(QHostAddress("224.0.0.10"));
在这里插入代码片