一、Qt也有很多实用的库
- 线程库和线程池
- TCPSocket和TCPServer
- 打包一个应用程序
- QWebSocket
- QSerialPort
- QUdpSocket
- QCharts
二、Qt的多线程
- 操作界面交给main线程,其他耗时操作交给另一个线程实现,如果子线程想操作界面,只能通过信号和槽的方式传递给main线程实现
- 第一种线程的实现方法,继承QThread类,重写
run
方法,在主线程中创建QThread的子类对象,在外部调用start
方法相当于让run运行
- 第二种线程的实现方法,继承QObject类,实现一个公共的方法等价于
run
方法,在主线程中创建该对象,并创建一个QThread对象,使用QObjet的moveToThread方法将创建的对象移动到创建的子线程中,调用线程的start方法,此时线程启动了,但是你实现类的公共方法还没有启动
Qthread * sub = new QThread();
Work *work = new Work();
work->moveToThread(sub);
sub->start();
connect(btn1, &QPushButton::clicked, work, &Work::working);
- 移动到同一线程对象的多个子任务是顺序执行的
- 资源回收,方法一是创建QThread的时候指定父对象;方法二是构造函数中创建类对象,析构函数中删除类对象;或在mainwindow的destoryed信号关联的槽函数中删除类对象
t1->quit(); t1->wait(); t1->deleteLater();
(x的deleteLater方法等价于delete x)
三、Qt的线程池
- 线程池,包含任务队列(存储需要执行的任务)、工作线程(多个实例的线程)、管理线程(管理任务和线程)
- Qt的每个Application都有一个线程池对象,使用静态方法
QThreadPool::globalInstance()
可以获得线程池对象
- 线程池对象的setMaxThreadCount方法设置线程的最大数量
- 线程池对象的start方法添加一个QRunnable类型的对象的任务到线程池中
- 需要有一个类多重继承自QObject和QRunnable,并重写run方法,之后才可以用start方法添加到线程池中
- QRunnable类的一个属性setAutoDelete(true);设置任务完成后自动销毁
四、Qt的TCP通信类
TCP服务器的创建
1> QTcpServer * m_ser = new QTcpServer(this);
2> 调用QTcpServer的listen方法,监听任意的IP地址和指定的端口
3> 设计QTcpServer的newConnection信号对应的槽函数,该信号表示有一个新的连接建立
4> 使用QTcpServer的nextPendingConnection方法得到一个和客户端通信用的套接字QTcpSocket
5> QTcpSocket的readyRead信号触发,表示有数据到来,可以用readAll方法得到QByteArray数据
6> 调用write方法,实现往客户端写数据
7> QTcpSocket的disconnected信号触发,表示客户端断开连接,调用close方法和deleteLater方法注销掉QTcpSocket对象
TCp客户端的创建
1> QTcpSocket * m_tcp = new QTcpSocket(this);
2> 调用QTcpSocket的connectToHost的方法,连接到指定的ip和port
3> 触发connected信号,表示客户端和服务器连接成功
4> 触发readyRead信号,表示套接字有数据可以读取
5> 除非disconnectd信号,表示客户端和服务器断开连接
五、Qt程序的打包
- 使用windeployqt对exe进行打包,获得相应的库
- 使用Inno-setup工具对程序打包为一个setup的安装程序,该程序根据iss脚本打包
- 使用向导创建一个脚本或根据已有脚本修改
- 重要的指定目录、名称、exe文件位置、库文件位置等等均可以定制
六、QWebSocket
- 持久的全双工的双向的网络通信,基于TCP协议,用在多人在线的实时应用中
QWebSocketServer
构造函数中指定服务器名称、ws还是wss
listen监听,任意的IP和指定的port
newConnection信号到达,说明有新的连接对象,使用nextPendingConnection获取一个通信用的QWebSocket,关联textMessageReceived信号接收文本消息,同时有disconnected信号表示连接断开,此时释放QWebSocket资源
close方法关闭连接
QWebSocket
open方法指定URL连接
sendTextMessage发送文本信息
textMessageReceived信号接收文本信息
connected和disconnected信号表示连接建立和连接断开
close方法关闭服务器连接
七、QSerialPort
- 实现了串口类的封装
- 遍历寻找串口,使用QSerialPortInfo的availablePorts的静态方法得到一个可用的QSerialPortInfo的list,使用范围for循环+auto将portName拿出来,并使用QComBox显示
- 打开串口,实例化一个QSerialPort对象,设置名字、波特率、数据位、校验位、停止位、流控,之后调用QSerialPort的open方法打开串口
- 写串口,调用继承自QIODevice的write方法即可
- 当readyRead信号被发射时,代表串口有数据可以读了,使用readAll方法读出QByteArray类型数据
- 补充:实际使用过程中单击QComBox对象应该触发一次串口扫描操作,实现方法是重写QComboBox的mousePressEvent事件处理函数,在其中实现一个调用串口扫描函数的方法
八、QUdpSocket
- 单播和广播(广播是对于一个广播地址的单播)
1> 创建一个udpsocket对象
2> 使用bind方法绑定IP地址和端口,以及绑定模式,默认可以只设置port,表示监听这个端口的数据
3> readyRead信号表示有数据包到达,UDP是以包的形式收发的,在QT中是QNetworkDatagram,里边存储了数据、收发端的IP和port等等,使用while循环遍历直到hasPendingDatagrans返回false,对于每个包可以readDatagram或receiveDatagram接收,后者接收的是一个QNetworkDatagram,前者参数是后者的进一步解析,并且pendingDatgram可以获得排队包的大小
4> 使用writeDatagram可以往指定的IP和port上发包(UDP非连接,每次发包都需要指定ip和port),有两个重载函数,一个是QNetworkDatagram参数,另一个是数据+大小+ip+port的信息
5> 最后可以使用abort、close和deleteLater完成退出工作
2. 广播
1> 和单播不同之处在于,bind的时候指定mode为ShareAddress,bind完成之后可以通过joinMulticastGroup加入组播组,使用leaveMulticastGroup离开组播组
- 补充:abort和bind是互斥的,如果不需要在某一个端口上接收消息,只是发送数据包,也可以不进行bind,直接调用writeDatagram往指定IP和port上写
九、QChart
- 在UI界面中使用widget空间可以提升为QChartView
- 在头文件中添加QT_CHARTS_USE_NAMESPACE
- QChartView类为画布对象、QChart类为图表对象、QLineSeries类为折线类、QValueAxis类为坐标轴类
- 使用方法
1> 使用QChartView的setChart方法将QChart对象放到画布上
2> 构建一个QVector<QPointF>保存绘图所需要的数据
3> 使用QLineSeries的replace方法将数据保存到线对象上
4> 使用QChart的addSeries方法将线对象添加到QChart对象上
5> 如果想要重绘图,重新构造QVector<QPointF>保存数据,并使用QLineSeries的replace方法将数据保存到线对象上
- QChart对象其他方法
setTitle设置图表的标题
addAxis添加坐标轴并设置对齐方式
- QLineSeries对象其他方法
replace替换数据,最好是替换QPointF的vector对象
attachAxis绑定坐标轴,必须是与QChart相同的坐标轴,并且需要连续绑定x轴y轴
- QValueAxis类的方法setRange设置坐标轴的范围