将ue4程序嵌入qt界面显示
Posted Leslie X徐
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将ue4程序嵌入qt界面显示相关的知识,希望对你有一定的参考价值。
windows窗口编程
需求:将ue4程序嵌入qt界面显示
思路:通过使用 windowsAPI 对ue4窗口进行设置跟随qt界面以及活动窗口时的位置层序设置
结果:
1.打开程序获取句柄 设置样式
函数:
- 获取窗口句柄:
HWND FindWindow(L"class name",L"window title")
数据可通过“句柄精灵”软件获取 - 设置窗口样式:
SetWindowLong(HWND, GWL_STYLE, LONG dwNewLong)
- 获取窗口样式:
GetWindowLong(HWND, GWL_STYLE)
- 窗口样式宏
void Unreal4::on_pushButton_clicked()
QString unreal4Path"D:/lesliex/QTpro/QWidgetUnreal4/Windows/UEMetaFactory.exe";
QStringList arguments;
arguments << "-WINDOWED";
_process=new QProcess;
_process->start(unreal4Path,arguments);
QtConcurrent::run([this]
while(true)
_hwnWindow=FindWindow(L"UnrealWindow",L"UEMetaFactory ");
SetWindowLong(_hwnWindow, GWL_STYLE, GetWindowLong(_hwnWindow, GWL_STYLE) & (~WS_OVERLAPPEDWINDOW));//使用&~去除某种样式
if(_hwnWindow != NULL)
qDebug()<<("get SeerSupports");
emit sigUe4Complete();
break;
);
2.等待显示 移动位置
此处不使用 createWindowContainer,对ue4有鼠标键盘交互问题
函数:
- 移动窗口:
BOOL MoveWindow(
[in] HWND hWnd,
[in] int X,
[in] int Y,
[in] int nWidth,
[in] int nHeight,
[in] BOOL bRepaint
);
等待到窗口出现才能获取句柄
connect(this,&Unreal4::sigUe4Complete,this,&Unreal4::slotUe4Complete);
void Unreal4::slotUe4Complete()
//createWindowContainer方式不好
// _window=QWindow::fromWinId((WId)_hwnWindow);
// _windowWidget = QWidget::createWindowContainer(_window);
_windowWidget = ui->widget_2;
MoveWindow(_hwnWindow,mapToGlobal(_windowWidget->pos()).x(),mapToGlobal(_windowWidget->pos()).y(),_windowWidget->width(),_windowWidget->height(),false);
3.定时器定时显示窗口到最上层
函数:
BOOL SetWindowPos(
[in] HWND hWnd,
[in, optional] HWND hWndInsertAfter,
[in] int X,
[in] int Y,
[in] int cx,
[in] int cy,
[in] UINT uFlags
);
将hWnd
移动到hWndInsertAfter
下层,并设置位置和大小,显示方式。
HWND GetWindow(
[in] HWND hWnd,
[in] UINT uCmd
);
要获取已知窗口上层的窗口句柄可用 GetWindow( (HWND)this->winId() ,GW_HWNDPREV )
当主要窗口和ue程序为活动窗口时,将hWndInsertAfter
设置为HWND_TOPMOST
,uFlags
设置为SWP_NOACTIVATE
只显示不激活
当主要窗口不为活动窗口时,将hWndInsertAfter
设置为 GetWindow( (HWND)this->winId() ,GW_HWNDPREV )
,uFlags
设置为SWP_NOACTIVATE
只显示不激活
Unreal4::Unreal4(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Unreal4)
ui->setupUi(this);
_timer = new QTimer(this);
_timer->start(10);
connect(_timer,&QTimer::timeout,this,&Unreal4::timerShowUe4);
void Unreal4::timerShowUe4()
if(_windowWidget)
if(GetForegroundWindow()==_hwnWindow||this->isActiveWindow())
qDebug()<<"isActive";
SetWindowPos(_hwnWindow, HWND_TOPMOST, mapToGlobal(_windowWidget->pos()).x(),mapToGlobal(_windowWidget->pos()).y(),\\
_windowWidget->width(),_windowWidget->height(),SWP_NOACTIVATE);
else
qDebug()<<"NotActive";
SetWindowPos(_hwnWindow, GetWindow((HWND)this->winId(),GW_HWNDPREV), mapToGlobal(_windowWidget->pos()).x(),mapToGlobal(_windowWidget->pos()).y(),\\
_windowWidget->width(),_windowWidget->height(),SWP_NOACTIVATE);
4.重写QWidget事件
函数:
- 设置窗口显示:
ShowWindow(HWND, int nCmdShow)
设置nCmdShow
:显示不激活为SW_SHOWNOACTIVATE
,隐藏为SW_HIDE
void Unreal4::showEvent(QShowEvent *event)
if(_process) ShowWindow(_hwnWindow,SW_SHOWNOACTIVATE);
void Unreal4::resizeEvent(QResizeEvent *event)
if(_windowWidget)
MoveWindow(_hwnWindow,mapToGlobal(_windowWidget->pos()).x(),mapToGlobal(_windowWidget->pos()).y(),_windowWidget->width(),_windowWidget->height(),false);
void Unreal4::hideEvent(QHideEvent *event)
if(_process) ShowWindow(_hwnWindow,SW_HIDE);
5.源码
pro文件中加入:
LIBS += -luser32
头文件:
#ifndef UNREAL4_H
#define UNREAL4_H
#include "mwidget.h"
#include <QProcess>
#include "windows.h"
#include <QTimer>
QT_BEGIN_NAMESPACE
namespace Ui class Unreal4;
QT_END_NAMESPACE
/// \\brief The Unreal4 class
/// \\details 将UE4界面嵌入QT界面
class Unreal4 : public QWidget
Q_OBJECT
public:
Unreal4(QWidget *parent = nullptr);
~Unreal4();
void closeUe4();
private slots:
void slotUe4Complete();
void on_pushButton_clicked();
void on_pushButton_2_clicked();
void on_pushButton_3_clicked();
void on_pushButton_4_clicked();
signals:
void sigUe4Complete();
private:
Ui::Unreal4 *ui;
QProcess *_processQ_NULLPTR;
HWND _hwnWindowQ_NULLPTR;
QWidget *_windowWidgetQ_NULLPTR;
QWindow * _windowQ_NULLPTR;
QTimer* _timerQ_NULLPTR;
// QWidget interface
protected:
void timerShowUe4();
void showEvent(QShowEvent *event) override;
void resizeEvent(QResizeEvent *event) override;
void hideEvent(QHideEvent *event) override;
;
#endif // UNREAL4_H
源文件:
#include "Unreal4.h"
#include "ui_Unreal4.h"
#include <QWindow>
#include <QDebug>
#include <QPalette>
#include <QtConcurrent>
#include <QMouseEvent>
#include <QPainter>
Unreal4::Unreal4(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Unreal4)
ui->setupUi(this);
connect(this,&Unreal4::sigUe4Complete,this,&Unreal4::slotUe4Complete);
_timer = new QTimer(this);
_timer->start(10);
connect(_timer,&QTimer::timeout,this,&Unreal4::timerShowUe4);
Unreal4::~Unreal4()
closeUe4();
delete ui;
void Unreal4::closeUe4()
if(!_process) return;
if(_process->state()==QProcess::Running)
_process->kill();
QString exe = "UEMetaFactory-Win64-Shipping.exe";
_process->execute("taskkill",QStringList()<<"-im"<<exe<<"-f");
_process->waitForFinished(5000);
delete _process; _process = Q_NULLPTR;
ui->verticalLayout->removeWidget(_windowWidget); delete _windowWidget;
void Unreal4::slotUe4Complete()
_windowWidget = ui->widget_2;
MoveWindow(_hwnWindow,mapToGlobal(_windowWidget->pos()).x(),mapToGlobal(_windowWidget->pos()).y(),_windowWidget->width(),_windowWidget->height(),false);
void Unreal4::on_pushButton_clicked()
QString unreal4Path"D:/lesliex/QTpro/QWidgetUnreal4/Windows/UEMetaFactory.exe";
QStringList arguments;
arguments << "-WINDOWED";
_process=new QProcess;
_process->start(unreal4Path,arguments);
QtConcurrent::run([this]
while(true)
_hwnWindow=FindWindow(L"UnrealWindow",L"UEMetaFactory ");
SetWindowLong(_hwnWindow, GWL_STYLE, GetWindowLong(_hwnWindow, GWL_STYLE) & (~WS_OVERLAPPEDWINDOW));
if(_hwnWindow != NULL)
qDebug()<<("get SeerSupports");
emit sigUe4Complete();
break;
);
//==================================show ue4===============================
void Unreal4::timerShowUe4()
if(_windowWidget)
if(GetForegroundWindow()==_hwnWindow||this->isActiveWindow())
qDebug()<<"isActive";
SetWindowPos(_hwnWindow, HWND_TOPMOST, mapToGlobal(_windowWidget->pos()).x(),mapToGlobal(_windowWidget->pos()).y(),\\
_windowWidget->width(),_windowWidget->height(),SWP_NOACTIVATE);
else
qDebug()<<"NotActive";
SetWindowPos(_hwnWindow, GetWindow((HWND)this->winId(),GW_HWNDPREV), mapToGlobal(_windowWidget->pos()).x(),mapToGlobal(_windowWidget->pos()).y(),\\
_windowWidget->width(),_windowWidget->height(),SWP_NOACTIVATE);
void Unreal4::showEvent(QShowEvent *event)
if(_process) ShowWindow(_hwnWindow,SW_SHOWNOACTIVATE);
void Unreal4::resizeEvent(QResizeEvent *event)
if(_windowWidget)
MoveWindow(_hwnWindow,mapToGlobal(_windowWidget->pos()).x(),mapToGlobal(_windowWidget->pos()).y(),_windowWidget->width(),_windowWidget->height(),false);
void Unreal4::hideEvent(QHideEvent *event)
if(_process) ShowWindow(_hwnWindow,SW_HIDE);
//=====================button==========================
void Unreal4::on_pushButton_3_clicked()
_timer->start(10);
if(_process) ShowWindow(_hwnWindow,SW_SHOWNOACTIVATE);
void Unreal4::on_pushButton_2_clicked()
this->close();
void Unreal4::on_pushButton_4_clicked()
_timer->stop();
if(_process) ShowWindow(_hwnWindow,SW_HIDE);
以上是关于将ue4程序嵌入qt界面显示的主要内容,如果未能解决你的问题,请参考以下文章
对《将Unreal4打包后的工程嵌入到Qt或者桌面中》一文的补充