qt把unity发入widget中
头文件showunitywindowsinqt

#ifndef SHOWUNITYWINDOWSINQT_H
#define SHOWUNITYWINDOWSINQT_H
#include <QObject>
#include <QProcess>
#include <windows.h>
#include <winuser.h>
#include <QDebug>
class ShowUnityWindowsInQt : public QObject
{
    Q_OBJECT
public:
    explicit ShowUnityWindowsInQt(QObject* parent = nullptr);
    ~ShowUnityWindowsInQt();
    void startUnityProgram(const QString& unityExePath);
    void setWindowParent(HWND parentWidgetHandle, const QString& sonWindowTitleName);
signals:
    void unityProgramStarted();//定义信号不需要在cpp文件中实现。信号本身是一种声明,它告诉编译器该对象将会发出该信号,其他对象可以连接到这个信号以接收通知。
private:
    QProcess* process;
};
#endif // SHOWUNITYWINDOWSINQT_H

cpp文件 showunitywindowsinqt.cpp

#include "showunitywindowsinqt.h"
#include <QTimer>
#include <QThread>

ShowUnityWindowsInQt::ShowUnityWindowsInQt(QObject* parent)
    : QObject{parent}
{
    //Qprocess 执行行外部进程,它提供了一种在应用程序内部启动和管理外部程序的方式
    process = new QProcess(this);
    connect(process, &QProcess::started, this, &ShowUnityWindowsInQt::unityProgramStarted);//   当执行新进程时将会发射信号
   //QProcess::started 信号是在 QProcess 对象开始执行新进程时发出的


}

ShowUnityWindowsInQt::~ShowUnityWindowsInQt()
{
    process->kill();//强制终止当前正在运行的进程
}

void ShowUnityWindowsInQt::startUnityProgram(const QString& unityExePath)
{
    process->setProgram(unityExePath);//将 unityExePath 设置为要执行的程序路径
    process->start(QIODevice::Truncate);//启动进程
    qDebug() << "PID: " << process->processId();//打印出当前进程的进程 ID(PID)。
}

void ShowUnityWindowsInQt::setWindowParent(HWND parentWidgetHandle, const QString& sonWindowTitleName)//父窗口句柄,unity的名称
{
    qDebug()<<"第一个参数"<<parentWidgetHandle<<"第二个参数"<<sonWindowTitleName;
    std::wstring titleName = sonWindowTitleName.toStdWString();
    HWND hfigure = nullptr;//nullptr表示一个空地址或者空指针对象
    while (true)//找到unity窗口的句柄
        {
        //通过 FindWindowW(nullptr, titleName.c_str()) 搜索具有指定窗口名的子窗口,并将返回的子窗口句柄赋值给 hfigure。
        //将 nullptr 传递给函数的第一个参数,表示查找顶级窗口(即不指定窗口类名),将 titleName.c_str() 传递给函数的第二个参数,表示查找具有指定窗口名的窗口,
            hfigure = FindWindowW(nullptr, titleName.c_str());//titleName是所指定的窗口名
                qDebug()<<"搜找到的hfigure是"<<hfigure;
            if (hfigure != nullptr)
            {
                qDebug() <<"find sucess";
                break;
            }
            QThread::msleep(100);//延时100毫秒
        }
        qDebug() << "话柄是"<<hfigure;
        RECT rect;
        qDebug() << "2222";
        GetWindowRect(parentWidgetHandle, &rect);//获取父窗口的矩形区域
        QThread::msleep(500);//延时500毫秒
        SetParent(hfigure, parentWidgetHandle);//将子窗口设置为父窗口的子控件
        qDebug() << "3333";

           LONG_PTR dwStyle = GetWindowLongPtr(hfigure, GWL_STYLE);//子窗口样式
           dwStyle = dwStyle & ~(WS_THICKFRAME | WS_CAPTION | WS_SIZEBOX | WS_MAXIMIZEBOX | WS_MINIMIZEBOX);//移除子窗口的移动和调整大小的样式
              dwStyle |= WS_CHILD | WS_CLIPCHILDREN;//添加固定位置的样式。WS_CHILD 表示这是一个子窗口,WS_CLIPCHILDREN 表示绘制子窗口时,只绘制子窗口区域内的内容。(注释此行可实现,滑动鼠标滚轮进行放大缩小)
              SetWindowLongPtr(hfigure, GWL_STYLE, dwStyle);//更新子窗口的样式

           MoveWindow(hfigure, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, true);//将子窗口移动到父窗口的位置,并调整大小以适应父窗口
        SetWindowPos(hfigure, HWND_TOP, 0, 0, rect.right - rect.left, rect.bottom - rect.top, SWP_SHOWWINDOW |SWP_HIDEWINDOW);//设置窗口的位置和大小,并可以控制窗口的显示和隐藏
       //(hfigure, HWND_TOP, 0, 0, rect.right - rect.left, rect.bottom - rect.top, SWP_SHOWWINDOW |SWP_HIDEWINDOW);0,0,代表与父窗口的左上角位置相同

        ShowWindow(hfigure, SW_SHOW);//显示子窗口
      SetFocus(hfigure);//焦点设置到子窗口。使用户直接在该子窗口中输入字符和操作控件,而不必手动点击选中该子窗口。
}

调用上述文件,实现在一个widget中显示unity(widget:ui->tab

要实现处的头文件(mainwindow.h)

//头文件
#include "showunitywindowsinqt.h"
#include <QTcpSocket>

//定义 unit与tcp协议
 ShowUnityWindowsInQt* util;
    QTcpSocket *tcpSocket;

private slots:

    void onConnected();//连接
    void onDisconnected();//连接断开
    void onReadyRead();//接受unity数据
    void msg();//向unity发送数据

要实现处的cpp文件(mainwindow.cpp)

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "QPushButton"
#include <QProcess>
#include<QJsonArray>
#include <QJsonObject>
#include <QJsonDocument>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //unity的exe显示
    util = new ShowUnityWindowsInQt(this);
  //  QString titleName("6");
    QString titleName("baban2");//unity的.exe名称
    connect(util, &ShowUnityWindowsInQt::unityProgramStarted, this, [&]()
            {
                util->setWindowParent((HWND)ui->tab->winId(),titleName);//ui->tab指的是ui设计界面中的一个widget
            });//当信号被发射时,执行对应的槽函数
   QString unityExePath("./Baban2/baban2.exe");//unity的路径
   // QString unityExePath("./unity1/6.exe");
    util->startUnityProgram(unityExePath);//startUnityProgram启动进程,proess有新进程,unityProgramStarted信号发射,setWindowParent函数触发将unity窗口放入widget窗口中
    //tcp
    tcpSocket = new QTcpSocket(this);
    connect(tcpSocket, &QTcpSocket::connected, this, &MainWindow::onConnected);//tcp连接时触发onConnected函数
    connect(tcpSocket, &QTcpSocket::disconnected, this, &MainWindow::onDisconnected);
    connect(tcpSocket, &QTcpSocket::readyRead, this, &MainWindow::onReadyRead);
 //   tcpSocket->connectToHost("127.0.0.1", 12345);//tcp连接的 ip地址 和 端口号
      tcpSocket->connectToHost("127.0.0.1", 9998);
    //发送按钮
    QPushButton *sendbtn=new QPushButton (this);
    sendbtn->setText("发送");
    sendbtn->setGeometry(0,0,100,100);
   connect(sendbtn,SIGNAL(clicked()),this,SLOT(msg()));
   //发送json
   QJsonObject jsonObject;
    QJsonArray jsonArray;
      jsonObject.insert("Key","K文件");
      jsonObject.insert("Value",jsonArray);
      QJsonDocument jsonDoc(jsonObject);//将QJsonObject转换为JSON格式的字符串。
      QString jsonData = jsonDoc.toJson(QJsonDocument::Compact);
        tcpSocket->write(jsonData.toUtf8());
}
void MainWindow::msg()//发送消息
{
//发送字符串
    QString name="驾驶员";
    tcpSocket->write(name.toUtf8());
    qDebug()<<name.toUtf8();
}
MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::onConnected()
{
    // 连接建立时的处理
    qDebug()<<"连接以建立";
}
void MainWindow::onDisconnected()
{
    // 连接断开时的处理
     qDebug()<<"连接断开";
}
void MainWindow::onReadyRead()
{
    // 接收到数据时的处理
    QByteArray receivedData = tcpSocket->readAll();
    QString receivedString = QString::fromUtf8(receivedData);//转换成正确的string格式
   qDebug()<<"接受的数据是 "+receivedString;    
}