10

In our project we have three independent applications, and we have to develop a QT control application that controls these three applications. The main window will be seperated to three sub windows - each one display another one application.
I thought to use QX11EmbedWidget and QX11EmbedContainer widgets, but two problems with that:

  1. The QX11Embed* is based on X11 protocol and I dont know if it's supported on non-x11 systems like Windows OS.
  2. Since QT 5 these classes are not existing, and the QT documentation doesn't mention why.

So that I dont know whether to use it or not - I'll be happy to get an answers.
In addition, I see that the QT 5.1 contains QWidget::createWindowContainer(); function that in some posts it looks like this should be the replacement to the X11Embed. Can anyone please explian me more how can I use this function to create a QT widget that will run another application (a Calculator for example) inside its?

I have searched a lot in Google, and didn't find answers to my Qs.
Can anyone please help me? Am I on the right way?
Thanks!

RRR
  • 3,937
  • 13
  • 51
  • 75

2 Answers2

9

If all three independent applications are written with Qt, and you have their source, you should be able to unify them just through the parenting of GUI objects in Qt.

http://qt-project.org/doc/qt-4.8/objecttrees.html

http://qt-project.org/doc/qt-4.8/widgets-and-layouts.html

http://qt-project.org/doc/qt-4.8/mainwindows-mdi.html

If you don't have access to them in that way, what you are talking about is like 3rd party window management. It is kind of like writing a shell, like Windows Explorer, that manipulates the state and the size of other window applications.

Use a program like Spy++ or AutoIt Spy for Windows and the similar ones for other OS's, and learn the identifying markings of your windows you want to control, like the class, the window title, etc. Or you can launch the exe yourself in a QProcess::startDetached() sort of thing.

http://qt-project.org/doc/qt-5.1/qtcore/qprocess.html#startDetached

Then using the OS dependent calls control the windows. The Qt library doesn't have this stuff built in for third party windows, only for ones under the QApplication that you launched. There are a lot of examples of doing things like this by AutoHotKey, or AHK. It is a scripting language that is made for automating a lot of things in the windows environment, and there is port for Mac as well (though I haven't tried the mac port myself).

So in the end you are looking at finding your window probably with a call like this:

#include <windows.h>

HWND hwnd_1 = ::FindWindow("Window_Class", "Window Name");
LONG retVal = GetWindowLongA(hwnd_1, GWL_STYLE); // to query the state of the window

Then manipulate the position and state of the window like so:

::MoveWindow(hwnd_1, x, y, width, height, TRUE);
::ShowWindow(hwnd_1, SW_SHOWMAXIMIZED);

You can even draw widgets on top of the windows you are controlling if you set your window flags correctly for the windows you are manipulating.

transparent QLabel with a pixmap

Cannot get QSystemTrayIcon to work correctly with activation reason

Some gotchas that come up in Windows when doing all of this, is finding out the quirks of the Windows UI when they set the Display scaling different from what you expect, and if you want to play nice with the Task bar, and handling all the modal windows of your programs you are manipulating.

So overall, it is do-able. Qt will make a nice interface for performing these commands, but in the end you are looking at a lot of work and debugging to get it in a beautiful, reliable, window manager.

Hope that helps.

Community
  • 1
  • 1
phyatt
  • 18,472
  • 5
  • 61
  • 80
  • 1
    First of all thank you answer me, I began to think that nobody could answer me. I dont have access to the source code. 2 Qs: what do you know about the QWidget::createWindowContainer(); function, may it do all the work? 2. if your solution is required a lot of porting to windows - maybe it's not worth - a nd the shorted solution is to write the app in .NET for windows and in I dont know for Linux-Ubuntu? – RRR Aug 27 '13 at 19:18
  • I haven't used `createWindowContainer` before. It looks like it is a shortcut to upgrading any sort of `QWindow`, like the scenegraph or the Qt Quick or a OpenGL window to have a full window decoration that works with other QWidgets. It doesn't look like it can just take any HWND id... http://blog.qt.digia.com/blog/2013/02/19/introducing-qwidgetcreatewindowcontainer/ – phyatt Aug 27 '13 at 19:35
  • Handling windows isn't too difficult. It does take research and work, but to be up and manipulating them in Windows shouldn't take more than a few hours. I haven't done it in Linux and OSX yet, but it should just be a matter of getting the right calls in place. – phyatt Aug 27 '13 at 19:40
  • Also if you do it in .NET correctly, you may be able to use their ports to do similar calls in other OS's. I haven't used .NET a lot, but it sounds like some people have done it for AHK. http://www.ironahk.net/ – phyatt Aug 27 '13 at 19:43
  • So looking at ironAHK, it still is a pretty young project. It may be able to do some of it, but there are a lot of `throw new NotImplementedException();` in it right now. It may be a good start to find examples to do the `C#` route. – phyatt Aug 27 '13 at 19:54
7

I never tried it myself, but from the docs in Qt 5.1 I would try QWindow::fromId(WId id), which gives you a QWindow, which should be embeddable with createWindowContainer:

QWindow * QWindow::fromWinId(WId id) [static] Creates a local representation of a window created by another process or by using native libraries below Qt.

Given the handle id to a native window, this method creates a QWindow object which can be used to represent the window when invoking methods like setParent() and setTransientParent(). This can be used, on platforms which support it, to embed a window inside a container or to make a window stick on top of a window created by another process.

But no guarantee. :-)

Greenflow
  • 3,935
  • 2
  • 17
  • 28