QT跨线程的信号与槽[2]---后台SOCKET

继上一篇文章

大体实现了一个与UI线程分离的SOCKET封装类

即后台线程负责收发数据包,有数据到来则通知UI线程

UI线程发送数据时通知后台线程(异步)

嗯,大概是这个意思

#pragma once
#include <QTcpSocket>
#include <QByteArray>
#include "XBackgroundWorker.h"

class CXAsyncSocket : public CXBackgroundWorker
{
	Q_OBJECT
public:
	explicit CXAsyncSocket(void);
	virtual ~CXAsyncSocket(void);
private:
	QTcpSocket *m_TcpSocket;
private slots:
	void Construct_Invokee();
	void Destruct_Invokee();
	void Connect_Invokee(char *host, quint16 port);
	void DisConnect_Invokee();
	void Send_Invokee(QByteArray buffer);
public:
	static void RegisterMetaTypes();

	// 下面三个函数用于前台线程
	void Connect(char *host, quint16 port);
	void DisConnect();
	void Send(QByteArray buffer);
private slots:
	// 执行环境为后台线程
	void OnReceive();
protected:
	// 执行环境为后台线程
	virtual void OnReceiveBuffer(QByteArray &buffer) = 0;
signals:
	void OnConnect();
	void OnDisConnect();
	void OnException(QAbstractSocket::SocketError);
};

#include "XAsyncSocket.h"

CXAsyncSocket::CXAsyncSocket()
{
	m_TcpSocket = NULL;
	QMetaObject::invokeMethod(this, "Construct_Invokee", Qt::BlockingQueuedConnection);
	Q_ASSERT(m_TcpSocket != NULL);
}

CXAsyncSocket::~CXAsyncSocket(void)
{
	Q_ASSERT(m_TcpSocket != NULL);
	QMetaObject::invokeMethod(this, "Destruct_Invokee", Qt::BlockingQueuedConnection);
	Q_ASSERT(m_TcpSocket == NULL);
}

void CXAsyncSocket::RegisterMetaTypes()
{
	qRegisterMetaType<char*>("char*");
	qRegisterMetaType<QAbstractSocket::SocketError>("QAbstractSocket::SocketError");
}

void CXAsyncSocket::Construct_Invokee()
{
	m_TcpSocket = new QTcpSocket;
	connect(m_TcpSocket, SIGNAL(connected()), this, SIGNAL(OnConnect()), Qt::QueuedConnection);
	connect(m_TcpSocket, SIGNAL(disconnected()), this, SIGNAL(OnDisConnect()), Qt::QueuedConnection);
	connect(m_TcpSocket, SIGNAL(error(QAbstractSocket::SocketError)), 
		this, SIGNAL(OnException(QAbstractSocket::SocketError)), Qt::QueuedConnection);
	connect(m_TcpSocket, SIGNAL(readyRead()), this, SLOT(OnReceive()), Qt::QueuedConnection);
}

void CXAsyncSocket::Destruct_Invokee()
{
	m_TcpSocket->disconnect();
	m_TcpSocket->abort();
	delete m_TcpSocket;
	m_TcpSocket = NULL;
}

void CXAsyncSocket::Connect_Invokee(char *host, quint16 port)
{
	m_TcpSocket->connectToHost(host, port);
}

void CXAsyncSocket::Connect(char *host, quint16 port)
{
	QMetaObject::invokeMethod(this, "Connect_Invokee", Qt::QueuedConnection, Q_ARG(char*, host), Q_ARG(quint16, port));
}

void CXAsyncSocket::DisConnect_Invokee()
{
	m_TcpSocket->abort();
}

void CXAsyncSocket::DisConnect()
{
	QMetaObject::invokeMethod(this, "DisConnect_Invokee", Qt::QueuedConnection);
}

void CXAsyncSocket::Send_Invokee(QByteArray buffer)
{
	m_TcpSocket->write(buffer);
}

void CXAsyncSocket::Send(QByteArray buffer)
{
	QMetaObject::invokeMethod(this, "Send_Invokee", Qt::QueuedConnection, Q_ARG(QByteArray, buffer));
}

void CXAsyncSocket::OnReceive()
{
	OnReceiveBuffer(m_TcpSocket->readAll());
}


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Qt中,线程信号连接需要使用Qt线程间通信机制。下面是一些基本的步骤: 1. 使用QObject::moveToThread()方法将对象移动到目标线程。 2. 在目标线程中创建一个QObject,并调用QObject::connect()方法将信号连接起来。 3. 如果信号需要传递参数,则需要使用Qt的元对象系统(Meta-Object System)来注册参数类型。可以使用Q_DECLARE_METATYPE宏来注册自定义类型。 4. 在发送信号时,需要使用QMetaObject::invokeMethod()方法,将该方法的第一个参数设置为接收信号的对象,第二个参数设置为接收信号的函数名,第三个参数设置为Qt::QueuedConnection,以确保信号被放入目标线程的事件队列中。 下面是一个简单的示例: ```cpp class Worker : public QObject { Q_OBJECT signals: void resultReady(int result); public slots: void doWork() { int result = 0; // 计算结果 emit resultReady(result); } }; class Controller : public QObject { Q_OBJECT public: Controller() { Worker *worker = new Worker(); QThread *workerThread = new QThread(); worker->moveToThread(workerThread); connect(workerThread, &QThread::started, worker, &Worker::doWork); connect(worker, &Worker::resultReady, this, &Controller::handleResult); workerThread->start(); } ~Controller() { // 停止线程 } public slots: void handleResult(int result) { // 处理结果 } }; ``` 在这个例子中,Worker对象的doWork()方法在一个新的线程中执行,当计算完成后,使用信号resultReady(int result)发送结果。Controller对象将自己的handleResult(int result)连接到该信号上,在目标线程中处理结果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值