New to Qt - Need to reparent external window into Qt form
Hi, I am VERY new to Qt, I am coming from the windows world and am starting on my first linux app.
I am writing a CAR PC frontend for a setup I am building. It will be running under raspbian on a rPI 3.
I started playing around a few weeks ago and have been able to make some decent progress so far.
One thing I need to be able to do however is to reparent a window into my app. I get the impression that it can be done from reading around on Google, but I can't come anywhere near making it work. My last attempt ended up causing X to hang...
So basically what I am after is this, my app will be running true full screen, but there are some external apps that I would like to be able to start and then embed them into my window, or more specifically, a widget in my window. So if I want to say launch NavIT and pop that window in for naviagtion, or a browser window, or VLC/mPlayer, etc etc...
On Windows, not a big deal at all, have done it many times, but for the life of me, I cannot seem to make it work, or even approach working in Qt under X...
I am working in Qt Creator, so I have got my main form layout setup, have some buttons and sliders and such spaced around an area in the middle for the main content. I am wanting to design it to be in a way a tab interface... Some widget (a panel on the .NET framework) to host either an external window, or another form( or widget layout) in it as you select through the different options of the app. IE, hit the nav tab, and it launches and rewindows NAVIT, or you go to video and play something, it launches mplayer or VLC and rewindows it into this.
My gut tells me that I need to be using just a QWidget as the host container and switch out it's contents... That said, I am starting to suspect that Qt doesn't work that way.
So, question one is this, will I be able to put a QWidget out on my window and then load different either external windows or my own layout/widget sets into and out of it as I need to switch between the functions of my app?
Question two, can anyone point me in the right direction on what I need to do to actually reparent the window into my widget?
I have tried a number of things I have seen in various posts, but so far haven't been able to get it to work. I either get no window, a regular external window or crash the window system.
As it stands I am starting the external process with QProcess...
My test app for trying to get this figured out has a button and a qwidget both created in the designer on the window. You hit the button, it starts the process, and then hopefully rewindows the external process.
On windows I would just change the parent of the window in question. But, for starters, I am at a loss as how to get a window ID of the process I am starting, and secondly, I am getting the impression that I can't just tell it to reparent into my QWidget, is that correct?
Also, strangely enough, whenever I call WinID() on my QWidget, it's crashing SIGSEV...
Any help would be great!
Hi, welcome to the Qt forum!
QWindow *QWindow::fromWinId(WId id) [static]
QWidget *QWidget::createWindowContainer(QWindow *window, QWidget *parent = Q_NULLPTR, Qt::WindowFlags flags = Qt::WindowFlags()) [static]
auto *window_of_external_application = QWindow::fromWinId(window_id); Q_ASSERT(window_of_external_application); auto *widget = QWidget::createWindowContainer(window_of_external_application);
BTW: Why would you want to do that? We have software to manage windows of multiple applications simultaneously, it's called "desktop environment". This will result in a horribly inconsistent GUI.
I'm also a newcomer to Qt but learning from this forum.
Reading your post I wonder if you could benefit from using a useful automation tool found here to prototype your application. http://www.actionaz.org
In fact Actionaz is a Qt developed application (a bit like AutoKey). I've downloaded the Actionaz source and rebuilt using Qt Creator. But you can use the binary download as it is.
Then you can launch external applications / processes from a common window.
Of course you can learn to build all this in Qt Creator / Designer in the conventional way. But personally I find that it sometimes helps to build a "strawman" prototype to quickly test the workflow for integrating external apps/processes/assets into a final Qt layout as you seem to be doing.
Just an idea. My development is in Ubuntu - not Windows - but Actionaz runs on Linux/windows.
I did at least figure out why I was getting SEGFAULTS trying to do stuff... Spent too much time in C# and keep forgetting my C++ accessors and scope.
@Wieland Thanks, if I can get everything working on QT5 I will give it a try, get TONS of import errors when I try to just switch out to QT5 from 4 in the build settings...
As to why I would want to do this... As far as I have ever seen, there's not really a GREAT touch optimized desktop environment for Linux... I have never seen one anyway... And I hear you, it could end up with a really bad GUI if not addressed properly, and even then still might not be what I want... But, going to give it a try and see what I can do. Basically I'm really just wrapping basic (or mostly basic) functionality into a more touch friendly GUI, bigger buttons better spacing, that kind of thing. ANY standard desktop interface is almost unusable at high resolution on a touch screen, especially from any kind of distance...
If I can get it working, I probably wont even bother launching a normal window manager, will just kick off X and my app and let it go at that.
@eureka Thanks, I will check it out...
Hi and welcome to devnet,
I suspect that your application makes use of widgets and that you are missing
QT += widgetsin your .pro file. Widgets have been moved in their own module in Qt 5.
As for getting a friendly touch based desktop environment. KDE's Plasma might be of interest.
Ok, so I managed to get everything worked out against 4.8, got the window embedding and it looks great!
So, I decided to give it a shot under 5.7, so I started up a new project and got it ready.
So here's the weird thing I cannot figure out... When I pull the window in using fromWinId and createWindowContainer by default it just stick a fully decorated window over the top of the spot where the widget I want to put it into sits... But I can move them around independently of each other. The best I can do is to get it to make a borderless window above my window, but not actually embed it in...
In 4.8 using X11EmbedContainer I can get it truly embedded in my window, so what do I need to do in 5.7 to get the same kind of thing with the fromWinID and createWindowContainer?
@aBs0lut30 I spent a long time trying to do the same thing. From everything I've read, (which is substantial amount at this point), it was possible in Qt4, but Qt5 broke the way a widget could integrate an external window from a window id. We were able to partially get it working in Qt5, but it never fully worked the way it did in Qt4.