Qt笔记

本文最后更新于:2022年5月27日 晚上

Qt 信号与槽、内存管理等基本机制;Qt 网络编程; Qt 元对象系统

Qt信号与槽

作用

实现对象和对象之间的通信,当一个对象发生改变会发送一个信号通知另一个对象执行一个函数,这个函数称之为槽

信号

信号的声明:

1
2
3
signals:
void signaleA();
...

信号只需要声明,不需要定义

信号的发送:

1
emit signalA();

槽的声明:只在头文件进行,关键字:slots, 声明槽函数后必须实现 在.cpp文件

1
2
private slots:
void slotA();//实现和普通函数没有区别

实现:在对应源文件中,必须实现

调用:

信号调用:与槽函数关联的信号被发送时,槽函数被调用

普通调用:通过函数名或函数指针调用

信号与槽的连接

连接方式:

  • 手动连接:
1
>connect(Obj_sender, SIGNAL(my_signal()), Obj_receiver, SLOT(), ConnectType);

最后一个参数,可以省略,默认为:自动方式

  • 自动连接:通过命名连接
1
2
>void MyClass::on_obj_signal(); //槽函数
>on_发送信号的对象名_发送的信号()

连接规则:

  • 信号的参数可以比槽函数多,反之不可以
  • 信号与槽,可以一对一,一对多,多对一
  • 信号与信号也可以连接:发起方信号参数要多于接收方,连接成功后,触发接收方信号不会触发发起方信号
  • 连接可以被删除:disconnect
  • 同一个连接可以绑定多次,触发以此信号会执行多个槽函数,执行顺序按照绑定顺序

连接类型

  • 直连方式(DirectConnection):槽函数在信号发送时候,直接被调用,(建议)槽函数运行于信号发送者的线程
  • 排队方式(QueuedConnection):(建议)槽函数运行于信号接收者所在线程。发送信号之后,槽函数不会立刻被调用,等到接收者当前函数执行完,进入事件循环,槽函数被调用
  • 自动方式(AutoConnection):默认方式,如果接收者和发送者在同一线程,自动调用直连方式,在不同线程,自动调用排队方式
  • 阻塞排队方式(BlockingQueuedConnection):槽函数调用时机和排队方式一致,不过发送完信号后,发送者所在线程会阻塞,直到槽函数运行完。发送者和接收者绝不能在一个线程,否则死锁
  • 唯一连接方式(UniqueConnection):和前面几个结合使用,这个flag可以通过按位或(|),和以上四个结合使用。当设置这个flag时候,某个信号和槽已经连接时,再重连就失败,避免重复连接。

Qt元对象系统

功能

Qt元对象系统提供对象间的通信机制:信号与槽,以及运行时类型信息和动态属性系统的支持,是对标准C++ 的拓展,使Qt更好的实现GUI图形用户界面编程

组成

  • QObject

  • 类声明私有段中Q_OBJECT宏

  • 元对象编译器(moc)

    moc 工作流程:

    • 确认类继承自QObject
    • 寻找Q_OBJECT宏
    • 类的一般信息
    • Qt关键字(slots、signals)

    moc从头文件获取数据,编译成moc文件,再和.cpp编译的文件共同生成中间代码文件

Qt的几种机制

  • 内存管理机制

    Qt的内存管理机制,让Qt定义的类,继承一个父类,父类作为管理者管理子类,当父类销毁,子类跟着销毁

    两个类继承 QObject,且有Q_OBJECT

  • 信号与槽机制

    实现对象与对象间的通信

  • 事件机制

Qt实现Http通信

Http协议数据格式

请求数据方式

  • GET 是http协议的默认请求方法,日常使用GET方法来提交表单数据。

    但GET方法的表单数据只经过简单的编码,同时作为URL的一部分向Web服务器发送,存在安全隐患,此外提交的数据量不能太大

  • POST 是GET方法的代替,克服了GET方法不安全和数据量小的缺点。

    POST方法,将数据作为标准数据发送给Web服务器,放在附属体中,更加安全且可以调教大批量数据

Qt实现Http通信常用类

  • QNetworkRequest — 网络连接请求类

    1
    QNetworkRequest netWorkRequest(QUrl("https://l-by.cn/yinyue/api.php")); //URL地址
    1
    netWorkRequest.setRawHeader("Content-type","application/x-www-form-urlencoded; charset=UTF-8"); //标头
  • QNetworkAccessManager — 网络访问管理器

    1
    2
    QString body = QString("types=search&count=100&source=netease&pages=1&name=%1").arg(searchData);//附属体
    QNetworkReply *networkReply = netWorkAccessMangager->post(netWorkRequest,body.toUtf8()); //让网络管理类通过POST方式发送请求,返回一个网络回复类指针
  • QNetworkReply — 网络回复类

    1
    2
    3
    networkReply->readAll(); //读取所有数据返回一个QByteArray
    readLine(qint64 maxSize = 0);//按行读取
    read(char *data, qint64 maxSize);//读取最大字节为maxSize,存到data中,返回读取到的字节数
    1
    2
    3
    4
    signals:
    void readRead(); //网络中有数据发送给你触发该信号
    void finished(); //所有数据接收完成触发该信号
    void error(QNetworkReply::NetworkError code); //网络连接出错触发该信号

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!