首先可以参考如下文章:
QT打开外部程序并嵌入Qt界面_qt界面嵌入外部应用程序_初学小白Lu的博客-CSDN博客
Qt嵌入外部程序界面初探_qt嵌入其他程序窗口_liming4675的博客-CSDN博客
QT 如何把外部程序嵌入到QT界面_qt嵌入其他程序窗口_hellokandy的博客-CSDN博客
Qt界面程序中嵌入其他可执行exe程序_qt 把exe嵌入窗口_new_2018的博客-CSDN博客
Qt 嵌入第三方程序_qt 内嵌第三方程序_缘如风的博客-CSDN博客
QT中使用嵌入窗口_qt 嵌入窗口_blwinner的博客-CSDN博客
qt中父进程窗口嵌入子进程产生的窗口_tusong86的博客-CSDN博客
缺点就是:
- 依赖windows的原生api,因此别的平台,可能就无法实现了,例如mac上好像就不行了
- 需要先通过QProcess等方式打开该软件,然后进行嵌入,会导致被嵌软件闪烁一下,然后嵌进去,影响使用感。这个问题是无法解决的,就算QProcess启动后,立刻进行嵌入,也会闪现一下软件的
- 再拉伸外面软件时,被嵌软件出现锯齿状残留等现象,明显是有问题的
- 可能鼠标,或者键盘啥的,响应有奇奇怪怪的问题
总之,这样做,是不好用的,所以要么就是以分离软件的形式启动,让它独立运行,或者直接嵌入源码一起编译了(在两个软件都是自己开发的情况了,因为需要源码)。
mainwindow.h 文件
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class QProcess;
class WidgetScheulerAnalysis : public QMainWindow
{
Q_OBJECT
public:
explicit WidgetScheulerAnalysis(QWidget *parent = 0);
~WidgetScheulerAnalysis();
private slots:
void on_pushButton_clicked();
void on_processStarted();
private:
Ui::MainWindow *ui;
QProcess* m_process;
QWindow* m_window;
QWidget* m_widget;
};
#endif // MAINWINDOW_H
mainwindow.cpp 文件
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <Windows.h>
#include <QProcess>
#include <QWindow>
#include <QDebug>
#include <QDir>
#include <QMessageBox>
//自定义结构体
struct handle_data {
unsigned long process_id;
HWND best_handle;
};
BOOL IsMainWindow(HWND handle);
BOOL CALLBACK EnumWindowsCallback(HWND handle, LPARAM lParam);
HWND FindMainWindow(unsigned long process_id);//通过进程id号获取主窗口句柄
BOOL IsMainWindow(HWND handle)
{
return GetWindow(handle, GW_OWNER) == (HWND)0 && IsWindowVisible(handle);
}
BOOL CALLBACK EnumWindowsCallback(HWND handle, LPARAM lParam)
{
handle_data& data = *(handle_data*)lParam;
unsigned long process_id = 0;
GetWindowThreadProcessId(handle, &process_id);
if (data.process_id != process_id || !IsMainWindow(handle)) {
return TRUE;
}
data.best_handle = handle;
return FALSE;
}
//通过进程id号获取主窗口句柄
HWND FindMainWindow(unsigned long process_id)
{
handle_data data;
data.process_id = process_id;
data.best_handle = 0;
EnumWindows(EnumWindowsCallback, (LPARAM)&data);
return data.best_handle;
}
WidgetScheulerAnalysis::WidgetScheulerAnalysis(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
WidgetScheulerAnalysis::~WidgetScheulerAnalysis()
{
delete ui;
}
void WidgetScheulerAnalysis::on_pushButton_clicked()
{
#if 0
// QProcess *pro = new QProcess(this);
// pro->start("TaskSchedSimulatPlatform/TaskSchedSimulatPlatform.exe");
// QString Name = "TaskSchedSimulatPlatform";
//启动
QDir::setCurrent("C:\\windows\\system32");
QProcess *pro = new QProcess(this);
pro->start("notepad.exe");
// pro->waitForStarted();
// Sleep(10);
QString Name = "无标题 - 记事本";
// WId hwnd = (WId)FindWindow(L"MainWindow",(LPCTSTR)Name.unicode());
WId hwnd ;
while(1)
{
hwnd = (WId)FindWindow(L"Notepad",(LPCTSTR)Name.unicode());
if(hwnd != 0)
break;
}
qDebug()<<hwnd;
//嵌入
if (hwnd > 0)
{
QWindow *m_window;
m_window = QWindow::fromWinId(WId(hwnd));
QWidget *m_widget;
m_widget = QWidget::createWindowContainer(m_window,this);
ui->verticalLayout->addWidget(m_widget);
}
#endif
/*
*启动外部程序
*/
//QString cmd = "D:/Program Files/InnovMetric/PolyWorks MS 2021/bin/polyworks.exe";
//QString cmd = "D:/Program Files (x86)/Adobe/Reader 11.0/Reader/AcroRd32.exe";
//QString cmd = "D:/Program Files/MVS/MVS/Applications/Win64/MVS.exe";
QString exePath = "TaskSchedSimulatPlatform/TaskSchedSimulatPlatform.exe";
m_process = new QProcess(this);
connect(m_process, &QProcess::started, this, &WidgetScheulerAnalysis::on_processStarted);
m_process->setParent(this);
QStringList arg;
arg << "";
m_process->start(exePath, arg);//外部程序启动后,将随主程序的退出而退出
//m_process->start(exePath);//外部程序启动后,将随主程序的退出而退出
}
//嵌入外部程序
void WidgetScheulerAnalysis::on_processStarted()
{
qint64 id = m_process->processId();//如果程序没有运行,将会返回0
// while (1) {
// if(m_process->state() == QProcess::Running && id !=0)
// break;
// }
// if (id == 0)
// {
// QMessageBox::information(NULL, "提示", "程序没有启动");
// return;
// }
// Sleep(100);
qDebug() << "Status: " << m_process->state();
// HWND mainwindowHwnd = FindMainWindow(id);
HWND mainwindowHwnd;
while (1) {
mainwindowHwnd = FindMainWindow(id);
if(mainwindowHwnd)
break;
}
// qDebug() << "mainwindowHwnd: " << mainwindowHwnd;
// if (!mainwindowHwnd)
// return;
// while (1) {
// if(mainwindowHwnd != 0)
// break;
// }
QWindow *m_window;
m_window = QWindow::fromWinId(WId(mainwindowHwnd));
m_window->setFlags(m_window->flags() | Qt::CustomizeWindowHint | Qt::WindowTitleHint); //这边可以设置一下属性
QWidget *m_widget;
m_widget = QWidget::createWindowContainer(m_window,this);
ui->verticalLayout->addWidget(m_widget);
}