QT打开外部程序并嵌入Qt子窗口的缺点

首先可以参考如下文章:

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博客

缺点就是:

  1. 依赖windows的原生api,因此别的平台,可能就无法实现了,例如mac上好像就不行了
  2. 需要先通过QProcess等方式打开该软件,然后进行嵌入,会导致被嵌软件闪烁一下,然后嵌进去,影响使用感。这个问题是无法解决的,就算QProcess启动后,立刻进行嵌入,也会闪现一下软件的
  3. 再拉伸外面软件时,被嵌软件出现锯齿状残留等现象,明显是有问题的
  4. 可能鼠标,或者键盘啥的,响应有奇奇怪怪的问题

总之,这样做,是不好用的,所以要么就是以分离软件的形式启动,让它独立运行,或者直接嵌入源码一起编译了(在两个软件都是自己开发的情况了,因为需要源码)。

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);

}








猜你喜欢

转载自blog.csdn.net/kangkanglhb88008/article/details/129273376
今日推荐