Results 1 to 10 of 10

Thread: QVariant and Plugin interfaces

  1. #1
    Join Date
    Jul 2007
    Posts
    121
    Thanks
    38
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default QVariant and Plugin interfaces

    I have interfaces obtained from plugins and these interface pointers are stuffed in a QList container. Then this container is shown in a combobox with smth. like:

    MyInterface* ptrInterface; // pointer to interface
    foreach(ptrInterface, m_container.List() )
    ui.combobox->insertItem(0,ptrInterface->Description(), QVariant(ptrInterface));

    Next, I am trying to retrieve the data associated with the combobox item:


    MyInterface* ptrInterface= qvariant_cast<MyInterface*>(ui.cmbModels->itemData(0));

    moc compiler complains that 'qt_metatype_id' : is not a member of 'QMetaTypeId<T>'.

    Indeed there is no place to define metatype for interface since interface methods are abstract.

    My question is: how to put interface into a combobox item data and then retrieve it? (I understand that currentIndex of combobox also points to a container, but I would rather retrieve the data from combobox item).

  2. #2
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QVariant and Plugin interfaces

    See Q_DECLARE_METATYPE in the documentation.
    qMetaTypeId() calls fail for a type that has not been declared with that macro.

    EDIT: also, qRegisterMetaType could be of some help.

    Regards

  3. #3
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QVariant and Plugin interfaces

    Otherwise, you could try adding QPointer containing the pointer to the interface as item data, and not directly the interface pointer.

    Regards

  4. #4
    Join Date
    Jul 2007
    Posts
    121
    Thanks
    38
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QVariant and Plugin interfaces

    Marcel, thank you for this and also previous replies. Your help is greatly appreciated. In this particular case the problem seems to be that abstract classes cannot be used with Q_DECLARE_METATYPE. The same thing is QPointer encapsulation of a pointer to an abstract class.

    If you have any code snipped that does it, can you please post it here ?

    Thanks.

  5. #5
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QVariant and Plugin interfaces

    I don't have code for this, but I think the reason for that is your interfaces do not inherit QObject.
    So, a possible solution is this.

    Anyway, could you say what errors do you get?

    Regards

  6. #6
    Join Date
    Jul 2007
    Posts
    121
    Thanks
    38
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QVariant and Plugin interfaces

    Here is how the interface class looks like with Q_DECLARE_METATYPE:

    class ModelInterface : public QObject
    {
    public:
    virtual ~ModelInterface() { }
    virtual QString Description () = 0;
    virtual int ID() = 0;
    virtual bool setImplementation(QString fname) = 0;
    };
    Q_DECLARE_INTERFACE(ModelInterface,
    "xxxx/1.0")
    Q_DECLARE_METATYPE(ModelInterface)

    It is defined in a header file (.h). Upon compiling I am getting following errors:

    >xxxx\ModelInterface.h(14) : error C2259: 'ModelInterface' : cannot instantiate abstract class
    2> due to following members:
    2> 'QString ModelInterface::Description(void)' : is abstract
    2> xxxx\ModelInterface.h(7) : see declaration of 'ModelInterface::Description'
    2> 'int ModelInterface::ID(void)' : is abstract
    ....

    When I take out Q_DECLARE_METATYPE everything compiles OK

    (Adding Q_OBJECT to the class declaration does not change anything)

  7. #7
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QVariant and Plugin interfaces

    I think you can do this:
    Qt Code:
    1. typedef struct InterfaceMask {
    2. MyInterface *interfacePtr;
    3. InterfaceMask() {
    4. interfacePtr = NULL;
    5. }
    6. InterfaceMask(MyInterface* ptr) {
    7. interfacePtr = ptr;
    8. }
    9. } InterfaceMask;
    10.  
    11. Q_DECLARE_METATYPE(InterfaceMask);
    To copy to clipboard, switch view to plain text mode 

    Next, when adding the interfaces to the combo:

    Qt Code:
    1. MyInterface* ptrInterface; // pointer to interface
    2. foreach(ptrInterface, m_container.List() )
    3. {
    4. InterfaceMask *mask = new InterfaceMask(ptrInterface);
    5. ui.combobox->insertItem(0,ptrInterface->Description(), QVariant(mask));
    6. }
    To copy to clipboard, switch view to plain text mode 


    Finally, you can retrieve it with:
    Qt Code:
    1. InterfaceMask *mask = qvariant_cast<InterfaceMask*>(ui.cmbModels->itemData(0));
    2. MyInterface* ptrInterface= mask->interfacePtr;
    To copy to clipboard, switch view to plain text mode 

    BTW, I didn't test this, but should work.

    Regards

  8. #8
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QVariant and Plugin interfaces

    Ok. I think I have done it.
    Qt Code:
    1. #include <QtCore/QCoreApplication>
    2. #include "test.h"
    3.  
    4. int main(int argc, char *argv[])
    5. {
    6. QCoreApplication a(argc, argv);
    7.  
    8. QVariant v = QVariant::fromValue(new holder(new impl()));
    9. holder *h = qvariant_cast<holder*>(v);
    10.  
    11.  
    12. return a.exec();
    13. }
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. #ifndef TEST_H
    2. #define TEST_H
    3.  
    4. #include <QtCore>
    5.  
    6. class intf
    7. {
    8. public:
    9. virtual void xxx() = 0;
    10. };
    11.  
    12. class impl : public intf
    13. {
    14. int x;
    15. public:
    16. impl()
    17. {
    18. x = 5;
    19. }
    20.  
    21. void xxx()
    22. {
    23. }
    24. };
    25.  
    26. typedef struct holder
    27. {
    28. intf* ptr;
    29. char* xx;
    30. holder()
    31. {
    32. ptr = NULL;
    33. xx = new char[10];
    34. strcpy(xx, "lksjd");
    35. }
    36.  
    37. holder(intf* p)
    38. {
    39. ptr = p;
    40. xx = new char[10];
    41. strcpy(xx, "lksjd");
    42. }
    43. };
    44.  
    45. Q_DECLARE_METATYPE(holder)
    46. Q_DECLARE_METATYPE(holder*)
    47.  
    48. #endif
    To copy to clipboard, switch view to plain text mode 
    After performing the cast in main, I get the same structure, which is good .
    Those class members are there just to assure I'm getting the same thing back from the qvariant.

    Please note:
    Qt Code:
    1. Q_DECLARE_METATYPE(holder)
    2. Q_DECLARE_METATYPE(holder*)
    To copy to clipboard, switch view to plain text mode 
    Also holder*( has to be registered, otherwise it won't work. I forgot to mention this earlier.

    I thing you too can use this.(sorry for the messy code).
    Instead of an "impl" instance you can pass the pointer to your interface when building the qvariant.


    Regards
    Last edited by marcel; 5th August 2007 at 22:08.

  9. #9
    Join Date
    Jul 2007
    Posts
    121
    Thanks
    38
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QVariant and Plugin interfaces

    I was actually typing the response when I got the reply from you. Your help is extremely valuable, especially for QT novice like myself. Your first option did not work, as you already know, so I would not bore you with the details .

    Thank you again for your efforts and time spend helping us all here on this forum. I am taking your latest submission for incorporation in the code. I am sure it will work.

  10. #10
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QVariant and Plugin interfaces

    No problem, I am in a kind of vacation .
    Yes, it should work since I tested it before.
    However you should use only the idea because the code I posted is a crap ( but it will compile and work anyway ). It was meant only as a 5 minute proof to the idea.

    Anyway, the code in the previous post is basically the same as the last one and it would have worked if you registered the pointer to holder type. (e.g. Q_REGISTER_METATYPE(holder*)).

    Regards

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

    QPlace (6th August 2007)

Similar Threads

  1. Plugin woes
    By stevey in forum Qt Programming
    Replies: 8
    Last Post: 24th July 2006, 01:30

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.