Re: [Interest] QML Singleton and QTimer?

2021-05-10 Thread Jason H


> Sent: Monday, May 10, 2021 at 3:08 AM
> From: "Ulf Hermann" 
> To: interest@qt-project.org
> Subject: Re: [Interest] QML Singleton and QTimer?
>
> Hi,
>
> > GuiApplication::GuiApplication(int argc, char*argv[]):
> > QGuiApplication::QGuiApplication(argc, argv)
> > {
> > m_hardwareInterface = new HardwareInterface;
> > qmlRegisterSingletonInstance("com.company", 1, 0, "HardwareInterface", 
> > m_hardwareInterface);
> > }
>
> qmlRegisterSingletonInstance() is dangerous if you create your singleton
> in a different thread than the one the QML engine runs on. The QML
> engine expects to be able fiddle with internals of those objects via the
> metaobject system.
>
> It also does surprising things when you have multiple QML engines: The
> first one to access it grabs the objects and all others only see null.
>
> It also does not play ball with qmlRegisterTypesAndRevisions() the way I
> had intended. You cannot register an instance before the type because
> the type will then get rejected. You also cannot register an instance
> after the type because there is no way to hook into the type
> registration procedure without providing some kind of callback. If you
> could provide a callback, then that would be pretty much the same as
> providing a factory function, though.
>
> The whole qmlRegisterSingletonInstance() was a mistake, sorry about
> that. It's too easy to shoot yourself in the foot with it and there is
> no way to make its type visible at compile time. You should really use
> the QML_SINGLETON macro and let the QML engine handle the life cycle of
> the object. The QML engine will make sure to create and destroy it on
> the right thread. qmlRegisterSingletonInstance() will be deprecated
> before Qt 7.

It definitely seems that way! I hope this can be added to the documentation to
avoid other people going down this path? I was eager to finally use it, as it
would have simplified things on my side. But it looks like it is a difficult
thing to wield properly.


___
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest


Re: [Interest] QML Singleton and QTimer?

2021-05-10 Thread Ulf Hermann

Hi,


GuiApplication::GuiApplication(int argc, char*argv[]):
QGuiApplication::QGuiApplication(argc, argv)
{
m_hardwareInterface = new HardwareInterface;
qmlRegisterSingletonInstance("com.company", 1, 0, "HardwareInterface", 
m_hardwareInterface);
}


qmlRegisterSingletonInstance() is dangerous if you create your singleton 
in a different thread than the one the QML engine runs on. The QML 
engine expects to be able fiddle with internals of those objects via the 
metaobject system.


It also does surprising things when you have multiple QML engines: The 
first one to access it grabs the objects and all others only see null.


It also does not play ball with qmlRegisterTypesAndRevisions() the way I 
had intended. You cannot register an instance before the type because 
the type will then get rejected. You also cannot register an instance 
after the type because there is no way to hook into the type 
registration procedure without providing some kind of callback. If you 
could provide a callback, then that would be pretty much the same as 
providing a factory function, though.


The whole qmlRegisterSingletonInstance() was a mistake, sorry about 
that. It's too easy to shoot yourself in the foot with it and there is 
no way to make its type visible at compile time. You should really use 
the QML_SINGLETON macro and let the QML engine handle the life cycle of 
the object. The QML engine will make sure to create and destroy it on 
the right thread. qmlRegisterSingletonInstance() will be deprecated 
before Qt 7.


best,
Ulf
___
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest


Re: [Interest] QML Singleton and QTimer?

2021-05-07 Thread Jérôme Godbout
Hi,
Is your QTimer access before the QGuiApplication is created (static singleton)? 
That could explain why this complain and moving the singleton instance into the 
GuiApplcation constructor solve your problems.

What we do over here, I have a custom template method that register the 
singleton from Qml and from C++ singleton class (templated too). This keep a 
map of type and pointer to object:

typedef QMap>> SingletonMapType;
extern SingletonMapType singleton_instances_map_;

after that the C++ singleton fetch into that map and so does my Qml singleton 
register type, so I get a single instance no matter who the C++ or the Qml 
request the singleton first. It might not be ideal, but it work well. So they 
are not really a static instance but instead a version that is kept based on 
the current QQmlEngine and application. If your application only use a single 
QQmlengine (like most of them do, you can skip the first layer of the map and 
simply use the map from string to QObject. For the QString you can extract it 
from template type and T::staticMetaObject.className()

you only need a getSingleton() and a createSingleton() class to fill the 
blank. So my class are not bake with singleton, there might be an instance that 
is singleton instead (make it easier to test the class without enforcing 
singleton into it and I can still make memento and the like of those object 
without being screw to have only hard single copy.


Jérôme Godbout, B. Ing.

Software / Firmware Team Lead
O: (418) 682-3636 ext.: 114
C: (581) 777-0050
godbo...@dimonoff.com<mailto:godbo...@dimonoff.com>
[signature_75730]<https://www.dimonoff.com/>
dimonoff.com<https://www.dimonoff.com/>
1015 Avenue Wilfrid-Pelletier,
Québec, QC G1W 0C4, 4e étage


From: Jason H 
Date: Friday, May 7, 2021 at 10:10 AM
To: Jérôme Godbout 
Cc: interestqt-project.org 
Subject: Re: [Interest] QML Singleton and QTimer?
Well, the documentation gives the example of the singleton being instantiated 
at the main.cpp:main() level.

It felt a little wrong, but I subclassed QGuiApplication, and created and 
registered the singleton there:

GuiApplication::GuiApplication(int argc, char*argv[]):

QGuiApplication::QGuiApplication(argc, argv)

{

m_hardwareInterface = new HardwareInterface;

qmlRegisterSingletonInstance("com.company", 1, 0, "HardwareInterface", 
m_hardwareInterface);

}

This seems to work, but seemed unnatural.






Sent: Thursday, May 06, 2021 at 5:42 PM
From: "Jérôme Godbout" 
To: "Jason H" , "interestqt-project.org" 

Subject: Re: [Interest] QML Singleton and QTimer?
You can check the thread affinity of an object and the current thread that will 
display the problem you encounter. Use a queued signal into the QTimer thread 
to sent the start (it will be delayed until the thread process the event, 
hopefully you do no need precision there).

Jérôme Godbout, B. Ing.

Software / Firmware Team Lead
O: (418) 682-3636 ext.: 114
C: (581) 777-0050
godbo...@dimonoff.com<mailto:godbo...@dimonoff.com>
[signature_93124102]<https://www.dimonoff.com/>
dimonoff.com<https://www.dimonoff.com/>
1015 Avenue Wilfrid-Pelletier,
Québec, QC G1W 0C4, 4e étage


From: Interest  on behalf of Jason H 

Date: Thursday, May 6, 2021 at 5:34 PM
To: interestqt-project.org 
Subject: [Interest] QML Singleton and QTimer?
I'm trying to have a simple singleton class, but it doesn't appear that I can 
use timers?


HardwareInterface::HardwareInterface(QObject *parent) : QObject(parent)
{
m_timer = new QTimer(this);

connect(m_timer, ::timeout, this, [=](){
qDebug() << Q_FUNC_INFO;
});

m_timer->start(100); // QObject::startTimer: Timers can only be used 
with threads started with QThread

}

main.cpp: int main() {
...
qmlRegisterSingletonInstance("com.company.example", 1, 0, "HardwareInterface", 
);
...

How do we go about using timers in singletons?

___
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest
___
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest


Re: [Interest] QML Singleton and QTimer?

2021-05-07 Thread Jason H
Well, the documentation gives the example of the singleton being instantiated at the main.cpp:main() level.

 

It felt a little wrong, but I subclassed QGuiApplication, and created and registered the singleton there:


GuiApplication::GuiApplication(int argc, char*argv[]):
	QGuiApplication::QGuiApplication(argc, argv)
{
	m_hardwareInterface = new HardwareInterface;
	qmlRegisterSingletonInstance("com.company", 1, 0, "HardwareInterface", m_hardwareInterface);
}

 

This seems to work, but seemed unnatural.

 


 

 

 

 
 

Sent: Thursday, May 06, 2021 at 5:42 PM
From: "Jérôme Godbout" 
To: "Jason H" , "interestqt-project.org" 
Subject: Re: [Interest] QML Singleton and QTimer?




You can check the thread affinity of an object and the current thread that will display the problem you encounter. Use a queued signal into the QTimer thread to sent the start (it will be delayed until the thread process the event, hopefully you do no need precision there).

 



Jérôme Godbout, B. Ing.


Software / Firmware Team Lead
O: (418) 682-3636 ext.: 114  

C: (581) 777-0050 
godbo...@dimonoff.com



dimonoff.com

1015 Avenue Wilfrid-Pelletier, 

Québec, QC G1W 0C4, 4e étage



 

 


From: Interest  on behalf of Jason H 
Date: Thursday, May 6, 2021 at 5:34 PM
To: interestqt-project.org 
Subject: [Interest] QML Singleton and QTimer?



I'm trying to have a simple singleton class, but it doesn't appear that I can use timers?


HardwareInterface::HardwareInterface(QObject *parent) : QObject(parent)
{
    m_timer = new QTimer(this);

    connect(m_timer, ::timeout, this, [=](){
    qDebug() << Q_FUNC_INFO;
    });

    m_timer->start(100); // QObject::startTimer: Timers can only be used with threads started with QThread

}

main.cpp: int main() {
...
qmlRegisterSingletonInstance("com.company.example", 1, 0, "HardwareInterface", );
...

How do we go about using timers in singletons?

___
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest






___
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest


Re: [Interest] QML Singleton and QTimer?

2021-05-06 Thread Jérôme Godbout
You can check the thread affinity of an object and the current thread that will 
display the problem you encounter. Use a queued signal into the QTimer thread 
to sent the start (it will be delayed until the thread process the event, 
hopefully you do no need precision there).

Jérôme Godbout, B. Ing.

Software / Firmware Team Lead
O: (418) 682-3636 ext.: 114
C: (581) 777-0050
godbo...@dimonoff.com<mailto:godbo...@dimonoff.com>
[signature_93124102]<https://www.dimonoff.com/>
dimonoff.com<https://www.dimonoff.com/>
1015 Avenue Wilfrid-Pelletier,
Québec, QC G1W 0C4, 4e étage


From: Interest  on behalf of Jason H 

Date: Thursday, May 6, 2021 at 5:34 PM
To: interestqt-project.org 
Subject: [Interest] QML Singleton and QTimer?
I'm trying to have a simple singleton class, but it doesn't appear that I can 
use timers?


HardwareInterface::HardwareInterface(QObject *parent) : QObject(parent)
{
m_timer = new QTimer(this);

connect(m_timer, ::timeout, this, [=](){
qDebug() << Q_FUNC_INFO;
});

m_timer->start(100); // QObject::startTimer: Timers can only be used 
with threads started with QThread

}

main.cpp: int main() {
...
qmlRegisterSingletonInstance("com.company.example", 1, 0, "HardwareInterface", 
);
...

How do we go about using timers in singletons?

___
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest
___
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest


[Interest] QML Singleton and QTimer?

2021-05-06 Thread Jason H
I'm trying to have a simple singleton class, but it doesn't appear that I can 
use timers?


HardwareInterface::HardwareInterface(QObject *parent) : QObject(parent)
{
m_timer = new QTimer(this);

connect(m_timer, ::timeout, this, [=](){
qDebug() << Q_FUNC_INFO;
});

m_timer->start(100); // QObject::startTimer: Timers can only be used 
with threads started with QThread

}

main.cpp: int main() {
...
qmlRegisterSingletonInstance("com.company.example", 1, 0, "HardwareInterface", 
);
...

How do we go about using timers in singletons?

___
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest