Pong

August 28th 2014, Declarative Camera

August 27th 2014 Valgrind | | August 29th 2014 Declarative Camera Improvements

If we would like to extend our Android app with a camera module, the “declarative-camera” example is a good starting point. Beware of the regular C++ camera example which will work up to Qt 5.2 but not on Qt 5.3 (it is unclear if this is going to be fixed for Qt 5.4).

When going declarative, there are basically three options:

  • Write a pure declarative Qt Quick application
  • Mix a Qt Quick application with C++ QObject-based Widgets
  • Embed QML based QWidgets into a C++ application.

The “declarative-camera” example is using the first approach:

It creates a QQuickView object which owns a QQMLEngine that interpretes the declarative qml source code and is able to provide signals and slots from within the QML scene to the C++ level:

#include <QGuiApplication>
#include <QQuickView>
#include <QQmlEngine>

int main(int argc, char* argv[])
{
   QGuiApplication app(argc,argv);

   QQuickView view;
   QObject::connect(view.engine(), SIGNAL(quit()), qApp, SLOT(quit()));

   view.setSource(QUrl("qrc:///declarative-camera.qml"));
   view.show();

   return(app.exec());
}

For the second approach, see here:

Using the third approach on Qt4, we create a custom QDeclarativeView-based class, which derives from QWidget and contains a QML engine. Here is a stripped down example that creates a custom C++ widget based on some declarative qml code:

class Camera: public QDeclarativeView
{
   QOBJECT

public:

   Camera(QWidget *parent = NULL)
      : QDeclarativeView(parent)
   {
      setSource(QUrl("qrc:///code.qml"));
      show();

      connect(rootObject(), SIGNAL(quit()), this, SLOT(quit()));
   }

};

More info on that topic:

Using the third approach on Qt5, we embed a QQuickView in a QWidget by using the QWidget::createWindowContainer (as a replacement for the outdated Qt4 QDeclarativeView), like so:

More info on that topic:

With Qt 5.3 the class QQuickWidget is a convenience wrapper for the above approach. It creates a render buffer and places a QQuickWindow in it to be displayed inside the widget’s view area. Typical usage:

QQuickWidget *view = new QQuickWidget;
view->setSource(QUrl::fromLocalFile("code.qml"));
view->show();

QQuickWidget manages sizing of the view and root object. By default, the resizeMode is SizeViewToRootObject, which will load the component and resize it to the size of the view. Alternatively the resizeMode may be set to SizeRootObjectToView which will resize the view to the size of the root object.

I did not try the above approach yet. Instead, I created an regular instance of a QQuickView with Qt 5.3 and let the declarative camera run in full-screen mode in that view. This full-screen view is displayed on the entire Android screen on its own surface view. When mixing a Qt Quick ui with a native QWidget ui, the Qt Quick application is displayed in its own view surface below the widget’s surface view, which means that the camera is running all the time but it is in fact invisible, because it is occluded by the top level widget.

To account for that we need to hide the top level window, when we would like to get access to the camera. When the camera emits the quit signal we need to show the top level widget again.

Here is a screen shot of the full-screen declarative camera with a hidden top level widget on my LG smart phone:


August 27th 2014 Valgrind | | August 29th 2014 Declarative Camera Improvements

Options: