1

i’m developing a clock application and I need to do it using Q_PROPERTY. The idea is to make all the clock control logic using C++ and deploy it in a QML GUI. I got this working on a windows machine but when I run it on a linux distro in a development board I get sometimes undefined text (which are the exposed properties from C++).

The header file is:

#ifndef QCPPCLOCK_H
#define QCPPCLOCK_H

#include <QObject>
#include <QDebug>
#include <QString>
#include <QTime>
#ifdef __linux__
#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#endif

class QcppClock : public QObject
{
    Q_OBJECT

    Q_PROPERTY(QString hours READ hours WRITE setHours NOTIFY hoursChanged)
    Q_PROPERTY(QString minutes READ minutes WRITE setMinutes NOTIFY minutesChanged)

private:
    QString actualHours;
    QString actualMinutes;
    QObject* rootObject;
    QTime actualTime;
    qint8 alarmHour;
    qint8 alarmMinutes;
    QString timeFormat;
    bool alarmSet;
#ifdef __linux__
    struct tm* ptm;
    struct timeval tv;
#endif

public:
    explicit QcppClock(QObject *parent = 0);
    QString hours();
    void setHours(QString);
    QString minutes();
    void setMinutes(QString);

public slots:
    void qcppClock_vUpdateTextTime_slot(void);

signals:
    void qcppClock_vTriggerAlarm_signal(void);
    void hoursChanged(void);
    void minutesChanged(void);
};

#endif // QCPPCLOCK_H

The .cpp file:

#include "qcppclock.h"
#include <QTimer>
#include <QtCore/qmath.h>

QcppClock::QcppClock(QObject *parent) :
    QObject(parent)
{
    QTimer* timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(qcppClock_vUpdateTextTime_slot()));
    rootObject = parent;
    actualTime = QTime::currentTime();
    /* Initialize the format to 24 hours */
    timeFormat = "24hours";
    timer->start(1000);
#ifdef __linux__
    gettimeofday (&tv, NULL);
    ptm = localtime (&tv.tv_sec);
    int hour = ptm->tm_hour;
    //setHours(hour);
    //actualHours = QString::number(hour);
    int minutes = ptm->tm_min;
    //setMinutes(minutes);
    //actualMinutes = QString::number(minutes);
    int seconds = ptm->tm_sec;
    (void)actualTime.setHMS(hour , minutes, seconds);
#endif

}

QString QcppClock::hours()
{
    return actualHours;
}

void QcppClock::setHours(QString newHours)
{
    actualHours = newHours;
#ifdef __linux__
    tv.tv_sec += 3600 * actualHours.toInt();
    settimeofday(&tv, NULL);
#else
    (void)actualTime.setHMS(actualHours.toInt() , actualMinutes.toInt(), actualTime.second());
#endif
    emit hoursChanged();
}

QString QcppClock::minutes()
{
    return actualMinutes;
}

void QcppClock::setMinutes(QString newMinutes)
{
    actualMinutes = newMinutes;
#ifdef __linux__
    tv.tv_sec += 60 * actualMinutes.toInt();
    settimeofday(&tv, NULL);
#else
    (void)actualTime.setHMS(actualHours.toInt() , actualMinutes.toInt(), actualTime.second());
#endif
    emit minutesChanged();
}

void QcppClock::qcppClock_vUpdateTextTime_slot(void)
{
    actualTime = actualTime.addSecs(1);
    actualMinutes = QString::number(actualTime.minute());
    emit minutesChanged();
    actualHours = QString::number(actualTime.hour());
    emit hoursChanged();
    QString::number(actualTime.minute());
}

The main file which instantiates the clockctrl object is:

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "qcpp_Clock/qcppclock.h"

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

    QQmlApplicationEngine engine;
    QcppClock qcpp_Clock;
    QQmlContext* context = engine.rootContext();
    context->setContextProperty("clockCtrl", &qcpp_Clock);
    engine.load(QUrl(QStringLiteral("qrc:///main.qml")));

    return app.exec();
}

And the QML file using the exposed properties is:

import QtQuick 2.2
import QtQuick.Window 2.1

Window {
    visible: true
    width: 800
    height: 480

    MouseArea {
        anchors.fill: parent
        onClicked: {
            Qt.quit();
        }
    }

    Text {
        property string prHours: clockCtrl.hours
        property string prMinutes: clockCtrl.minutes
        text: {
            console.log(clockCtrl, clockCtrl.hours, clockCtrl.minutes);
            return (prHours + " : " + prMinutes)
        }
        anchors.centerIn: parent
    }
}

As you can see it’s a short and easy code, the problem is in QML when I try to make reference to the C++ exposed properties, i added a couple of consoles in order to see the result in the log and It works like a charm in windows, I never get these “undefined text” but in the development board with linux distro I get sometimes:

qml: QcppClock(0×7e8eeca8) 1 49 qml: QcppClock(0×7e8eeca8) undefined undefined qml: QcppClock(0×7e8eeca8) 1 49

The first debug is the address of the c++ exposed object in C++, then, the Q_PROPERTY “hour” and the Q_PROPERTY “minutes”.

Thank you in advance.

Ramsés

  • 3
    Unrelated, why Linux specific APIs when you have QDateTime... – peppe Feb 16 '15 at 21:20
  • 1
    Where exactly is clockCtrl defined? Also, very little of this code is necessary to reproduce the problem -- please create a [Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve) to illustrate the problem.. – MrEricSir Feb 16 '15 at 21:47
  • @MrEricSir I updated the code with the main file, thank you so much. – Ramsés Ramírez Feb 16 '15 at 22:10
  • I've tried to compile and run you project in Debian Linux and it works without problem/warnings. Yes, it's strange why you use system specified time function when you have QTime but anyway it works. Remove all system specified files from the project, like *.user etc. Run qmake and recompile the project. I used Qt 5.4 on x86 system btw. – folibis Feb 17 '15 at 00:59
  • Thank you @folibis for testing the code, however, I am cross-compiling the code for a development board with ARM Cortex-A9 and running a light modified version of Linux. If I test the code in any x86 system, it doesn´t matter the operating system it works perfectly, but when I run it on this board with the ARM processor and the light version of linux, I get these strange undefined text instead of the hours and minutes. – Ramsés Ramírez Feb 17 '15 at 14:16
  • Why don't you use QTimer? Try it, may be the problem is native time functions – folibis Feb 17 '15 at 21:19
  • @folibis I use native time functions 'cause is a project requirement, however, these are not causing the problem, I've seen this issue in many other modules not regarding time functions. I believe this is a QT issue with the property bindings to referred c++ objects in development boards because I tried with different operating systems on a x86 machine and it works like a charm. I am using a variscite board with i.MX 6 as development board. Thank you – Ramsés Ramírez Feb 17 '15 at 21:47

0 Answers0