Problems with Open-Source Downloads read https://www.qt.io/blog/problem-with-open-source-downloads and https://forum.qt.io/post/638946

[Solved] QML Slot not executed by C++ Signal



  • Hello,

    i have a main programm that loads QPlugins (dlls). These plugins do some qmlRegisterType witch i can use in the qml file. I have the problem that signals are emited from the plugin are not executing the slot in qml. But when i call a function from qml and the function emit the signal, the slot ist executed.

    Here some sourceparts:

    Mainprogramm that loads the plugins;
    @ QString pluginpath = QDir::toNativeSeparators(QDir::cleanPath(Settings::get("Plugin.Path").toString()));
    if(!pluginpath.endsWith("/"))
    pluginpath.append("/");
    QVariantList plugins = Settings::get("Plugin.Plugins").toList();
    foreach(QVariant plugin, plugins)
    {
    QString path = pluginpath;
    path.append(plugin.toString());
    m_PluginManager->load(path); // When the dll is loading the classes are registered by calling qmlRegisterType

    }
    m_PluginManager->startAll(); <-- does actual nothing
    
    QQmlEngine engine;
    

    // Load the qml file
    QQmlComponent component(&engine, m_sConfigDir + __CONFIG_SUB_FOLDER + "/" + __SCRIPT_NAME);
    QObject *obj = component.create();
    if (obj) {
    } else {
    qDebug() << component.errors();
    }
    @

    The Class that is registered by qmlRegisterType<Timer>("Demo", 1, 0, "Timer");
    Timer.h
    @#ifndef TIMER_H
    #define TIMER_H

    #include <QObject>

    class QTimer;

    class Timer : public QObject
    {
    Q_OBJECT
    Q_PROPERTY( int interval READ interval WRITE setInterval NOTIFY intervalChanged )
    Q_PROPERTY( bool active READ isActive NOTIFY activeChanged )

    public:
    explicit Timer( QObject* parent = 0 );

    void setInterval( int msec );
    int interval();
    
    bool isActive();
    
    Q_INVOKABLE int randomInterval( int min, int max ) const;
    

    public slots:
    void start();
    void stop();

    private slots:
    void ttimeout();

    signals:
    void timeout();

    void intervalChanged();
    void activeChanged();
    

    private:
    QTimer* m_timer;
    };

    #endif // TIMER_H
    @

    Timer.cpp
    @#include "Timer.h"

    #include <QDebug>
    #include <QTimer>

    Timer::Timer( QObject* parent )
    : QObject( parent ),
    m_timer( new QTimer( this ) )
    {
    connect( m_timer, SIGNAL( timeout() ), this, SLOT( ttimeout() ) );
    }

    void Timer::setInterval( int msec )
    {
    if ( m_timer->interval() == msec )
    return;
    m_timer->setInterval( msec );
    emit intervalChanged();
    }

    int Timer::interval()
    {
    return m_timer->interval();
    }

    bool Timer::isActive()
    {
    return m_timer->isActive();
    }

    int Timer::randomInterval( int min, int max ) const
    {
    int range = max - min;
    int msec = min + qrand() % range;
    qDebug() << "Random interval =" << msec << "msecs";
    return msec;
    }

    void Timer::start()
    {
    if ( m_timer->isActive() )
    return;
    m_timer->start();
    emit activeChanged(); //This signal is fired because the function is called from the qml file
    }

    void Timer::stop()
    {
    if ( !m_timer->isActive() )
    return;
    m_timer->stop();
    emit activeChanged();
    }

    void Timer::ttimeout()
    {
    emit timeout(); // This signal is not fired because it is called from the c++ programm (timer timeout)
    }
    @

    The qml File:
    @
    import QtQuick 2.0
    import Demo 1.0

    Item
    {
    Timer {
    id: timer
    interval: timer.randomInterval(500, 5000)
    onActiveChanged: {
    console.log("ActiveChanged")
    }
    onIntervalChanged: {
    console.log("IntervalChanged: " + interval)
    }
    onTimeout: {
    console.log("Timer fired!")
    }
    }
    Component.onCompleted:
    {
    console.log("Hello from Script")
    if (timer.active == false) {
    console.log("Timer started")
    timer.start();
    } else {
    console.log("Timer stopped")
    timer.stop();
    }
    }
    }@

    The Output:

    @Random intervall = 4437 msecs
    IntervalChanged: 4437
    Hello from Script
    Timer started
    ActiveChanged@

    In debug mode the slot ttimeout is executed.

    I hope anyone has a suggestion



  • I found out that the problem has something todo with the qtservice. When i load the Plugins without QtService then all slots will be execute.



  • I found a solution. I loaded the plugins and the start the qml in the start method (virtual method from QtService). When i load the plugins and the qml file in the executeApplication method all works fine.


Log in to reply