Results 1 to 14 of 14

Thread: Direct connection in QML

  1. #1
    Join Date
    Feb 2013
    Location
    Prague
    Posts
    7
    Thanked 2 Times in 2 Posts
    Qt products
    Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Direct connection in QML

    Hello,

    I am connecting QML object signal to a slot like so:
    Qt Code:
    1. onSignal: slot
    To copy to clipboard, switch view to plain text mode 

    It creates
    Qt Code:
    1. Qt::QueuedConnection
    To copy to clipboard, switch view to plain text mode 
    between the two objects.
    But I want to create
    Qt Code:
    1. Qt::DirectConnection
    To copy to clipboard, switch view to plain text mode 
    between them.

    How can I achieve it? Or is there a code in QML engine that I can tweak?

    Thank you.

    Michal
    Last edited by mfojtak; 14th February 2013 at 15:40.

  2. #2
    Join Date
    Jan 2012
    Location
    Iran, Tehran
    Posts
    308
    Thanks
    75
    Thanked 24 Times in 21 Posts
    Qt products
    Qt4 Qt5 PyQt3 PyQt4
    Platforms
    Unix/X11 Windows

    Default Re: Direct connection in QML

    Your question is ambiguous! can you make a simple example?

  3. The following user says thank you to alizadeh91 for this useful post:


  4. #3
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Direct connection in QML

    Quote Originally Posted by mfojtak View Post
    How can I achieve it?
    I don't think you can do it directly. In theory you could expose a C++ function to QML where you'd do the connection on C++ side but it wouldn't be as simple to use as "onSignal: codeToExecute".

    Why do you need that?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. #4
    Join Date
    Feb 2013
    Location
    Prague
    Posts
    7
    Thanked 2 Times in 2 Posts
    Qt products
    Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Direct connection in QML

    The C++ function is obviously an option. But it would not allow me to define the connections declaratively as with "onSignal: codeToExecute".
    I need the direct connections for what they are exactly for - connecting slots directly. I developed a real-time application which is performance critical. The queued connections bring an overhead with copying slot arguments, queue slot arguments.
    Also, I need the slot to run under the same thread as signal owner.
    My application is a kind of dataflow/workflow application. Each module/building block is represented by a QObject which are interconnected via signals/slots.
    I've created an XML configuration file for it. However, it would be much better to utilize QML, which is declarative, it allows me to embed a Javacript code - well you know benefits of QML :-)

  6. #5
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Direct connection in QML

    Quote Originally Posted by mfojtak View Post
    The C++ function is obviously an option. But it would not allow me to define the connections declaratively as with "onSignal: codeToExecute".
    Of course you can define connections in a declarative manner. It's just a matter of exposing a proper interface from C++ to QML.

    I need the direct connections for what they are exactly for - connecting slots directly. I developed a real-time application which is performance critical. The queued connections bring an overhead with copying slot arguments, queue slot arguments.
    Khem... QtQuick is not really designed for time critical tasks. Queued connections are the least of your problems.

    Also, I need the slot to run under the same thread as signal owner.
    I'm not even going to explain now what that is Wrong(TM).

    My application is a kind of dataflow/workflow application. Each module/building block is represented by a QObject which are interconnected via signals/slots.
    I've created an XML configuration file for it. However, it would be much better to utilize QML, which is declarative, it allows me to embed a Javacript code - well you know benefits of QML :-)
    QML (in Qt5) can be used without QtQuick as a way to define relations between objects. However its work ends after the QML tree is parsed and all functionality is embedded in the object types you expose from C++. You can expose an alternative for Connections that will make direct connections however be aware that writing slots directly in QML scripts has its limitations. Because they are executed by the script engine, they are limited to a single thread (as the script engine itself cannot be called from multiple threads). If there are objects behind the scene that live in other threads, trying to invoke script code from such thread will simply crash your program.

    Either way, using JavaScript with garbage collecting, JIT compiling and all that stuff for time critical tasks is very likely bad design.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  7. #6
    Join Date
    Feb 2013
    Location
    Prague
    Posts
    7
    Thanked 2 Times in 2 Posts
    Qt products
    Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Direct connection in QML

    Khem... QtQuick is not really designed for time critical tasks. Queued connections are the least of your problems.
    QtQuick is just a QML plugin. I want to use QML as a language to define an object tree of any QObjects. The app could be a deamon with no UI.

    I'm not even going to explain now what that is Wrong(TM).
    What do you mean? That's what direct connections are for - slot is executed by the same thread which emits the signal.
    Direct connections are used when necessary. The UI elements are connected with other parts by queued connections which makes sense because I don't want my UI to disrupt my real time part (UI runs under dedicated thread anyway).

    You can expose an alternative for Connections that will make direct connections
    How is that possible?

    Either way, using JavaScript with garbage collecting, JIT compiling and all that stuff for time critical tasks is very likely bad design.
    The application doesn't contain only time critical parts. Javascript gives user an extra flexibility. Let say I need to add some extra logging to my app. I can just write handler which will do logging in QML without recompiling my app. I am fully aware that Javascript handlers run under dedicated JS engine's thread.

    I just need to have a choice which connection type to use. Real-world applications usually need both.

  8. #7
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Direct connection in QML

    Quote Originally Posted by mfojtak View Post
    What do you mean? That's what direct connections are for - slot is executed by the same thread which emits the signal.
    If your objects live in different threads then having direct connections between them is a good first step to the end of the world.

    I don't want my UI to disrupt my real time part (UI runs under dedicated thread anyway).
    Qt does not bring any real-time guarantees. Regardless if you use direct connections or queued ones.

    How is that possible?
    It's as possible as exposing any other QML element. "Connections" is by no means different.

    The application doesn't contain only time critical parts. Javascript gives user an extra flexibility. Let say I need to add some extra logging to my app. I can just write handler which will do logging in QML without recompiling my app. I am fully aware that Javascript handlers run under dedicated JS engine's thread.
    And that logging has influence on when your time-critical part gets executed (or not).

    I just need to have a choice which connection type to use. Real-world applications usually need both.
    You do have that freedom. You just need to enable it for yourself.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  9. The following user says thank you to wysota for this useful post:


  10. #8
    Join Date
    Feb 2013
    Location
    Prague
    Posts
    7
    Thanked 2 Times in 2 Posts
    Qt products
    Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Direct connection in QML

    If your objects live in different threads then having direct connections between them is a good first step to the end of the world.
    The objects which I connect directly live in the same thread. But the code is executed by a new QThread that I create. This thread acts as a realtime timer which triggers the execution of slots which emit signals and other slots and so. This object graph is defined by a custom XML at the moment. Take a look at the project's (beta) website. It might help you to understand what I am after.
    Qt does not bring any real-time guarantees. Regardless if you use direct connections or queued ones.
    Qt is only an application framework. The OS does bring real-time guarantees. I am using clock_nanosleep() kernel instruction in my C++/Qt timer code. It works great. My realtime part is not missing deadlines on sub-microsecond basis - but only if my modules (QObjects) are connected directly. With queued connections it doesn't even make sense to measure delays as you bring an extra queue in between my modules. That's why I need direct connections.

    It's as possible as exposing any other QML element. "Connections" is by no means different.
    The Connections object is used as this. See the following example:
    Qt Code:
    1. Connections {
    2. target: area
    3. onClicked: foo(parameters)
    4. }
    To copy to clipboard, switch view to plain text mode 
    Looking at the code above I can't see any way how to impact the connection type of clicked signal. I must be missing something. Should I inherit Connections class? I don't have problem with exposing a QML element. My problem is that the notation onSignal:slot always creates queued connection.

  11. The following user says thank you to mfojtak for this useful post:


  12. #9
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Direct connection in QML

    You have to implement your own element, say DirectConnections.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  13. The following user says thank you to wysota for this useful post:


  14. #10
    Join Date
    Feb 2013
    Location
    Prague
    Posts
    7
    Thanked 2 Times in 2 Posts
    Qt products
    Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Direct connection in QML

    OK, let say I have implemented my DirectConnections object. Now I also have object called Sender which emits signal called signal. And I have object called Receiver with slot called slot(). All three objects are exposed by my QML plugin called CustomPlugin.
    The QML would look like this:
    Qt Code:
    1. import CustomPlugin 1.0
    2. Sender {
    3. id: sender
    4. }
    5. Receiver {
    6. id: receiver
    7. }
    8. DirectConnections {
    9. target: receiver
    10. NOW HOW DO I CREATE CONNECTION BETWEEN onSignal and receiver.slot()
    11. }
    To copy to clipboard, switch view to plain text mode 

    The question is hidden in the code above. What shloud I do to implement such a class which would understand this: onSignal: receiver.slot() ?
    I know you can do it with Connections object. But this object is part of QML language which parses "signal: slot" notation in a special way.
    It would be brilliant if I could have custom object which keeps the same notation as Connection object. But how to implement it. Could you provide few lines of code which would illustrate it?

  15. The following user says thank you to mfojtak for this useful post:


  16. #11
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Direct connection in QML

    For example:

    javascript Code:
    1. DirectConnections {
    2. source: sender.signal
    3. target: receiver.slot
    4. }
    To copy to clipboard, switch view to plain text mode 

    I'm not sure how to access the signal and the slot itself from the C++ side. If you can't find a way to do it, you can always use separate properties for the signal and slot signatures (as strings) that you will then use in the backend.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  17. #12
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Direct connection in QML

    More likely having two properties of type QObject* and two properties of type QString.
    Once all four properties are set, code is triggered that does
    1) lookup of slot and signal through QMetaObject
    2) call connect with the two objects and the retrieved signal and slot signatures

    Cheers,
    _


    Added after 8 minutes:


    Ok, I have to say I don't understand the problem.

    I get DirectConnection behavior in a simple test application

    Qt Code:
    1. #ifndef TIMER_H
    2. #define TIMER_H
    3.  
    4. #include <QObject>
    5.  
    6. #include <QtQuick>
    7.  
    8. class QTimer;
    9.  
    10. class Timer : public QObject
    11. {
    12. Q_OBJECT
    13.  
    14. public:
    15. explicit Timer( QObject* parent = 0 );
    16.  
    17. signals:
    18. void timeout();
    19.  
    20. private:
    21. QTimer* m_timer;
    22.  
    23. private slots:
    24. void onInternalTimeout();
    25. };
    26.  
    27. #endif // TIMER_H
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. #include "timer.h"
    2.  
    3. #include <QDebug>
    4. #include <QTimer>
    5.  
    6. Timer::Timer( QObject* parent )
    7. : QObject( parent ),
    8. m_timer( new QTimer( this ) )
    9. {
    10. m_timer->setInterval( 1000 );
    11. connect(m_timer, SIGNAL(timeout()), this, SLOT(onInternalTimeout()));
    12. m_timer->start();
    13. }
    14.  
    15. void Timer::onInternalTimeout()
    16. {
    17. qDebug() << Q_FUNC_INFO;
    18. emit timeout();
    19. qDebug() << "emit timeout() returned";
    20. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. import QtQuick 2.0
    2. import CustomComponents 1.0
    3.  
    4. Timer {
    5. id: timer
    6. onTimeout: console.log( "onTimeout in QML" )
    7. }
    To copy to clipboard, switch view to plain text mode 

    Obviously exporting the Timer class with qmlRegisterType in "CustomComponents" version 1.0

    Output is
    Qt Code:
    1. void Timer::onInternalTimeout()
    2. onTimeout in QML
    3. emit timeout() returned
    To copy to clipboard, switch view to plain text mode 

    So emit returns after the "QML slot" has been called. AKA DirectConnection

    Cheers,
    _
    Last edited by anda_skoa; 12th March 2013 at 17:58.

  18. The following user says thank you to anda_skoa for this useful post:


  19. #13
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Direct connection in QML

    Quote Originally Posted by anda_skoa View Post
    More likely having two properties of type QObject* and two properties of type QString.
    Yes, that's what I mean in the last paragraph of my previous post.

    Ok, I have to say I don't understand the problem.

    I get DirectConnection behavior in a simple test application
    I think OP wants a direct connection between objects living in different threads which is a Bad Thing.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  20. The following user says thank you to wysota for this useful post:


  21. #14
    Join Date
    Feb 2013
    Location
    Prague
    Posts
    7
    Thanked 2 Times in 2 Posts
    Qt products
    Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Direct connection in QML

    More likely having two properties of type QObject* and two properties of type QString.
    Once all four properties are set, code is triggered that does
    1) lookup of slot and signal through QMetaObject
    2) call connect with the two objects and the retrieved signal and slot signatures
    That makes sense and I will give it a try.

    I think OP wants a direct connection between objects living in different threads which is a Bad Thing.
    As I stated before - all objects live in the same thread and signals are emitted/slots executed by the same thread.


    Added after 1 30 minutes:


    So I implemented DirectConnection class and it works.

    Here is the header file:
    Qt Code:
    1. #ifndef DIRECTCONNECTION_H
    2. #define DIRECTCONNECTION_H
    3.  
    4. #include <QObject>
    5.  
    6. class DirectConnection : public QObject
    7. {
    8. Q_OBJECT
    9. Q_PROPERTY(QObject* source READ getSource WRITE setSource)
    10. Q_PROPERTY(QObject* destination READ getDestination WRITE setDestination)
    11. Q_PROPERTY(QString signal READ getSignal WRITE setSignal)
    12. Q_PROPERTY(QString slot READ getSlot WRITE setSlot)
    13.  
    14. QString _signal, _slot;
    15. QObject* _source;
    16. QObject* _destination;
    17. void tryConnect();
    18. QMetaMethod findMethod(QObject* owner, QString signature);
    19. public:
    20. explicit DirectConnection(QObject *parent = 0);
    21. QObject* getSource();
    22. void setSource(QObject* source);
    23. QObject* getDestination();
    24. void setDestination(QObject* destination);
    25. QString getSignal();
    26. void setSignal(QString signal);
    27. QString getSlot();
    28. void setSlot(QString slot);
    29.  
    30. signals:
    31.  
    32. public slots:
    33.  
    34. };
    35. #endif // DIRECTCONNECTION_H
    To copy to clipboard, switch view to plain text mode 

    Source file:
    Qt Code:
    1. #include "directconnection.h"
    2. #include <QMetaMethod>
    3.  
    4. DirectConnection::DirectConnection(QObject *parent) :
    5. QObject(parent), _source(NULL), _destination(NULL)
    6. {
    7. }
    8. QObject* DirectConnection::getSource()
    9. {
    10. return _source;
    11. }
    12. void DirectConnection::setSource(QObject* source)
    13. {
    14. _source = source;
    15. tryConnect();
    16. }
    17. QObject* DirectConnection::getDestination()
    18. {
    19. return _destination;
    20. }
    21. void DirectConnection::setDestination(QObject* destination)
    22. {
    23. _destination = destination;
    24. tryConnect();
    25. }
    26. QString DirectConnection::getSignal()
    27. {
    28. return _signal;
    29. }
    30. void DirectConnection::setSignal(QString signal)
    31. {
    32. _signal = signal;
    33. tryConnect();
    34. }
    35. QString DirectConnection::getSlot()
    36. {
    37. return _slot;
    38. }
    39.  
    40. void DirectConnection::setSlot(QString slot)
    41. {
    42. _slot = slot;
    43. tryConnect();
    44. }
    45. QMetaMethod DirectConnection::findMethod(QObject *owner, QString signature)
    46. {
    47. const QMetaObject* metaObject = owner->metaObject();
    48. int index = metaObject->indexOfMethod(signature.toUtf8().constData());
    49. return metaObject->method(index);
    50. }
    51.  
    52. void DirectConnection::tryConnect()
    53. {
    54. if(_source && _destination && !_signal.isNull() && !_slot.isNull())
    55. {
    56. QMetaMethod slot = findMethod(_destination, _slot);
    57. QMetaMethod signal = findMethod(_source, _signal);
    58. QObject::connect(_source, signal,
    59. _destination, slot,
    60. Qt::DirectConnection);
    61. }
    62. }
    To copy to clipboard, switch view to plain text mode 

    Thank you guys!
    Last edited by mfojtak; 13th March 2013 at 10:20.

Similar Threads

  1. Direct QwtPlot painting
    By ssample in forum Qwt
    Replies: 1
    Last Post: 23rd January 2013, 06:41
  2. Replies: 0
    Last Post: 11th November 2011, 19:18
  3. Replies: 1
    Last Post: 2nd April 2010, 06:42
  4. Qt + WINAPI + direct painting
    By JovianGhost in forum Qt Programming
    Replies: 8
    Last Post: 26th March 2010, 05:10
  5. How to use Signal through direct connection
    By santosh.kumar in forum Qt Programming
    Replies: 1
    Last Post: 14th December 2007, 07:07

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.