Tag Archives: Qt

Running application just with X11

I have ubuntu core on my system without any UI just the bare bone minimum ubuntu core. I want the system to run some qt application nothing else.

There was two ways to it either I can take the Ubuntu mate and remove useless stuff and make my process run at startup with auto-login or to use bare bone ubuntu core and then just add the things needed to run my application.

Actually I would not have needed anything else for qt application and just used –platform linuxfb flag to run the Qt app with gun on the frame buffer. I actually did that but the problem was frame buffer approach was too slow I can actually see the screen restoring from top to bottom and for my application there was some times where screen was updated quite frequently. So I needed some other windowing system library like Wayland or X11 to handle the slow Frame buffer approach.

I chose X11 first and with some hiccups I made it work woohoo!!

You just need to install xorg and then use startx. I have put this in startup script inside /etc/init.d I will cover application starting at boot up in some other post.

apt-get install  libqt5declarative5  
# for my qt application this will install qt5-default and other qt related dependencies

It was quite a great learning and good experience to make everything work. Now the ubuntu core boots with my splash and starts all three of my qt apps with Gui and works well. It is very fast and no extra processes consuming my processor or hogging the system’s RAM. No window manager no session manager no desktop manager.

You can start any application simply by

startx application_name
[\code]

Advertisements

Qt: Sending a window on top from another application

The problem statement was very simple. I had two applications in Qt say A and B both were communicating with Qt shared memory(very useful feature and easy to use also). Okay so two applications in Qt and what I wanted to do was on some trigger from application A, I want to send a window created in application B on top.

In other words:

Let us say you have two qt application on click of a button on one application window you want to bring the other application window on top. You can use any method of IPC between these two applications.

Solution:

Isn’t this a very simple problem? There is a catch
In windows above is not possible directly with qt. You can bang your head with all feature of qt to send a window on top. Give it focus make it active but to no avail. The window will remain on back.

You need to have a hack around to make this possible.

One peculiar observation was on the first try window was not coming on front but in next all try it comes in the front. So you can open close the window fast for the first time and going forward you have resolved the problem.

There are some other workaround mentioned on qt forum but it didn’t worked for me. I tried with registry setting but didn’t wanted to restart the system so not sure whether it works or not.

activate qt window


// HACK: bringing window to top
// from QT documentation:
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// void QWidget::activateWindow ()
// ...
// On Windows, if you are calling this when the application is not currently
// the active one then it will not make it the active window. It will change
// the color of the taskbar entry to indicate that the window has changed in
// some way. This is because Microsoft do not allow an application to
// interrupt what the user is currently doing in another application.
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 

My hack was very simple by using windows API to bring a window on top

 

SetWindowPos((HWND)viewer->winId(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);

 

Giving it focus is still not working for me for my particular application so I have to try the first hack also opening and closing the window fast. You can make this a very small window and put it in some weird position so no one can notice. Also this is needed only once so you can do it when your second application starts(whose window you want to bring in front from another app trigger).

 

Qt and it’s bug

Sometime you spend hours just to realize it is not you who is using the platform incorrectly but the platform itself is released with some limitation. Sometime the limitations doesn’t make any sense.

So I wanted to have menu like options in my application with qt. The options you see in almost all applications on top => File, Edit, Settings, Help etc when you click on it you see a list of sub-options.

As expected it is very simple to do it in Qt. It is widely used feature isn’t it?

menuBar: MenuBar {
Menu {
title: qsTr("&File")
MenuItem { text: qsTr("Hide"); onTriggered: windowClosing() }
MenuItem { text: qsTr("Exit"); onTriggered: mainwindow.exitApp() }

.. ..

I was using Qt5.5.1 with qml I made the menus add listeners everything seemed fine. Then I realized that I can’t click and select the sub-options by using touch screen(means touch) on windows with mouse it is okay but not with touch. It was like 3-4 hours of effort to do everything to realize that it is useless. I even updated my qt version to latest.

I searched and searched may be I was doing something wrong, no it is a known problem.

Menu bar doesn’t work with touch qt

I wasn’t going to stop using the menu feature and make buttons and windows for all these options now. I have added extra options just because I have it all so simple. I have added all these features in my application.

I was searching for workaround and there was one with QMenuBar it isn’t a workaround per say a different way of doing same thing with Qt and QMenuBar doesn’t have this bug. Now I just have to remove all my qml code and do things with Qwidgets etc which is again pain lots of code changes.

There is another way to handle all this using ‘createWindowContainer’  a sweet useful feature to create a parent widget with your existing qml window. You will get handle of the parent window widget which has your qml window contained inside it. It was such a saver for me.

QWidget *container = QWidget::createWindowContainer(qmlWindow, myWidget);

I created a widget class by inheriting Widget to add some extra features like I do not wanted to close the application when window close is clicked.

Some part of the code just to make things clear:

QWindow *qmlWindow = qobject_cast(this->rootObjects().first());

MyWidget* myWidget = new MyWidget();
QWidget *container = QWidget::createWindowContainer(qmlWindow, myWidget);
container->setMinimumSize(qmlWindow->size());
widget = new MyWidget();
QGridLayout *grid = new QGridLayout(widget);
grid->addWidget(container,0,0);
widget->show();

createActions();

menuBar = new QMenuBar();
createMenus();
widget->layout()->setMenuBar(menuBar);
showWindow();
connect(widget, SIGNAL(closeWindow(QCloseEvent*)), this, SLOT(onClosing()));
connect(myWidget, SIGNAL(closeWindow(QCloseEvent*)), this, SLOT(onClosing()));

First you get the qmlwindow handle using which you created the container window widget

actually there was one problem where I spent some extra time just to figure out that I can pass parent widget in createWindowContainer(qmlWindow); function and get my inherited widget work with it. createWindowContainer is a static function but luckily or intelligently they have given this option to pass a parent widget in it to make inheritance work.

createMenu and creatActions are functions to create all my menu and listener stuff.

Here is my special widget class inherited from QWidget

#include "mywidget.h"

MyWidget::MyWidget():QWidget()
{

}

void MyWidget::closeEvent(QCloseEvent *event)
{
emit closeWindow(event);
event->ignore();
}