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