Pong

October 20th 2014, Qt 5.4 Beta Testing

Here is a wrapup of my experiences with the new Qt 5.4.0 beta release:

EDIT: Note that Qt 5.5 is out, which solves most problems of qt 5.4 as described on this page. For more info see the Qt 5.5 post.

For a list of known issues with the prior Qt 5.3.1 Android release see here:

The following issues persist with Qt 5.4.0/Android:

• QML camera crashing in destructor
• EDIT: It is unsafe to delete QObjects in a slot while being signalled from the very same (or parent) object. In such a case one should not use the C++ delete function, but one should use Qt’s deleteLater() method.
• QML torch component broken (error connecting to missing slot)
• QML MetaDataDirectory is not exported to captured photos as EXIF tags (as opposed to Linux)

The following issues have been fixed with Qt 5.4.0/Android:

• QML video capture does no longer lock up the camera when capturing a second movie.
• QQuickWidget support is working
• QWebView support seems to be working
• QNetworkConfigurationManager no longer reports WLAN configuration as Ethernet on Android (and Mobile configuration as Unknown)

The following issues are new with Qt 5.4.0/Android:

• QQuickWidget’s visibility is not always correct
• There are lots of Java property parsing warnings on startup
• EDIT: persist with Qt-5.4.0rc
• EDIT: persist with Qt-5.4.1 snapshots
• QML Camera does not focus upon camera.searchAndLock
• EDIT: The problem persists with Qt-5.4.0rc
• EDIT 01/07/2015: The problem was not introduced with Qt-5.4.0 beta, but already with Qt-5.3.2. The latest Qt version with a working QML camera module on Android is Qt-5.3.1. Unfortunately, at least Qt-5.3.2 is required to produce signed APKs. This means that there is currently no Qt version at all, which allows to publish a Qt camera app on Google Play.
• EDIT 02/12/2015: The problem appears to be fixed on 11/28/14 but did not make it into the Qt 5.4.0 release branch as of 08/11/14. In the upcoming Qt 5.4.1 snapshots the fix should be merged.
• EDIT 02/17/2015: After testing the proposed fix, the problem was not solved, unfortunately!
• EDIT 03/17/2015: The fix is scheduled for the Qt-5.5 release.

The following test case illustrates the problem:

camtest.pro:

#-------------------------------------------------
#
# Project created by QtCreator 2014-10-20T08:54:47
#
#-------------------------------------------------

QT       += core gui quick quickwidgets multimedia

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = camtest
TEMPLATE = app

SOURCES += main.cpp\
mainwindow.cpp

CONFIG += mobility
MOBILITY =

OTHER_FILES +=

RESOURCES += \
declarative-camera.qrc


main.cpp:

#include "mainwindow.h"
#include <QApplication>

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

return a.exec();
}

mainwindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QtWidgets>
#include <QQuickWidget>
#include <QQmlEngine>

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
MainWindow(QWidget *parent = 0);
~MainWindow();

protected:

QQuickWidget *cam_;

protected slots:

void camStatusChanged(QQuickWidget::Status status);

void start();
void stop();
};

#endif // MAINWINDOW_H

mainwindow.cpp:

#include "mainwindow.h"

#define VISIBILITY_BUG 1

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), cam_(NULL)
{
QTabWidget *tab = new QTabWidget;

QPushButton *button1 = new QPushButton("Start Cam");
connect(button1, SIGNAL(pressed()), this, SLOT(start()));

QPushButton *button2 = new QPushButton("Quit");
connect(button2, SIGNAL(pressed()), this, SLOT(close()));

setCentralWidget(tab);
}

MainWindow::~MainWindow()
{
stop();
}

void MainWindow::start()
{
if (!cam_)
{
cam_ = new QQuickWidget();

connect(cam_, SIGNAL(statusChanged(QQuickWidget::Status)),
this, SLOT(camStatusChanged(QQuickWidget::Status)));

cam_->setSource(QUrl("qrc:///declarative-camera.qml"));
cam_->setResizeMode(QQuickWidget::SizeRootObjectToView);
}
}

void MainWindow::camStatusChanged(QQuickWidget::Status status)
{
{
connect(cam_->engine(), SIGNAL(quit()),
this, SLOT(stop()));

cam_->show();
cam_->raise();

#ifdef VISIBILITY_BUG
hide();
#endif
}
}

void MainWindow::stop()
{
if (cam_)
{
cam_->hide();
cam_->lower();

#ifdef VISIBILITY_BUG
show();
#endif

cam_->deleteLater(); // note that one cannot use delete
cam_ = NULL;
}
}

declarative-camera.qml:

import QtQuick 2.0
import QtMultimedia 5.3

Rectangle {
width: 800
height: 480

focus: true // to get key events
Keys.onReleased: {
if (event.key == Qt.Key_Back) {
event.accepted = true
Qt.quit()
}
}

Camera {
id: camera
videoRecorder {
resolution: "640x480"
frameRate: 30
}
}

VideoOutput {
anchors.fill: parent
source: camera
autoOrientation: true

MouseArea {
anchors.fill: parent;
onClicked: camera.searchAndLock()
onDoubleClicked: camera.imageCapture.capture()
}
}
}

The test case as zip archive: camtest.zip

Here is a description of what is going wrong with the above test case:

EDIT: The visibility problem has been fixed in the latest snapshots of Qt-5.4.1!

1) After starting the above app with Qt 5.4.0rc on Android (in my case on a LG L7II), I press the start button. When the cam has started I do no see it, because it is buried under the main widget although it is set to be hidden, for VISIBILITY_BUG being 1. If I change VISIBILITY_BUG to 0, which means that the QWidget surface is not hidden, everything is fine.

That the cam is actually running can be seen when pressing the Android home button and returning to the app. Then the camera’s view finder is visible as it should be:

I can also see the cam running when turning the phone vertically. Then it lurks through on the right side but the left side is still occluded. See this screen shot:

2) Now I press the Android back button, which triggers a Qt.quit signal that is routed from the camera to a slot which closes the quickwidget. The first time I do that, the app does not react. It will only react, if the QQuickSurface is touched at least a single time.

3) Starting with Qt5.4.0rc the new Android native look is broken for QTabWidget and QScrollArea. The tab titles and scroll bars appear black on black. This did not show for Qt-5.4.0beta.

• EDIT: Fixed as of 12/5/2014.

4) Side note: If the QQuickWidget object would be deleted instead of calling its deletedAfter() method, after the back button was pressed, the app would crash, because it is unsafe to do this in a slot which is being called from the object that is going to be deleted.

Also see the following bug reports:

EDIT: As of 11/26/2014 there is a patch available, which appears to fix some visibility problems:

Checking the issue with Qt-5.4.0rc reveals that the visibility issue as described above has not been fixed. The broken QML camera focus persists, also!

EDIT: As of 12/5/2014 there is a patch available, which fixes the broken QWidget style on Android.

EDIT As of 02/12/2015 the Qt 5.4.1 snapshots contain a proposed fix for the broken camera focus, e.g. the following snapshot contains the proposed fix:

EDIT As of 02/17/2015 the proposed fix does not solve the broken camera focus!

EDIT As of 02/17/2015 the visibility issue has been solved with the latest Qt-5.4.1 snapshot!

EDIT As of 02/21/2015 the Qml camera autoOrientation bug reappears with the latest Qt-5.4.1 snapshots!

EDIT As of 03/17/2015 the visibility issue is scheduled to be fixed with Qt-5.5. The bug report contains instructions how to get the camera working without waiting until 5.5 is released.

EDIT As of 04/02/2015 Qt-5.4.1 is available:

Continued in the Qt 5.5 post.