在您的代码中,MainWindow
的实例是在 MaintestServerStartThread
线程中创建的,但这个实例没有被保留或显示,因为在每次循环中都会创建一个新的 MainWindow
对象,并且它会很快被销毁。为了使 MainWindow
正常显示并保持可见,您应该考虑以下几点:
在主线程中创建 MainWindow:Qt GUI 应该在主线程中运行。因此,在工作线程 (
MaintestServerStartThread
) 中创建和显示窗口是不推荐的。使用信号与槽机制:可以在工作线程中接收到数据后,通过信号与主线程进行通信,从而更新 UI 或者打开
MainWindow
。持久化 MainWindow 实例:如果确实需要在
MaintestServerStartThread
中显示窗体,您需要保持对MainWindow
实例的引用,以防止其被销毁。
以下是基于这些建议改进后的示例代码:
class MyApplication : public QApplication {
public:
MyApplication(int &argc, char **argv) : QApplication(argc, argv), mainWin(nullptr) {}
void showMainWindow() {
if (!mainWin) {
mainWin = new MainWindow();
mainWin->show();
}
}
private:
MainWindow *mainWin;
};
DWORD WINAPI MaintestServerStartThread(LPVOID lpParam)
{
MyApplication *app = reinterpret_cast<MyApplication *>(lpParam);
while (true) {
QTcpSocket socket;
socket.connectToHost("127.0.0.1", 8809); // 连接到服务器
int datasize = 0;
if (socket.waitForConnected()) {
qDebug() << "Connected to the server.";
app->showMainWindow(); // 在这里调用方法来显示 MainWindow
while (true) {
if (socket.state() == QAbstractSocket::ConnectedState) {
// Socket 连接正常
if (socket.waitForReadyRead()) { // 等待有数据可读
QByteArray data = socket.readAll(); // 读取所有可用数据
datasize += data.size();
qDebug()<<"datasize:"<< datasize<<endl;
tcpClient::getInstance()->processData(data);
}
} else {
break; // Socket 连接已断开
}
}
socket.disconnectFromHost(); // 断开连接
} else {
qDebug() << "Failed to connect to the server.";
QThread::sleep(5); // 等待重连
}
}
return 0;
}
int main(int argc, char *argv[])
{
MyApplication a(argc, argv);
HANDLE threadHandle = CreateThread(NULL, 0, MaintestServerStartThread, &a, 0, NULL);
CloseHandle(threadHandle);
return a.exec();
}
改动说明:
- 创建了一个自定义的
MyApplication
类,用于管理MainWindow
的生命周期。 - 使用了指向应用程序实例的指针,在工作线程内通过调用成员函数来显示
MainWindow
。
这样确保了 MainWindow
是在主线程中显示,并且只会初始化一次,不会因为循环中的多次尝试而不断生成新的对象。
内容由零声教学AI助手提供,问题来源于学员提问