在上一文中本人尝试将Ue4嵌入到Qt中,但依然有一些问题没有去尝试解决。今天因为帮助知乎专栏作者@大钊的关系,顺便进行补完
已知的坑
1、因为启动的exe进程并非游戏进程,所以通过QProcess的状态来判断Ue4是否启动是不对的,推荐使用WINAPI来获取对应线程。
2、可以在项目设置中修改窗口显示标题,可以把讨厌的(32-bit, PCD3D_SM5)去掉,强烈推荐使用窗口句柄查看工具,我是网上下了句柄精灵。(窗口标题后面都是有空格的)
嵌入Qt后,UE4无法接受键盘鼠标输入
使用 以下函数
//window为QWindow
window->setKeyboardGrabEnabled(true);
window->setMouseGrabEnabled(true);
在使用createWindowContainer函数时有两个选择
QWidget::createWindowContainer(window,nullptr,Qt::Window);
QWidget::createWindowContainer(window);
区别在于前者为窗口模式,可以很好接受鼠标与键盘输入,后者无法接受鼠标操作。
但是如果使用Qt的QProcess来启动Ue4,前者就只能接受鼠标操作了。
本人认为这个是焦点的问题,需要在焦点改变时重新指定。这里就麻烦各位自己动手解决了
关于静默启动外部程序与枚举进程与窗体句柄
因为本人对WINAPI不熟所以只找了一些资料
打开一个外部程序,一般是通过ShellExecute/Ex或CreateProcess或WinExec等API。
至于隐藏主窗口以及控制窗口上的控件,这个根据不同的程序会有一定的复杂程度,首先是找到所谓的主窗口,然后再枚举窗口上的子窗口,通过一系列API模拟点击或读取/设置文本内容等。
https://www.cnblogs.com/zjutlitao/p/3889900.html
代码
#pragma comment(lib, "User32.lib")
#include "widget.h"
#include "ui_widget.h"
#include "windows.h"
#include <QWindow>
#include <QDebug>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget),process(nullptr)
{
ui->setupUi(this);
}
Widget::~Widget()
{
//进程无法直接关闭,因为Ue4会启动另一个UeGame进程,如果是发布模式名字会改变
// process->terminate();
// process->waitForFinished();
if(process)
delete process;
delete ui;
}
void Widget::on_pushButton_clicked()
{
// //因为启动的进程并非游戏进程,所以通过QProcess的状态来判断Ue4是否启动是不对的
// //推荐使用WINAPI来获取对应线程
QString unreal4Path{"D:/QtProject/QtWithUnreal4/WindowsNoEditor/DemoGame.exe"};
QStringList arguments;
arguments << "-WINDOWED";
process=new QProcess;
connect(process,SIGNAL(stateChanged(QProcess::ProcessState)),this,SLOT(insetQt(QProcess::ProcessState)));
process->start(unreal4Path,arguments);
// WinExec("D:\\QtProject\\QtWithUnreal4\\WindowsNoEditor\\DemoGame.exe",SW_HIDE);
}
void Widget::insetQt(QProcess::ProcessState state){
qDebug()<<state;
if(state!=QProcess::Running)
return;
Sleep(3000);
//可以在项目设置中修改窗口显示标题,可以把讨厌的(32-bit, PCD3D_SM5)去掉
//强烈推荐使用窗口句柄查看工具,我是网上下了句柄精灵
HWND hwnWindow=FindWindow(NULL,L"DemoGame ");
qDebug()<<hwnWindow;
QWindow *window=QWindow::fromWinId((WId)hwnWindow);
//方法一
// SetParent(hwnWindow,(HWND)QWidget::winId());
// window->showFullScreen();
//方法二
window->requestActivate();
// //嵌入Qt窗口,需要设置焦点让Ue4接受按键事件
QWidget *windowWidget=QWidget::createWindowContainer(window,nullptr,Qt::Window);
// QWidget *windowWidget=QWidget::createWindowContainer(window);
//获取键盘与鼠标的输入
window->setKeyboardGrabEnabled(true);
window->setMouseGrabEnabled(true);
ui->verticalLayout->insertWidget(0,windowWidget,1);
// windowWidget->setFocusPolicy(Qt::StrongFocus);
// windowWidget->setFocus();
// windowWidget->grabKeyboard();
// windowWidget->grabMouse();
this->setFocusPolicy(Qt::NoFocus);
}
原文地址:https://www.cnblogs.com/blueroses/p/9151094.html
时间: 2024-10-13 06:25:58