VS2019+QT6.24学习心得4

一、事件分发器/事件过滤器

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"));
在这里插入代码片
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值