有两个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。
答案 0 :(得分:4)
如果两个QApplication
处理不同,那肯定是可能的。
QApplication
和QWidget
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(¢ralWidget);
QVBoxLayout* layout = new QVBoxLayout(¢ralWidget);
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(), ¢ralWidget ) );
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
。完成后,它将终止子进程。
作为最终用户,很难说小部件不是同一个过程的一部分,它们是完美嵌入的(小部件的红色部分来自子进程):
答案 1 :(得分:-1)
嗯,这就是整个QWidget
方法的想法:可以放入容器的所有内容都可以成为另一个应用程序的一部分。
然而,将完整的,未修改的Qt应用程序放入另一个应用程序将是不可能的:只能有一个QApplication
实例,并且只有一个全局事件循环。