为什么要是用多线程?

多线程的使用主要是为了处理比较耗时的过程。多线程的实现可以通过两种方式实现

分别是:1.继承QThread实现多线程2.继承QObject实现多线程(由于继承QObject的多线程实现方法更加灵活,Qt官方推荐使用该方法实现多线程)。这里将采用第二种方式实现多线程

多线程实现过程

1.创建一个继承于QObject的自定义线程类,用来处理比较耗时的功能。

相关函数:

void setFlag(bool flag = true); //用于设置线程是否启动

void ConnectServer();//用于连接到服务器

槽函数:注意:槽函数应该用“private slots:”来修饰

void dowork();//线程处理函数

void ConnectedSuccess();//用来响应QTcpSocket的conneted()信号

void readData();//用来响应QTcpSocket的readyRead()信号

信号函数:注意:信号函数应该用 “signals:”来修饰

void signal_connectsuccess(QString)//用来向主线程发送链接成功信息

void signal_back(QString)//用来向主线程发送从服务器获取的数据

2.在主线程中创建一个子线程

QThread *mThread = new QThread(this);

3.创建一个自定义线程对象

TcpSocketThread *mTcpSocketThread = new TcpSocketThread ();

注意:这里创建的对象不能指定父对象,因为不能移动已经具有父类的对象,mThread可以看做是mTcpSocketThread 的父类

4.将子线程类对象移动到子线程容器中

mTcpSocketThread .moveToThread(mThread);

5.连接主线程与子线程之间的信号和槽函数(这里用的是QT4.8.6,QT5版本的connect函数则不同)

主线程------>子线程

connect(this,SIGNAL(StartThread()),mTcpSocketThread, SLOT(doWork()));

子线程-------->主线程

connect(mTcpSocketThread,SIGNAL(signal_connectsuccess(QString)),this,SLOT(slot_handle_state(QString)));

connect(mTcpSocketThread,SIGNAL(signal_back(QString)),this,SLOT(slot_handle_data(QString)));

使用connect不成功有可能是如下原因

这里需要注意 信号函数和槽函数的参数列表应该一致

使用信号槽,需要在类中声明 Q_OBJECT宏

槽函数应该用“private slots:”来修饰

信号函数应该用 “signals:”来修饰

6.子线程使用完毕应该及时回收并销毁

mThread->quit();

mThread->wait()

相关代码

主线程类:tcpclient.h

#ifndef TCPCLIENT_H

#define TCPCLIENT_H

#include

#include

#include

#include

#include

#include "ui_tcpclient.h"

#include "tcpsocketthread.h"

class TCPClient : public QWidget

{

Q_OBJECT

public:

explicit TCPClient(QWidget *parent = 0, Qt::WFlags flags = 0);

~TCPClient();

private:

Ui::TCPClientClass ui;

TCPSocketThread *mTcpSocketThread; //子线程

QThread *mThread; //线程管理器

private slots:

//处理链接状态信号

void slot_handle_state(QString);

//处理数据信号

void slot_handle_data(QString);

private slots:

//链接服务器

void on_Btn_Connect_clicked();

//启动线程

void on_Btn_start_clicked();

//断开链接

void on_Btn_DisConnect_clicked();

signals:

void StartThread();

};

#endif // TCPCLIENT_H

主线程类:tcpclient.cpp

#include "tcpclient.h"

TCPClient::TCPClient(QWidget *parent, Qt::WFlags flags)

: QWidget(parent, flags)

{

ui.setupUi(this);

//创建子线程

mTcpSocketThread = new TCPSocketThread();

//创建线程管理

mThread = new QThread();

//将子线程移动到线程管理器中

mTcpSocketThread->moveToThread(mThread);

//信号槽事件

connect(this,SIGNAL(StartThread()),mTcpSocketThread, SLOT(doWork()));//开启子线程

connect(mTcpSocketThread,SIGNAL(signal_connectsuccess(QString)),this,SLOT(slot_handle_state(QString)));//处理子线程信号

connect(mTcpSocketThread,SIGNAL(signal_back(QString)),this,SLOT(slot_handle_data(QString)));

}

TCPClient::~TCPClient()

{

}

void TCPClient::on_Btn_Connect_clicked()

{

//若线程正在运行,返回

if(mThread->isRunning()==true) return;

//线程状态设置为开启

mTcpSocketThread->setFlag(false);

//开启线程

mThread->start();

//启动了线程,并未进入线程

//发送信号,进入线程

emit StartThread();

ui.Lbl_ClientState->setText("Connected Success!");

}

void TCPClient::on_Btn_start_clicked()

{

}

void TCPClient::on_Btn_DisConnect_clicked()

{

//若线程已关闭,返回

if(mThread->isRunning()!=true) return;

//线程状态设置为关闭

mTcpSocketThread->setFlag(true);

mThread->quit();

mThread->wait();

ui.Lbl_ClientState->setText("Not Connected");

}

void TCPClient::slot_handle_state(QString str)

{

ui.Lbl_ClientState->setText(str);

}

void TCPClient::slot_handle_data(QString str)

{

ui.textEdit->append(str);

}

自定义线程类 tcpsocketthread.h

#ifndef TCP_SOCKET_THREAD

#define TCP_SOCKET_THREAD

#include

#include

#include

#include

#include

#include

#include

enum MessageType{ConnectRequest,ConnectSuccess,DisConnect,DataRequest/*..........*/};//消息请求类型

class TCPSocketThread :public QObject

{

Q_OBJECT

public:

explicit TCPSocketThread(QObject *parent = 0);

~TCPSocketThread(void);

private:

bool isStop; //线程是否停止

bool isConnected; //服务器是否链接

QTcpSocket *mTcpSocket;

quint16 nextBlockSize;

public:

//设置状态

void setFlag(bool flag = true);

private:

//链接服务器

void ConnectServer();

private slots:

//线程处理函数

void doWork();

//链接成功

void ConnectedSuccess();

//获取数据

void readData();

signals:

//链接状态信号

void signal_connectsuccess(QString);

//数据信号

void signal_back(QString);

};

#endif

自定义线程类 tcpsocketthread.cpp

#include "tcpsocketthread.h"

TCPSocketThread::TCPSocketThread(QObject *parent /* = 0 */):QObject(parent)

{

isStop = false;

isConnected = false;

mTcpSocket = new QTcpSocket(this);

nextBlockSize = 0;

connect(mTcpSocket,SIGNAL(connected()),this,SLOT(ConnectedSuccess()));

connect(mTcpSocket,SIGNAL(readyRead()),this,SLOT(readData()));

}

TCPSocketThread::~TCPSocketThread(void)

{

}

void TCPSocketThread::doWork()

{

while(!isStop)

{

if(!isConnected) ConnectServer();

QByteArray data;

QDataStream out(&data,QIODevice::WriteOnly);//======out

out<

mTcpSocket->write(data);

mTcpSocket->waitForReadyRead();

}

}

void TCPSocketThread::setFlag(bool flag)

{

isStop = flag;

}

void TCPSocketThread::ConnectServer()

{

QString ip = "127.0.0.1";

qint16 port = 40404;

mTcpSocket->connectToHost(QHostAddress(ip),port);

mTcpSocket->waitForConnected();

}

void TCPSocketThread::ConnectedSuccess()

{

isConnected = true;

QString str = "connected success!";

emit signal_connectsuccess(str);

}

void TCPSocketThread::readData()

{

//这里的代码都无关紧要

//.......

emit signal_back(str);

//.......

}

qtcpsocket断开_2020-05-06 QT子线程使用QTcpSocket连接服务器相关推荐

  1. QT子线程实现串口通信_学习记录

    QT子线程实现串口通信_学习记录 1 新的改变 功能快捷键 合理的创建标题,有助于目录的生成 如何改变文本的样式 插入链接与图片 如何插入一段漂亮的代码片 生成一个适合你的列表 创建一个表格 设定内容 ...

  2. qt客户端连接服务器不响应,qt判断tcp客户端是否连接服务器

    qt判断tcp客户端是否连接服务器 内容精选 换一换 本章节指导您使用MongoDB客户端,通过弹性云服务器内网方式连接GaussDB(for Mongo)集群实例.操作系统使用场景:弹性云服务器的操 ...

  3. QT子线程与主线程的信号槽通信

    最近用QT做一个服务器,众所周知,QT的主线程必须保持畅通,才能刷新UI.所以,网络通信端采用新开线程的方式.在涉及到使用子线程更新Ui上的控件时遇到了点儿麻烦.网上提供了很多同一线程不同类间采用信号 ...

  4. Qt对话框的事件循环分析(子线程中不能创建UI窗体分析)

    重要: GUI线程和辅助线程 如前所述,每个程序在启动时都有一个线程.这个线程被称为"主线程"(在Qt应用程序中也称为"GUI线程").Qt GUI必须在这个线 ...

  5. Qt对话框的事件循环分析(子线程中不能创建UI窗体分析2)

    Qt事件机制 QT-UI 后端 重要: GUI线程和辅助线程 如前所述,每个程序在启动时都有一个线程.这个线程被称为"主线程"(在Qt应用程序中也称为"GUI线程&quo ...

  6. 关于QT多线程子线程使用信号和

    主线程最后必须调用exit()和wait()函数 源码地址 http://download.csdn.net/download/u010261063/10185891 #ifndef QSYSENDT ...

  7. 【多线程】学习记录七种主线程等待子线程结束之后在执行的方法

    最近遇到一个问题需要主线程等待所有的子线程结束,才能开始执行,统计所有的子线程执行结果,返回,网上翻阅各种资料,最后记录一下,找到七种方案 第一种:while循环 对于"等待所有的子线程结束 ...

  8. qt调用linux系统的线程函数吗,Qt之主线程与子线程通讯(linux下)

    Qt之主线程与子线程通信(linux下) 转载请注明出处:http://blog.csdn.net/feng1790291543 主线程与子线程通信主要是通过Qt上的Gui按钮,触发使得主线程上的信息 ...

  9. QT小例子GUI(主)线程与子线程之间的通信

    QT小例子GUI(主)线程与子线程之间的通信 在主线程上,可以控制子线程启动,停止,清零 如果子线程启动的话,每一秒钟会向主线程发送一个数字,让主线程更新界面上的数字. #ifndef TQT_H_ ...

最新文章

  1. 2018.12.22 spoj7258 Lexicographical Substring Search(后缀自动机)
  2. 机器学习入门学习资源
  3. C++多个文本读取问题
  4. CM3计算板安装硬件时钟DS3231
  5. 一篇教你xftp连接阿里云轻量级应用服务器。超级详细,避免踩坑
  6. uniapp 封装网络请求
  7. 招程序员不要信中医的? | 从编程的角度看中医
  8. RocketMQ-安装使用
  9. C#Repeater控件的使用
  10. Pytorch 入门之数据处理 -- Dataset、Sampler、DataLoader
  11. Steam注册遇到CAPTCHA问题,一直注册不了,一个简单的注册办法
  12. LimeWire Basic 4.8.1 for Linux(转)
  13. 你是哪种类型的拖延症患者?
  14. 如何撤回已发送的邮件?邮件撤回成功后对方还能看到吗
  15. 上海创蓝253董事长_从世界记忆大师到互联网百强企业CEO:创蓝253钛牛哥的传奇之路...
  16. 支持OnVif协议的摄像头直播推流php
  17. 数据查询和业务流分开_基于大数据的舆情分析系统架构 - 架构篇
  18. WIN32 opengl三角形绘制
  19. 在浏览器端浏览EPUB
  20. 今天,我宣布了新 Logo

热门文章

  1. 【狂神JAVA】MyBatis笔记
  2. Python程序员面试必备常用问题答案及解析
  3. html中的rel,rev是什么?
  4. 关于Android中Intent传递Serialzilable数据的问题
  5. 存储专家论IP存储现实可行性
  6. MAT分析android内存泄漏
  7. PyQt4(简单界面)
  8. 防数据泄密:是否应实施“多重认证”?
  9. 百度对TOP等冷门域名冷淡
  10. ONLY三行脚本, SQL数据恢复到指定时间点