Category Archives: Qt

Problem with #define from other libraries

While building a qt project with libxdo xdo.h I faced some strange problems with qt enum names conflicting with X #define macros.

There is no standard way of including headers the one which works is the best. For Qt I think it is recommended to include qt headers first then your files and other library files. This worked for me. To begin with I started to do #undef before include for each terms which was getting really bad as there were many conflicts.

 

 

undefined reference to `xdo_new(char*)’

Inline with xdo.h I was including it in C++ project. libxdo is C project and it doesn’t have extern “C” declaration as other libraries have.

 

extern "C" {
#include <xdo.h>
}

 

 

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();
}