there 2 qapplications & b, can executed separately own main window.
i achieve following:
1) //open application b. //inside app b's code qprocess* proa = new qprocss(); proa->start(a.exe) //under windows7 2) //instead of showing app in separate window. //i show widget of app b's main window.
sort of google chrome. similar post here:qt how embed application qt widget talked similar problem. involves implement own window management system. there simpler solutions both app qt's qapp , both uses qwindow.
it's possible if 2 qapplication
s in different processed.
- create 2 process each it's
qapplication
,qwidget
- from 1 process, find winid of other processe's
qwidget
, reparent own widget.
to manage widget other process reparented yours, may use qtwinmigrate. meant embed mfc widget (with own cwinapp
) in qt widget, can embedding qwidget
separate process.
here piece of working code:
child process:
#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(); }
parent process:
#include <qmainwindow> #include <qapplication> #include <qmessagebox> #include <qvboxlayout> #include <qlabel> #include <qprocess> #include "windows.h" #include "qtwinmigrate5/qwinhost.h" #include <iostream> #include <sstream> /* 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 false stops 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 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 create child process"); return 1; } // create qtwinmigrate widget container: qwinhost* host = new qwinhost( &wnd ); // child process wiindow handle hwnd hchildwnd = null; int timeout = 20; while ((hchildwnd = (hwnd)getchildwindowhandle(process.processid())) == null) { // let child process more time create , show widget.... sleep(200); --timeout; if (timeout == 0) break; } int res = 1; if (hchildwnd != null) { // attach child window handle 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 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 find child process widget"); } // kill child process process.kill(); return res; }
1- compile child process executable named test_3rdparty_inprg_qtwinmigrate_child.exe
. 2- compile parent process executable 3- run parent process, 1 start child process, find it's top level widget window handle , insert within own qmainwindow
child. when done, kill child process.
as end user, it's hard tell widgets not part of same process, embedded (the red part of widget comes child process):