gpt4 book ai didi

c++ - 如何将一个 qApplication 的 GUI 嵌入到另一个 qApplication 的主窗口中?

转载 作者:搜寻专家 更新时间:2023-10-31 01:35:18 24 4
gpt4 key购买 nike

有两个qApplications A & B,它们可以在各自的主窗口中分别执行。

我想实现以下目标:

1) //Open Application B.

//Inside App B's code
QProcess* proA = new QProcss();
proA->start(A.exe) //Under Windows7

2) //Instead of showing app A in a separate window.
//I would like to show it as a widget of app B's main window.

有点像谷歌浏览器。这里有一个类似的帖子:QT How to embed an application into QT widget谈到了类似的问题。但它涉及实现您自己的窗口管理系统。是否有更简单的解决方案,因为我的应用程序都是 Qt 的 qApp 并且都使用 QWindow。

最佳答案

如果两个 QApplication 在不同的进程中,那肯定是有可能的。

  • 创建两个进程,每个进程都有 QApplicationQWidget
  • 从一个进程中,找到另一个进程的 QWidget 的 winId,并将其重新设置为您自己的小部件。

要从其他进程管理小部件到你的,你可以使用 qtwinmigrate .最初这是为了在 Qt 小部件中嵌入一个 MFC 小部件(带有它自己的 CWinApp),但它也可以帮助从一个单独的进程中嵌入一个 QWidget

这是一段工作代码:

子进程:

#include <QLabel>
#include <QWidget>
#include <QVBoxLayout>
#include <QApplication>

#include <sstream>

int main(int argc, char **argv)
{
QApplication app(argc,argv);
QWidget widget;
widget.setWindowTitle( "CHILD WINDOW" );

std::stringstream str;
str << "QWidget ID: " << widget.winId() << std::endl;
str << "Process Name: " << argv[0];

Qt::WindowFlags flags = widget.windowFlags();
flags |= Qt::FramelessWindowHint;
flags |= Qt::MSWindowsFixedSizeDialogHint;
flags |= Qt::SubWindow;
widget.setWindowFlags( flags );

widget.setLayout(new QVBoxLayout(&widget));
QLabel label;
widget.layout()->addWidget(&label);
label.setText(str.str().c_str());

widget.setStyleSheet( "background: red" );

widget.show();

QEvent e(QEvent::EmbeddingControl);
QApplication::sendEvent(&label, &e);

app.processEvents();

return app.exec();
}

父进程:

#include <QMainWindow>
#include <QApplication>
#include <QMessageBox>
#include <QVBoxLayout>
#include <QLabel>
#include <QProcess>

#include "windows.h"
#include "qtwinmigrate5/qwinhost.h"

#include <iostream>
#include <sstream>

/* The EnumChildProc callback */

static HWND hWndHandle = NULL;
static qint64 childProcessID = 0;
BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam)
{
DWORD dwProcessID = 0;
if (GetWindowThreadProcessId(hwnd, &dwProcessID) &&
dwProcessID == childProcessID )
{
char strTemp[256] = "";
GetWindowText(hwnd, strTemp, 256);
std::string str = strTemp;
if (str == "CHILD WINDOW") // sanity check
hWndHandle = hwnd;
}

return ( hWndHandle == NULL ); // must return TRUE; If return is FALSE it stops the recursion
}

void* GetChildWindowHandle( qint64 pid )
{
hWndHandle = NULL;
childProcessID = pid;

EnumWindows(EnumChildProc, 0);

return hWndHandle;
}

int main(int argc, char **argv)
{
QApplication app(argc,argv);
QMainWindow wnd;
wnd.setWindowTitle("That's the parent window!");

// Create child process:
QProcess process;
process.start("test_3rdparty_inprg_qtwinmigrate_child.exe");
if (process.state() != QProcess::Running)
{
QMessageBox::critical(NULL, "ERROR", "Unable to create child process");
return 1;
}

// Create qtwinmigrate widget container:
QWinHost* host = new QWinHost( &wnd );

// Get child process wiindow handle
HWND hChildWnd = NULL;
int timeout = 20;
while ((hChildWnd = (HWND)GetChildWindowHandle(process.processId())) == NULL)
{
// let child process more time to create and show its widget....
Sleep(200);
--timeout;
if (timeout == 0)
break;
}

int res = 1;
if (hChildWnd != NULL)
{
// attach child window handle to qtwinmigrate widget container
host->setWindow(hChildWnd);

char strTemp[256] = "";
GetWindowText(hChildWnd, strTemp, 256);

QWidget centralWidget(&wnd);
wnd.setCentralWidget(&centralWidget);

QVBoxLayout* layout = new QVBoxLayout(&centralWidget);

std::stringstream str;
str << "Attached data window " << std::showbase << std::hex << hChildWnd << std::endl;
str << "Window title: " << strTemp << std::endl;
str << "Widget below runs in a separate process:" << std::endl;

layout->addWidget( new QLabel( str.str().c_str(), &centralWidget ) );
layout->addWidget(host);

wnd.resize(400, 200);

wnd.show();

res = app.exec();
}
else
{
QMessageBox::critical(NULL, "ERROR", "Unable to find child process widget");
}

// kill child process
process.kill();

return res;
}

1- 将子进程编译成名为 test_3rdparty_inprg_qtwinmigrate_child.exe 的可执行文件。 2-将父进程编译成可执行文件 3- 运行父进程,这个进程将启动子进程,找到它的顶级小部件窗口句柄并将其作为子进程插入到它自己的 QMainWindow 中。完成后,它将终止子进程。

作为最终用户,很难分辨这些小部件不是同一进程的一部分,它们是完美嵌入的(小部件的红色部分来自子进程):

enter image description here

关于c++ - 如何将一个 qApplication 的 GUI 嵌入到另一个 qApplication 的主窗口中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37665389/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com