0

I am using Qt 5.7 & unit testing using gtest or as its called googletests.

I have a function to test which intakes a QQuickItem. To test this, I want to create a QQuickItem on fly when my unit test in run. Is it possible?

Note that I do have access to QQmlApplicationEngine or the any qml files like main.qml. However I should be able to create a dummy.qml in the resources of my tests project ?
I also thinking that doing a #include <QQmlApplicationEngine> should give me access to QQmlApplicationEngine ?

How do I create dummy QQuickItem in C++ code with some valid width & height in my unit test, & pass it to my method at runtime?

TheWaterProgrammer
  • 7,055
  • 12
  • 70
  • 159
  • You will still be using QML, just that instead of a stand-alone file you'll pass the QML script directly to the engine, as a `QString`. – Kuba hasn't forgotten Monica Aug 11 '17 at 18:21
  • @KubaOber - I don't think this is an option from C++. There are additional requirements for visible objects, including `QQuickItem` which doesn't have any default graphical representation but is a visible item nonetheless - you have to `setParentItem(someVisualItemPointer)`. – dtech Aug 11 '17 at 18:29
  • Note that there is `void QQmlComponent::setData(const QByteArray &data, const QUrl &url)` which you can use to create a qml component out of a source string. – dtech Aug 11 '17 at 18:32
  • There's no way to use QML without, well, using QML. Instantiating any QML objects from C++ requires passing QML that instantiates those objects to the QML engine. The QML script can be generated at runtime if you wish so, of course. There's this sorry idea that somehow if only you could "instantiate" a QML object from C++ using `new`, things would be peachy. Alas, just think about it: such objects would be typically useless as there's no C++ APIs to do anything useful with them - you can't set bindings, you can't access all of the QML properties, etc. You want QML, you have to use it! – Kuba hasn't forgotten Monica Aug 11 '17 at 18:38
  • Yeah, I have been a pretty vocal opponent of doing anything QML from C++. It only "makes sense" if you don't know what you are doing. – dtech Aug 11 '17 at 18:50
  • There is however the `setContextForObject()` function and the question what is its purpose. I mean the "traditional means" to create a QML object from C++ all set the context, even if you don't pass a context, the root context will be used. And setting a context works only if you don't have a context, and it is a public API function, so presumably there might be some way to create an object and have it associated with the engine. – dtech Aug 11 '17 at 18:53
  • there is no way to `qml_engine->load(QUrl(QStringLiteral("qrc:/dummy.qml"))` & get valid view? or some kind temporary view that lives only within my test function? – TheWaterProgrammer Aug 11 '17 at 19:09
  • You will have an isolated qml engine with that single QML file loaded in it, not very useful IMO, but if that's what you want, it is perfectly doable. However, if you use `QQmlApplicationEngine ` your root will have to be an `ApplicationWindow`. Maybe try with `QQuickView` instead, they you can have any qml tyle as a root. – dtech Aug 11 '17 at 19:13
  • @dtech is there a sample you can point me too or an answer ? any-way is fine for me. just need a valid `qquickitem` in my unit-test function. – TheWaterProgrammer Aug 11 '17 at 19:15
  • `QQuickItem *dummy_view = qml_engine->rootObjects()[0]->findChild("DummyViewObject")` - Using this complains `item is not attached to a window`. Can provide it a window on the fly ? – TheWaterProgrammer Aug 11 '17 at 19:24

1 Answers1

3

The easiest way to have an isolated QQuickItem object for testing would be to use a QQuickView:

QQuickView * view = new QQuickView;
view->setSource(QUrl(QStringLiteral("qrc:/dummy.qml")));
QQuickItem * dummyItem = view->rootObject();

Due to popular demand:

// dummy.qml
import QtQuick 2.0

Item {
  width: 200
  height: 200
}
dtech
  • 47,916
  • 17
  • 112
  • 190