PDA

View Full Version : QT5.6 Howto load qml into QMainWindow derived userdefined Object



froeben
11th February 2016, 10:55
I am trying to embed a simple "Hello World" text qml into a QMainWindow derived userdefined object.
In any possible idea that i tested, the text does not show up.

This is my object constructor code:

MainWindow::MainWindow() : QMainWindow ()
{
this->resize(1024, 768);

QWidget *topFiller = new QWidget;
topFiller->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

QWidget *bottomFiller = new QWidget;
bottomFiller->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

QVBoxLayout *layout = new QVBoxLayout;

layout->setMargin(5);
layout->addWidget(topFiller);
layout->addWidget(bottomFiller);
this->setLayout(layout);

createActions();
createMenus();

QQmlEngine engine(this);
QQmlComponent component(&engine, QUrl::fromLocalFile("D:\\test.qml"),this);


This is my main app code:


int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow mw;
mw.show();

return a.exec();
}


This ist the QML file:


import QtQuick 2.0

Text {
text: "Hello world!" //a basic greeting
/*
We want this text to stand out from the rest so
we give it a large size and different font.
*/
font.family: "Helvetica"
font.pointSize: 24
}

anda_skoa
11th February 2016, 13:15
Couple of things:

1) QMainWindow has a layout by default, if you need to add content you create a widget and set it as the main window's centralWidget

2) You are loading the QML file into the QQmlComponent but you never create an object.

3) The root element of your QML file is a QQuickItem. A QQuickItem is not a widget.

Cheers,
_

froeben
11th February 2016, 13:55
Thanks for the input!
Could you explain more detailed the third remark?

3) The root element of your QML file is a QQuickItem. A QQuickItem is not a widget.

Is it possible to add a QQuickItem to a widget?

Kind regards,
Frank

anda_skoa
11th February 2016, 16:11
The easiest way to embed a QtQuick scene into a widget is to use QQuickWidget.

Cheers,
_

froeben
12th February 2016, 14:27
So, after one and a half day, i found 2 possible solutions that work which i would like to share with other newbies:


MainWindow::MainWindow() : QMainWindow ()
{
// embed resources into binary
// infos: http://doc.qt.io/qt-5/resources.html
Q_INIT_RESOURCE(qmlsources);

this->resize(1024, 768);

QWidget *topFiller = new QWidget;
topFiller->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

QWidget *bottomFiller = new QWidget;
bottomFiller->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

QVBoxLayout *layout = new QVBoxLayout;

layout->setMargin(5);
layout->addWidget(topFiller);
//layout->addWidget(_infoLabel);
layout->addWidget(bottomFiller);
//this->setLayout(layout);

createActions();
createMenus();

//WORKS!!!
// uses QQmlEngine and QQuickWidget
QQmlEngine *engine = new QQmlEngine(this);
QQuickWidget *view = new QQuickWidget(engine, this);

view->setSource(QUrl("qrc:/test.qml"));
this->setCentralWidget(view);

/* //WORKS!!!
// uses QQuickView and QWidget
QQuickView *view = new QQuickView(QUrl("qrc:/test.qml"));
QWidget *container = QWidget::createWindowContainer(view);
this->setCentralWidget(container);
*/
}


Since this is a library, you have to embed the qml-file in the resources otherwise the application will not find you qml-file since it is located in the directory tree of the library.

To be honest, the information are described in the documentation but hard to understand since the examples only show snippets of the code.

anda_skoa
12th February 2016, 15:45
If you intend this to be useful for others, you should probably clean it up :)

There is lots of unneccessary code, e.g. the filler widgets and layout.

Also you don't have to create an QQmlEngine for QQuickWidget, it can do that itself just like QQuickView.

I am also unsure what you mean with your statement regarding resources.
Q_INIT_RESOURCE is only necessary if the resource is in a static library.

Cheers,
_