Results 1 to 4 of 4

Thread: Pointers and Q_PROPERTY

  1. #1
    Join Date
    Feb 2006
    Posts
    2
    Thanks
    1
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Pointers and Q_PROPERTY

    Hi,

    I want to configure objects that are encapsulated in other objects using a configuration file and a plugin architecture, so I do not know in advance which objects are contained within the object. Is it possible to do this using the QObject:roperty() function?

    Example:
    Qt Code:
    1. class BInterface {
    2. public:
    3. virtual ~BInterface() {}
    4. virtual int foo() = 0;
    5. };
    6.  
    7. class B : public QObject, public BInterface
    8. {
    9. Q_OBJECT
    10. Q_PROPERTY(int b READ b WRITE setB );
    11. public:
    12. virtual ~B() {}
    13. virtual int foo() { return mv_b; }
    14. const int b() const { return mv_b; }
    15. void setB( const int b ) { mv_b = b; }
    16. private:
    17. int mv_b;
    18. };
    19.  
    20. class A : public QObject{
    21. Q_OBJECT
    22. Q_PROPERTY(BInterface* B READ B WRITE setB);
    23. public:
    24. A() { mv_B = NULL; }
    25. virtual ~A() { if(mv_B) delete mv_B; }
    26. const BInterface * B() { return mv_B; }
    27. void setB( const BInterface * B ) { if (mv_B) delete mv_B; mv_B = B; }
    28. private:
    29. BInterface * mv_B;
    30. };
    To copy to clipboard, switch view to plain text mode 

    what I want to do is something like:
    Qt Code:
    1. QObject * objA = new A();
    2. BInterface* b = a.property("B");
    3. b.setProperty("b", someValue);
    To copy to clipboard, switch view to plain text mode 
    can this be done at all?

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Pointers and Q_PROPERTY

    Quote Originally Posted by andersin
    can this be done at all?
    To some extent:
    Qt Code:
    1. #include <QtDebug>
    2.  
    3. #include <QCoreApplication>
    4. #include <QObject>
    5. #include <QVariant>
    6.  
    7. class BInterface
    8. {
    9. public:
    10. virtual int foo() = 0;
    11. };
    12.  
    13. class B : public QObject, public BInterface
    14. {
    15. Q_OBJECT
    16. Q_PROPERTY( int b READ b WRITE setB )
    17. public:
    18.  
    19. virtual int foo() { return mv_b; }
    20.  
    21. const int b() const { return mv_b; }
    22. void setB( int b ) { mv_b = b; }
    23.  
    24. private:
    25. int mv_b;
    26. };
    27.  
    28. class A : public QObject
    29. {
    30. Q_OBJECT
    31. Q_PROPERTY( QObject* B READ B WRITE setB )
    32. public:
    33. A( QObject *b = 0 ) : mv_B( b ) {}
    34. virtual ~A() { if(mv_B) delete mv_B; }
    35. QObject * B() { return mv_B; }
    36. void setB( QObject* B ) { if (mv_B) delete mv_B; mv_B = B; }
    37.  
    38. private:
    39. QObject* mv_B;
    40. };
    41.  
    42. int main( int argc, char **argv )
    43. {
    44. QCoreApplication app( argc, argv );
    45.  
    46. QObject *a = new A( new B() );
    47.  
    48. // QObject *a = new A();
    49. // a->setProperty( "B", 0 ); // works
    50.  
    51. // QObject *a = new A();
    52. // a->setProperty( "B", new B() ); // crashes
    53.  
    54. QObject* b1 = a->property( "B" ).value< QObject *>();
    55. if( b1 != 0 ) {
    56. b1->setProperty( "b", 1234 );
    57. }
    58. else {
    59. qDebug() << "b1 is null";
    60. }
    61.  
    62. QObject* b2 = a->property( "B" ).value< QObject *>();
    63. if( b2 != 0 ) {
    64. qDebug() << b2->property( "b" );
    65. }
    66. else {
    67. qDebug() << "b2 is null";
    68. }
    69.  
    70. return 0;
    71. }
    72.  
    73. #include "main.moc"
    To copy to clipboard, switch view to plain text mode 

    Output:
    $ ./properties
    QVariant(int, 1234)

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

    andersin (28th February 2006)

  4. #3
    Join Date
    Feb 2006
    Posts
    2
    Thanks
    1
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: Pointers and Q_PROPERTY

    Ok, that creates a workaround. The problem there is that I lose the type information of the property that I want to set.

    I want to write plugins, so I am forced to use QObject and the meta object. I hoped that I could use const char * QMetaProperty::typeName together with void QObject::inherits(const char*) to check if I can use a particular plugin for the property. Like so:

    Qt Code:
    1. // initialize the plugin loaders and all that jazz
    2.  
    3. QObject * pluginA = pluginLoaderForA.instance();
    4. QObject * pluginB = pluginLoaderForB.instance();
    5.  
    6. const QMetaObject * mobjA = pluginA->metaObject;
    7. QMetaProperty propA = mobj->property(mobj->indexOfProperty("B"));
    8. QString typeName = QString(propA.typeName());
    9. typeName.chop(1); //remove the * at the end
    10. if ( pluginB.inherits(typeName.toAscii().constData()) ) {
    11. // it inherits the object, so we can use it.
    12. pluginA.setProperty("B", QVariant::fromValue(pluginB));
    13. }
    To copy to clipboard, switch view to plain text mode 

    That is of course lost when I use QObject* as the type. On the other hand I am not sure if the setProperty still works. The object is still a QObject, but I doubt that the meta object stuff knows this.

    Now one solution would probably be to inherit the interface from QObject, since then I know about the interface in the meta object system. It gets tricky with multiple inheritance of interfaces though, since the inheritance path to QObject is not unique any longer.

    I guess I just need to provide the type of BInterface as a const char* property and force some naming scheme on the whole thing.

    p.s.: I figured out that the crash in your code is due to some QVariant stuff. This is how I got that to work

    Qt Code:
    1. // QObject *a = new A();
    2. // a->setProperty( "B", new B() ); // crashes
    3.  
    4. QObject *a = new A();
    5. a->setProperty("B", QVariant::fromValue(new B())); //works
    To copy to clipboard, switch view to plain text mode 

  5. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Pointers and Q_PROPERTY

    OK, another try:
    Qt Code:
    1. #include <QtDebug>
    2.  
    3. #include <QCoreApplication>
    4. #include <QMetaProperty>
    5. #include <QObject>
    6. #include <QVariant>
    7.  
    8. class BInterface : public QObject
    9. {
    10. Q_OBJECT
    11. public:
    12. virtual int foo() = 0;
    13. };
    14.  
    15. class B : public BInterface
    16. {
    17. Q_OBJECT
    18. Q_PROPERTY( int b READ b WRITE setB )
    19. public:
    20.  
    21. virtual int foo() { return mv_b; }
    22.  
    23. const int b() const { return mv_b; }
    24. void setB( int b ) { mv_b = b; }
    25.  
    26. private:
    27. int mv_b;
    28. };
    29.  
    30. Q_DECLARE_METATYPE( BInterface* );
    31.  
    32. lass A : public QObject
    33. {
    34. Q_OBJECT
    35. Q_PROPERTY( BInterface* B READ B WRITE setB )
    36. public:
    37. A( BInterface *b = 0 ) : mv_B( b ) {}
    38. virtual ~A() { if(mv_B) delete mv_B; }
    39.  
    40. BInterface * B() { return mv_B; }
    41. void setB( BInterface *B ) { if (mv_B) delete mv_B; mv_B = B; }
    42.  
    43. private:
    44. BInterface* mv_B;
    45. };
    46.  
    47. int main( int argc, char **argv )
    48. {
    49. QCoreApplication app( argc, argv );
    50.  
    51. QObject *a = new A();
    52. BInterface * b = new B();
    53. a->setProperty( "B", QVariant::fromValue( b ) );
    54.  
    55. const QMetaObject * metaObj = a->metaObject();
    56. int index = metaObj->indexOfProperty( "B" );
    57. if( index != -1 ) {
    58. QMetaProperty prop = metaObj->property( index );
    59. qDebug() << prop.typeName();
    60. }
    61. else {
    62. qDebug() << "property not found";
    63. }
    64.  
    65. BInterface *b1 = a->property( "B" ).value< BInterface *>();
    66. if( b1 != 0 ) {
    67. b1->setProperty( "b", 1234 );
    68. }
    69. else {
    70. qDebug() << "b1 is null";
    71. }
    72.  
    73. BInterface *b2 = a->property( "B" ).value< BInterface *>();
    74. if( b2 != 0 ) {
    75. qDebug() << b2->property( "b" );
    76. }
    77. else {
    78. qDebug() << "b2 is null";
    79. }
    80.  
    81. return 0;
    82. }
    83.  
    84. #include "main.moc"
    To copy to clipboard, switch view to plain text mode 

    Output:
    $ ./properties
    BInterface*
    QVariant(int, 1234)

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.