在你提供的代码中,出现了QObject::moveToThread相关错误以及关于QSocketNotifier的问题。这个问题通常与Qt的对象在不正确的线程上下文中被创建或移动有关。具体来说,你不能将一个已经被创建的QTcpSocket对象从一个线程移动到另一个线程,因为Qt中的对象(特别是继承自QObject的类)只能在其创建时所在的线程内使用。
问题分析:
- QTcpSocket 对象: 你的代码尝试将通过 - TcpClient::getInstance()->GetTcpSocket()获取到的- QTcpSocket移动到不同的线程。这是问题所在。因为这个 socket 对象是在主线程中创建的,所以直接调用- moveToThread()会导致运行时错误。
- 线程间通信: 通常,网络操作应该放置在特定于工作的线程中,并且信号和槽机制可以帮助我们进行跨线程通信,而不是直接移动这些对象。 
修复建议:
- 不移动 QTcpSocket:确保所有网络操作都在它们原始创建的同一线程中执行。你可以选择将 socket 的使用放入 QThread 的 run() 方法中,而不是尝试将其移至不同的线程。 
- 使用信号和槽来处理事件:而不是让多个线程序直接访问 socket,可以通过信号和槽来触发心跳发送等操作。 
下面是修正后的代码示例,避免了对 QTcpSocket 的移动,同时保留了多线程结构。
#include <QApplication>
#include <QTcpSocket>
#include <QByteArray>
#include <QDataStream>
#include <QDebug>
#include <QList>
#include <windows.h>
#include <tlhelp32.h>
#include <psapi.h>
#include <QFileInfo>
#include <QThread>
#include "protocolTool.h"
#include "tcpclient.h"
#include "mainwindow.h"
class MaintestServerStartThread : public QThread
{
public:
    void run() override
    {
        TcpClient::getInstance()->Start(); // Start TCP client here.
    }
};
class ThreadClientHeartbeatStart : public QThread
{
public:
    void run() override
    {
        while (true)
        {
            QTcpSocket *socket = TcpClient::getInstance()->GetTcpSocket();
            if (socket->state() == QAbstractSocket::ConnectedState) {
                TcpClient::getInstance()->SendHeartbeat(); // Send heartbeat from the main thread.
            }
            Sleep(1000);
        }
    }
};
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    
    // Initialize and configure TcpClient instance
    TcpClient::getInstance();
    
    QString strIp = (argc > 1) ? argv[1] : "127.0.0.1";
    
    MainWindow w;
    w.show();
    // Connect signals and slots for handling UI updates based on TCP events.
    QObject::connect(TcpClient::getInstance(), SIGNAL(sigShowQroll_call()), roll_call, SLOT(slotShowQroll_call()));
    
    TcpClient::getInstance()->SetTcpConnectIp(strIp);
    // Create and start server starter thread
    MaintestServerStartThread* serverStarter = new MaintestServerStartThread();
    serverStarter->start();
    // Create and start heartbeat checker thread
    ThreadClientHeartbeatStart* heartbeatChecker = new ThreadClientHeartbeatStart();
    heartbeatChecker->start();
    return a.exec();
}
总结
- 确保所有 QTcpSocket及其相关函数都是在线程安全且适当的上下文下调用。
- 避免在线程之间直接移动 QObject对象,如网络连接等,这可能会导致状态不一致或崩溃。
- 使用 Qt 的信号和槽机制以异步方式处理跨线程事件。
如果还有其他问题或需要进一步的信息,请随时询问!
内容由零声教学AI助手提供,问题来源于学员提问


 
                             
         
        
 
         
         
         
         
         
         
        
 
                 
                 
                 
                 
                 
                 
                 
                 
                