0
votes

I have following custom QML item with two states:

import QtQuick 2.0

import si.testfirm 1.0

Item
{
    id: ueDatabaseStatusIndicator

    property string ueParamImageStatusOn
    property string ueParamImageStatusOff

    state: ueApplicationStatus.m_ueBluetoothPrinterConnectionStatus===UeTypeBluetootPrinterConnectionStatus.NOT_PAIRED?
           "ueStatusIndicatorBluetoothNotConnected":
           "ueStatusIndicatorBluetoothConnected"

    Image
    {
        id: ueStatusIndicatorCurrentImage

        smooth: true

        fillMode: Image.PreserveAspectFit

        width: 96
        height: 96

        sourceSize.width: 96
        sourceSize.height: 96
    }   // Image

    states:
    [
        State
        {
            name: "ueStatusIndicatorBluetoothConnected"

            PropertyChanges
            {
                target: ueStatusIndicatorCurrentImage
                source: ueParamImageStatusOn
            }   // PropertyChanges
        },  // State

        State
        {
            name: "ueStatusIndicatorBluetoothNotConnected"

            PropertyChanges
            {
                target: ueStatusIndicatorCurrentImage
                source: ueParamImageStatusOff
            }   // PropertyChanges
        }   // State
    ]   // states
}   // Item

In first state, named ueStatusIndicatorBluetoothNotConnected, it shows red icon, which resembles bluetooth printer is not paired. In second state, named ueStatusIndicatorBluetoothConnected, it shows blue icon, which resembles bluetooth printer is paired with app. Now, when I run this app with following main.cpp file:

#include <QtQml>
#include <QApplication>
#include <QQmlApplicationEngine>

#include "database/uepeoplemodel.h"
#include "core/ueapplicationstatus.h"
#include "core/uedatabaseconnectionstatus.h"
#include "core/uebluetoothmanager.h"
#include "core/uebluetoothprinterconnectionstatus.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QQmlApplicationEngine engine;

    UeApplicationStatus* ueApplicationStatus=new UeApplicationStatus(qApp);
    UePeopleModel* uePeopleModel=new UePeopleModel(qApp);
    UeBluetoothManager* ueBtManager=new UeBluetoothManager(qApp);

    QObject::connect(uePeopleModel,
                     SIGNAL(ueSignalDatabaseConnectionChanged(UeDatabaseConnectionStatus::UeTypeDatabaseConnectionStatus)),
                     ueApplicationStatus,
                     SLOT(ueSlotDatabaseConnectionChanged(UeDatabaseConnectionStatus::UeTypeDatabaseConnectionStatus)));

    QObject::connect(ueBtManager,
                     SIGNAL(ueSignalBtPrinterConnectionChanged(UeBluetoothPrinterConnectionStatus::UeTypeBluetootPrinterConnectionStatus)),
                     ueApplicationStatus,
                     SLOT(ueSlotBtPrinterConnectionChanged(UeBluetoothPrinterConnectionStatus::UeTypeBluetootPrinterConnectionStatus)));

    engine.rootContext()->setContextProperty("uePeopleModel",
                                             uePeopleModel);
    engine.rootContext()->setContextProperty("ueApplicationStatus",
                                             ueApplicationStatus);
    engine.rootContext()->setContextProperty("ueBtManager",
                                             ueBtManager);

    engine.addImageProvider(QLatin1String("uePeopleModel"),
                            uePeopleModel);

    qmlRegisterUncreatableType<UeDatabaseConnectionStatus>("si.testfirm",
                                                           1,
                                                           0,
                                                           "UeTypeDatabaseConnectionStatus",
                                                           "Database Connection Status");

    qmlRegisterUncreatableType<UeBluetoothPrinterConnectionStatus>("si.testfirm",
                                                                   1,
                                                                   0,
                                                                   "UeTypeBluetootPrinterConnectionStatus",
                                                                   "Bluetooth Printer Connection Status");

    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    uePeopleModel->ueConnectToDatabase();
    ueBtManager->ueStartPairing();

    ueApplicationStatus->ueUpdate(uePeopleModel->ueFetchUsers());

    return app.exec();
}

in the app red icon is showed, which is ok, since printer is not paired, however, with the line ueBtManager->ueStartPairing(); I start searching for bluetooth printer and the printer is found and paired, since slot void UeBluetoothManager::ueSlotPairingFinished(const QBluetoothAddress& address,QBluetoothLocalDevice::Pairing pairing) gets called as you can see from screenshot: Slot gets called In the last line, as you can see from screenshot, I emit signal UeBluetoothManager::void ueSignalBtPrinterConnectionChanged(const UeBluetoothPrinterConnectionStatus::UeTypeBluetootPrinterConnectionStatus& newStatus); which is called in main.cpp by ueApplicationStatus object to update its status. Here is UeApplicationStatus header:

#ifndef UEAPPLICATIONSTATUS_H
#define UEAPPLICATIONSTATUS_H

#include <QObject>
#include <QList>
#include <QDebug>

#include "../core/uetypes.h"
#include "../core/uedatabaseconnectionstatus.h"
#include "../core/uebluetoothprinterconnectionstatus.h"

class UeApplicationStatus : public QObject
{
    Q_OBJECT

    Q_PROPERTY(UeTypeUsers* m_ueUsers
               READ ueUsers
               WRITE ueSetUsers
               NOTIFY ueSignalUsersChanged)
    Q_PROPERTY(UeDatabaseConnectionStatus::UeTypeDatabaseConnectionStatus m_ueDatabaseConnectionStatus
               READ ueDbConnectionStatus
               WRITE ueSetDbConnectionStatus
               NOTIFY ueSignalDatabaseConnectionChanged)
    Q_PROPERTY(UeBluetoothPrinterConnectionStatus::UeTypeBluetootPrinterConnectionStatus m_ueBluetoothPrinterConnectionStatus
               READ ueBtPrinterConnectionStatus
               WRITE ueSetBtPrinterConnectionStatus
               NOTIFY ueSignalBtPrinterConnectionChanged)

private:
    UeTypeUsers* m_ueUsers;
    UeDatabaseConnectionStatus::UeTypeDatabaseConnectionStatus m_ueDatabaseConnectionStatus;
    UeBluetoothPrinterConnectionStatus::UeTypeBluetootPrinterConnectionStatus m_ueBluetoothPrinterConnectionStatus;

public:
    explicit UeApplicationStatus(QObject *parent = 0);
    ~UeApplicationStatus();

    inline UeTypeUsers* ueUsers() const
        { return this->m_ueUsers; }
    inline UeDatabaseConnectionStatus::UeTypeDatabaseConnectionStatus ueDbConnectionStatus() const
        { return this->m_ueDatabaseConnectionStatus; }
    inline UeBluetoothPrinterConnectionStatus::UeTypeBluetootPrinterConnectionStatus ueBtPrinterConnectionStatus() const
        { return this->m_ueBluetoothPrinterConnectionStatus; }

    inline void ueSetUsers(UeTypeUsers* const users)
        { this->m_ueUsers=users; }
    inline void ueSetDbConnectionStatus(const UeDatabaseConnectionStatus::UeTypeDatabaseConnectionStatus& status)
        { this->m_ueDatabaseConnectionStatus=status; }
    inline void ueSetBtPrinterConnectionStatus(const UeBluetoothPrinterConnectionStatus::UeTypeBluetootPrinterConnectionStatus status)
        { this->m_ueBluetoothPrinterConnectionStatus=status; }

signals:
    void ueSignalUsersChanged();
    void ueSignalDatabaseConnectionChanged(const UeDatabaseConnectionStatus::UeTypeDatabaseConnectionStatus& newStatus);
    void ueSignalBtPrinterConnectionChanged(const UeBluetoothPrinterConnectionStatus::UeTypeBluetootPrinterConnectionStatus& newStatus);

public slots:
    void ueSlotDatabaseConnectionChanged(const UeDatabaseConnectionStatus::UeTypeDatabaseConnectionStatus& newStatus);
    void ueSlotBtPrinterConnectionChanged(const UeBluetoothPrinterConnectionStatus::UeTypeBluetootPrinterConnectionStatus& newStatus);
    void ueUpdate(UeTypeUsers* const users);
};

#endif // UEAPPLICATIONSTATUS_H

and its implementation:

#include "ueapplicationstatus.h"

UeApplicationStatus::UeApplicationStatus(QObject *parent)
    : QObject(parent)
{
    this->ueSetUsers(new UeTypeUsers());
    this->ueSetDbConnectionStatus(UeDatabaseConnectionStatus::NOT_CONNECTED);
    this->ueSetBtPrinterConnectionStatus(UeBluetoothPrinterConnectionStatus::NOT_PAIRED);

    connect(this,
            SIGNAL(ueSignalDatabaseConnectionChanged(UeDatabaseConnectionStatus::UeTypeDatabaseConnectionStatus)),
            this,
            SLOT(ueSlotDatabaseConnectionChanged(UeDatabaseConnectionStatus::UeTypeDatabaseConnectionStatus)));

    connect(this,
            SIGNAL(ueSignalBtPrinterConnectionChanged(UeBluetoothPrinterConnectionStatus::UeTypeBluetootPrinterConnectionStatus)),
            this,
            SLOT(ueSlotBtPrinterConnectionChanged(UeBluetoothPrinterConnectionStatus::UeTypeBluetootPrinterConnectionStatus)));
}   // constructor

UeApplicationStatus::~UeApplicationStatus()
{
    delete this->ueUsers();
}   // destructor

void UeApplicationStatus::ueSlotDatabaseConnectionChanged(const UeDatabaseConnectionStatus::UeTypeDatabaseConnectionStatus& newStatus)
{
    this->ueSetDbConnectionStatus(newStatus);
}   // ueSignalDatabaseConnectionChanged

void UeApplicationStatus::ueSlotBtPrinterConnectionChanged(const UeBluetoothPrinterConnectionStatus::UeTypeBluetootPrinterConnectionStatus& newStatus)
{
    this->ueSetBtPrinterConnectionStatus(newStatus);
}   // ueSlotBtPrinterConnectionChanged

void UeApplicationStatus::ueUpdate(UeTypeUsers* const users)
{
    this->ueSetUsers(users);
}   // ueUpdate

The question is, why images are not switched on QML side inside custom item ueDatabaseStatusIndicator, which code is listed first?

1
A friendly advice, those great walls of code will not do you favors when it comes to solving your problem. Try to isolate the problem and produce a minimal example reproducing it. This way you don't punish the people who want to help you out by having to go through all that irrelevant code.dtech
@ddriver I am aware but I could not shrink it since these classes are currently point of problem.KernelPanic

1 Answers

3
votes

It could be because of the way you are initialising your application. You are starting the event loop after emitting the signals. Try this.

engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

QTimer::singleshot(150, this, [&]() {
  uePeopleModel->ueConnectToDatabase();
  ueBtManager->ueStartPairing();
  ueApplicationStatus->ueUpdate(uePeopleModel->ueFetchUsers());
});

return app.exec();

This is just my guess. Best of luck.


update

inline void ueSetBtPrinterConnectionStatus(const UeBluetoothPrinterConnectionStatus::UeTypeBluetootPrinterConnectionStatus status)
{ 
    m_ueBluetoothPrinterConnectionStatus=status; 
    emit ueSignalBtPrinterConnectionChanged(m_ueBluetoothPrinterConnectionStatus);
}

You must remove the connect calls as this creates a infinite loop.