为啥 QTcpSocket 不发出信号?
Posted
技术标签:
【中文标题】为啥 QTcpSocket 不发出信号?【英文标题】:Why QTcpSocket does not emit signals?为什么 QTcpSocket 不发出信号? 【发布时间】:2013-08-13 14:24:40 【问题描述】:我在使用 QTcpSocket 时遇到问题,它没有发出任何信号:/
void NetworkInstance::run()
m_pSocket = new QTcpSocket();
connect(m_pSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError()));
connect(m_pSocket, SIGNAL(hostFound()), this, SLOT(socketHostLookupDone()));
connect(m_pSocket, SIGNAL(connected()), this, SLOT(socketConnected()));
connect(m_pSocket, SIGNAL(disconnected()), this, SLOT(socketDisconnected()));
connect(m_pSocket, SIGNAL(readyRead()), this, SLOT(socketReadyRead()));
QSettings s;
s.beginGroup("network");
emit log(QString("Connection to: ").append(s.value("host").toString()).append(":").append(s.value("port").toString()));
m_pSocket->connectToHost(s.value("host").toString(), s.value("port").toInt());
s.endGroup();
exec();
这是我的代码,我没有看到任何错误,但没有发出已连接的信号(hostFound、已连接等)。在服务器上,我可以看到已建立连接并发送了数据,但客户端没有任何反应。 NetworkInstance 正在扩展 QThread。
【问题讨论】:
如果你是 QThread 的子类,“你做错了”:blog.qt.digia.com/blog/2010/06/17/youre-doing-it-wrong 你根本不需要QThread!在所有 QTcpSocket 异步工作之后,您可以安全地在主线程中运行它。 我需要 QThread,我对接收到的数据进行了一些繁重的处理(是的,可以将处理本身放入 QThread,但这样更简单)。我每个线程有一个套接字,它适合我的需要。然而,公认的答案就是解决方案。 【参考方案1】:根据我之前的评论,子类化 QThread 是错误的,您需要做的是创建从 QObject 继承的类,然后将其移动到新的 QThread。
所以你会有一个看起来像这样的类:-
class NetworkInstance : public QObject
Q_OBJECT
public:
NetworkInstance();
public slots:
void Run();
void socketConnected();
void socketError();
// etc for other slots...
private:
class QTCPSocket* m_pSocket;
创建您的网络实例对象和线程:-
QThread* pThread = new QThread;
NetworkInstance* pNetworkInstance = new NetworkInstance;
创建 QTCPSocket 实例并连接 NetworkInstance 类中的信号/插槽,然后创建 QThread 并将您的类移动到线程:-
pNetworkInstance->moveToThread(pThread);
最后,启动线程运行:-
pThread->start();
【讨论】:
实现相同目的的一种不太复杂的方法是将 QObject 和 QRunnable 子类化,然后将工作线程传递给 QThreadPool 不完全是,'不那么复杂'恕我直言,但我同意这是另一种可能的方法。 事实上他根本不需要QThread。 QTCPSocket 异步工作。 是的,但也许他的班级会处理传入的数据包,并希望在不同的线程上执行此操作。【参考方案2】:我确定信号已发出。我不太确定它们是否被另一个线程中的插槽接收。应该。一般。
Qt::AutoConnection
(默认)如果信号是从不同的线程发出的,而不是 接收对象,信号被排队,表现为 Qt::QueuedConnection。否则,直接调用槽, 表现得像 Qt::DirectConnection。确定连接类型 当信号发出时。
但是现在你在 run() 中使用 exec() 开始你自己的事件循环。
编辑:啊……我明白了……
Qt::QueuedConnection
当控制返回到 接收者线程的事件循环。该插槽在 接收者的线程。
这是自动使用的,因为发送者和接收者在不同的线程中。但是使用你的 'exec()' 控件永远不会返回到接收者的线程。
【讨论】:
so.. 你说我不应该用 exec() 开始自己的事件循环吗?我不确定没有它它会如何工作,但尝试了它并没有帮助。以上是关于为啥 QTcpSocket 不发出信号?的主要内容,如果未能解决你的问题,请参考以下文章
Qt - 当一个类中有多个 QTcpSocket 时,我如何知道哪个 QTcpSocket 发出了 readyRead 信号?