Results 1 to 10 of 10

Thread: Interface composition and QObject

  1. #1
    Join Date
    Feb 2006
    Location
    US
    Posts
    173
    Thanks
    16
    Thanked 5 Times in 5 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default Interface composition and QObject

    The following was never really answered ... see thread for background.

    Is it a true statement that "you can't use Qt meta-object system with interface composition"?

    With interface composition, it's necessary (at least with C++) to use multiple inheritance. Defined interfaces (abstract base classes that derive from QObject for introspection) are composed to provide a composite interface (via inheriting from multiple base interface classes).

    The Qt documentation implies that multiple inheritance of QObject is not supported. However, for me it is working quite well as long as my base classes have unique slot and signal names ... this ambiguity being a problem with multiple inheritance in general ... not just limited to Qt. Is there some other limitation?

    The parallel in Java for what I'm trying to do is "a class that implements multiple interfaces".

  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: Interface composition and QObject

    Quote Originally Posted by brcain View Post
    The following was never really answered ... see thread for background.
    Then maybe you should continue the old thread?

    Quote Originally Posted by brcain View Post
    Is it a true statement that "you can't use Qt meta-object system with interface composition"?
    It depends how do you define an interface. If an interface is a class that contains only pure abstract methods (like in Java), then the answer is: "no, it isn't true".
    But in your case, the "interface" is a class derived from QObject, which obviously doesn't fit that definition.

    Quote Originally Posted by brcain View Post
    The Qt documentation implies that multiple inheritance of QObject is not supported.
    If the docs say it isn't supported then it means that it isn't supported, but not necessarily that it won't work.

    The biggest problem is that each signal or slot is internally represented by a number, so in each of the base classes will use the same number for different slots.

    Here's an example of qt_metacall:
    Qt Code:
    1. int Test::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
    2. {
    3. _id = QWidget::qt_metacall(_c, _id, _a);
    4. if (_id < 0)
    5. return _id;
    6. if (_c == QMetaObject::InvokeMetaMethod) {
    7. switch (_id) {
    8. case 0: show1(); break;
    9. case 1: show2(); break;
    10. }
    11. _id -= 2;
    12. }
    13. return _id;
    14. }
    To copy to clipboard, switch view to plain text mode 
    If you have several base classes then it should look like this:
    Qt Code:
    1. int Test::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
    2. {
    3. if( _id belongs to Base1 ) {
    4. _id = Base1::qt_metacall(_c, _id - base1offset, _a);
    5. }
    6. else if( _id belongs to Base2 ) {
    7. _id = Base1::qt_metacall(_c, _id - base2offset, _a);
    8. }
    9. if (_id < 0)
    10. return _id;
    11. ...
    12. }
    To copy to clipboard, switch view to plain text mode 
    or:
    Qt Code:
    1. Test::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
    2. {
    3. ...
    4. if (_c == QMetaObject::InvokeMetaMethod) {
    5. switch (_id) {
    6. case 0: Base1::someSlot1(); break;
    7. case 1: Base2::someSlot2(); break;
    8. ...
    9. }
    10. ...
    11. }
    To copy to clipboard, switch view to plain text mode 
    and of course you will have to write it yourself, as moc won't handle this (it only looks into the first base class).

    Another problem is that the QMetaObject for the derived class will be populated only with information about only one base class:
    Qt Code:
    1. const QMetaObject Test::staticMetaObject = {
    2. { &Base1::staticMetaObject, qt_meta_stringdata_Test,
    3. qt_meta_data_Test, 0 }
    4. };
    To copy to clipboard, switch view to plain text mode 
    While it should be something like this:
    Qt Code:
    1. const QMetaObject * otherBaseClasses[] = { &Base2::staticMetaObject, 0 };
    2. const QMetaObject Test::staticMetaObject = {
    3. { &Base1::staticMetaObject, qt_meta_stringdata_Test,
    4. qt_meta_data_Test, otherBaseClasses }
    5. };
    To copy to clipboard, switch view to plain text mode 

    In other words, you will have to do all of the work that moc does for you, it it's going to work.

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

    brcain (17th November 2006)

  4. #3
    Join Date
    Feb 2006
    Location
    US
    Posts
    173
    Thanks
    16
    Thanked 5 Times in 5 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: Interface composition and QObject

    Quote Originally Posted by jacek View Post
    It depends how do you define an interface. If an interface is a class that contains only pure abstract methods (like in Java), then the answer is: "no, it isn't true".
    But in your case, the "interface" is a class derived from QObject, which obviously doesn't fit that definition..
    Then I guess I was trying to use Qt for more that what it was created for ... interface composition with runtime introspection. This is considered an industry "best practice" technique.

    Do you know of another way to acheive this using Qt ... than the approach I was taking?

    Thanks,
    Ben
    Last edited by brcain; 17th November 2006 at 19:04.

  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: Interface composition and QObject

    Quote Originally Posted by brcain View Post
    Do you know of another way to acheive this ... than the approach I was taking?
    There's one library that caught my attention, by I didn't have time to check it: http://idioskopos.sourceforge.net/

  6. #5
    Join Date
    Feb 2006
    Location
    US
    Posts
    173
    Thanks
    16
    Thanked 5 Times in 5 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: Interface composition and QObject

    Using interface composition ... I also have to throw out signals and slots (as you mentioned above). This is the first design limitation that I've encountered with Qt. I'm not sure what to do to get around this one

    So, is interface composition just not used that often with Qt?

    I will look at idioskopos for the reflective programming. Thanks.

    But, there's still the signal/slot problem. I may have to switch to the Boost signals library (hoping it won't have the same multiple-inheritance limitation). But, Qt threads handle signals/slots seamlessly ... calling slots asynchronously when in a different thread. This limitation is very unfortunate.
    Last edited by brcain; 17th November 2006 at 19:46.

  7. #6
    Join Date
    Jan 2006
    Location
    Mountain View, CA
    Posts
    279
    Thanked 42 Times in 37 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Interface composition and QObject

    Quote Originally Posted by brcain View Post
    Then I guess I was trying to use Qt for more that what it was created for ... interface composition with runtime introspection. This is considered an industry "best practice" technique.
    Considered "best practice" by whom?
    Considered "best practice" for what purpose?

    It is important to approach C++/Qt with a fresh perspective and not try to enforce paradigms inherited from the baggage of a previously used language, e.g. Java. Think carefully about your intended goal rather than trying to implement some pattern just because that is what you used in the past.
    Save yourself some pain. Learn C++ before learning Qt.

  8. #7
    Join Date
    Feb 2006
    Location
    US
    Posts
    173
    Thanks
    16
    Thanked 5 Times in 5 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: Interface composition and QObject

    Quote Originally Posted by Chicken Blood Machine View Post
    It is important to approach C++/Qt with a fresh perspective and not try to enforce paradigms inherited from the baggage of a previously used language, e.g. Java.

    Save yourself some pain. Learn C++ before learning Qt.
    Normally I don't respond to this sort of stuff. But, this was clearly a rant. My statement is true ... was the "first" limitation that I've run into. That's actually a complement. I've been very impressed with Qt. However, there is obviously things Qt wasn't designed to do.

    Interface composition is not a language paradigm ... it's a design principle. And your comment on learning C++ before trying to learn Qt. Well, I've been doing C++ programming now for 15 years. So, does that make me qualified?

    BTW, I don't even develop in Java ... at least not professionally. But, I do try to follow today's best practice design principles ... some of which are embodied in other languages.

  9. #8
    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: Interface composition and QObject

    Quote Originally Posted by brcain View Post
    And your comment on learning C++ before trying to learn Qt. Well, I've been doing C++ programming now for 15 years. So, does that make me qualified?
    Look closely --- it wasn't a comment, but a signature. I'm sure it wasn't about you, but a general statement addressed to Qt newbies.

    Remember that you are trying to use interface composition on classes, not interfaces. Maybe instead of signals & slots, you could use observer pattern? There's an article that shows how to do it automagically using AspectC++.

  10. #9
    Join Date
    Feb 2006
    Location
    US
    Posts
    173
    Thanks
    16
    Thanked 5 Times in 5 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: Interface composition and QObject

    Quote Originally Posted by jacek View Post
    Maybe instead of signals & slots, you could use observer pattern?
    Observer pattern ... used it in the past ... prefer to use the listener pattern instead so the observer and observed don't depend upon one another.

    Note I really like the way Qt handles slots with multithreading ... very powerful capability ... automatically handling as an asynchronous event when in another thread. I may use the listener pattern with event queues to nicely handle the threading problems ... since I lose slots

    Thanks jacek ... maybe he wasn't trying to be personal. However, it sounded very condescending ... not necessary nor productive for a forum. I've noticed several who respond defensively to criticism in this forum. I've embraced Qt fully ... trying to use it fully ... with design patterns that I've used over the years.

  11. #10
    Join Date
    Jan 2006
    Location
    Mountain View, CA
    Posts
    279
    Thanked 42 Times in 37 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Interface composition and QObject

    Quote Originally Posted by brcain View Post
    Normally I don't respond to this sort of stuff. But, this was clearly a rant. My statement is true ... was the "first" limitation that I've run into.
    I wasn't ranting at all, I'm sorry you took it that way. I've learned to become very pragmatic over the years when moving from language to language. I was just suggesting that you consider your final goal rather than trying to use a design that may have made sense in the past, but that Qt has poor support for. My questions were perfectly reasonable: there is no "best practice" without qualification and different problems require different approaches. Often the suitability of these approaches is dictated by the tools and language used.

    The simple fact is that interface composition is perfectly possible, you just may have to give up the convenience of signals and slots. Since Java didn't provide this either, I see no real loss. It's certainly worth looking into what Boost signals gives you though.

    Oh, and trust me there's nothing defensive at all about my post. I am well aware of the limitations of Qt, just haven't come across anything that was unsurmountable yet.
    Save yourself some pain. Learn C++ before learning Qt.

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.