Results 1 to 13 of 13

Thread: templates and Q_OBJECT

  1. #1
    Join Date
    Jan 2006
    Location
    Munich, Germany.
    Posts
    111
    Thanks
    29
    Thanked 3 Times in 2 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Windows

    Default templates and Q_OBJECT

    hello everyone,
    I get the error:
    .\Logger.h(20): Error: Template classes not supported by Q_OBJECT
    when I have the following ...

    Qt Code:
    1. template<typename T>
    2.  
    3. class Logger : public QThread
    4. {
    5. Q_OBJECT
    6.  
    7. public:
    8. Logger( T* fridge){}
    9. virtual ~Logger();
    10. ...
    To copy to clipboard, switch view to plain text mode 

    What can I do?
    I want to pass an instance of any class (provided that the class has a function x()) to the constructor of Logger, so that the Logger can call the func. Is that possible?

    thanks
    K

  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: templates and Q_OBJECT

    Quote Originally Posted by TheKedge
    I want to pass an instance of any class (provided that the class has a function x()) to the constructor of Logger, so that the Logger can call the func. Is that possible?
    Of course it is. That's what interfaces are for.

    Qt Code:
    1. class MonitoredObject
    2. {
    3. public:
    4. virtual QString status() = 0;
    5. };
    6.  
    7. class Fridge : public SomeClass, public MonitoredObject
    8. {
    9. ...
    10. QString status() { if( rand() % 2 ) return "OK"; else return "ON FIRE"; }
    11. ...
    12. };
    To copy to clipboard, switch view to plain text mode 

  3. #3
    Join Date
    Jan 2006
    Location
    Munich, Germany.
    Posts
    111
    Thanks
    29
    Thanked 3 Times in 2 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Windows

    Default Re: templates and Q_OBJECT

    ok, but I'm not sure if that's what I want. I was thinking of something like
    Qt Code:
    1. logger::logger (<T*> thingToLog):thing(thingToLog)
    2. {
    3. <T*> thing;
    4. }
    5. logger::doJob()
    6. {
    7. thing->logData();
    8. }
    To copy to clipboard, switch view to plain text mode 

    and the object which wants logging to be done makes an instance of a logger thus:
    Qt Code:
    1. {
    2. logger = new logger(this);
    To copy to clipboard, switch view to plain text mode 
    and provides a func which decides what and how to log things
    Qt Code:
    1. logData()
    2. {
    3. logger->log(getOneDatum());
    4. logger->log(getAnotherDatum());
    5. logger->flush();
    6. }
    To copy to clipboard, switch view to plain text mode 

    My logger class has a fairly big interface which doesn't really have much to do with the class being logged. I just thought that that might be a good way of doing things since I don't inherit any interface - is it a bad idea? is it a question of having friends or having inheritance? what do you recommend?
    thanks for the help
    Kev

  4. #4
    Join Date
    Jan 2006
    Location
    Munich, Germany.
    Posts
    111
    Thanks
    29
    Thanked 3 Times in 2 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Windows

    Default Re: templates and Q_OBJECT

    ahh, one more thing:
    when I try:
    Qt Code:
    1. class Refrigerator : public BaseDevice, public Logger
    To copy to clipboard, switch view to plain text mode 
    thus inheriting the logger

    I get a error on trying to connect things:

    Qt Code:
    1. connect(view, SIGNAL(elementClicked(int /*index*/, int /*state*/)), fridge, SLOT(setSwitch(int /*index*/, int /*state*/)));
    To copy to clipboard, switch view to plain text mode 

    My logger is
    Qt Code:
    1. class Logger : public QThread
    To copy to clipboard, switch view to plain text mode 

    and the error is can't uniquely convert from class Refrigerator * to const class QObject *

    Will I have to restructure Logger before inheriting it?

    K

  5. #5
    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: templates and Q_OBJECT

    Quote Originally Posted by TheKedge
    when I try:
    class Refrigerator : public BaseDevice, public Logger
    thus inheriting the logger

    I get a error on trying to connect things
    This is a Qt limitation. The class that inherits QObject must be first:
    Qt Code:
    1. class Refrigerator : public Logger, public BaseDevice
    To copy to clipboard, switch view to plain text mode 

    Quote Originally Posted by TheKedge
    connect(view, SIGNAL(elementClicked(int /*index*/, int /*state*/)), fridge, SLOT(setSwitch(int /*index*/, int /*state*/)));
    I'm not sure if Qt will like those comments.

  6. #6
    Join Date
    Jan 2006
    Location
    Munich, Germany.
    Posts
    111
    Thanks
    29
    Thanked 3 Times in 2 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Windows

    Default Re: templates and Q_OBJECT

    ok, but my BaseDevice is also a QObject ..

    class BaseDevice : public QThread, public CommPort
    where CommPort is not a Qt-based class

    (Qt is fine with the comments, they just expand in the macro as comments)

    is the template solution (my original scheme) also a limited by Qt?
    i.e. Template classes not supported by Q_OBJECT

    Qt Code:
    1. #include <QtCore>
    2. template<class T>
    3.  
    4. class thing
    5. {
    6. Q_OBJECT
    7. public:
    8. thing( T* fridge):m_fridge(fridge) { }
    9. virtual ~thing() { }
    10.  
    11. private:
    12. T* m_fridge;
    13.  
    14. };
    To copy to clipboard, switch view to plain text mode 

  7. #7
    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: templates and Q_OBJECT

    Quote Originally Posted by TheKedge
    My logger class has a fairly big interface which doesn't really have much to do with the class being logged. I just thought that that might be a good way of doing things since I don't inherit any interface - is it a bad idea? is it a question of having friends or having inheritance? what do you recommend?
    First of all you create a separate thread for each device. If there is a lot of such devices, you will loose a lot of time for context switching. Maybe it will be better if a single logger thread would serve more than one device?

    The easiest way is to use an interface, but this requires a small change in all classes that need logging --- you must add another base class. The good news is that you will be able to treat all kinds of devices the same way and for example create a list of pointers that you can traverse and collect data (just be careful when you delete/remove someting).

    Another solution is to stick with templates, but the problem is that Qt doesn't handle them. One way is to split the implementation into two classes.

    Qt Code:
    1. class BaseLogger
    2. {
    3. public:
    4. virtual void logData() = 0;
    5. };
    6.  
    7. template< class T >
    8. class Logger : public BaseLogger
    9. {
    10. public:
    11. Logger( T* device );
    12. void logData();
    13. ...
    14. };
    15.  
    16. class LoggerThread : public QThread
    17. {
    18. Q_OBJECT
    19. public:
    20. // user will have to create Logger himself
    21. LoggerThread( BaseLogger * );
    22.  
    23. // or like this, but I'm not sure if Qt will like it:
    24. template< class T >
    25. static LoggerThread * createLoggerFor( T* device );
    26.  
    27. void run()
    28. {
    29. if( logger != 0 ) {
    30. logger->logData();
    31. }
    32. }
    33. ...
    34. };
    To copy to clipboard, switch view to plain text mode 
    After small modifications single logger thread will be able to handle multiple devices, but IMO the interface approach is cleaner.

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

    TheKedge (14th September 2006)

  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: templates and Q_OBJECT

    Quote Originally Posted by TheKedge
    ok, but my BaseDevice is also a QObject ..

    class BaseDevice : public QThread, public CommPort
    where CommPort is not a Qt-based class
    Qt doesn't use virtual inheritance, so you would end with an object that represents two distinct threads at the same time. Only one of the base classes can be derived from QObject.

    Quote Originally Posted by TheKedge
    Qt is fine with the comments, they just expand in the macro as comments
    The question is whether Qt will be able to remove them later when it comes to signature normalization during connection setup.

    Quote Originally Posted by TheKedge
    is the template solution (my original scheme) also a limited by Qt?
    i.e. Template classes not supported by Q_OBJECT
    Yes, moc can't generate code for template classes, since they require special treatment.

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

    TheKedge (14th September 2006)

  11. #9
    Join Date
    Jan 2006
    Location
    Munich, Germany.
    Posts
    111
    Thanks
    29
    Thanked 3 Times in 2 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Windows

    Default Re: templates and Q_OBJECT

    Jacek,
    they are great answers!
    thanks for the info, especially on Q_OBJECT and threads; I'll put your knowledge to my good use! thanks,
    K

  12. #10
    Join Date
    Jan 2006
    Location
    Kerala
    Posts
    371
    Thanks
    76
    Thanked 37 Times in 32 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: templates and Q_OBJECT

    We can't solve problems by using the same kind of thinking we used when we created them

  13. #11
    Join Date
    Jan 2006
    Location
    Kerala
    Posts
    371
    Thanks
    76
    Thanked 37 Times in 32 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: templates and Q_OBJECT

    @jacek

    Qt Code:
    1. template< class T > static LoggerThread * createLoggerFor( T* device );
    To copy to clipboard, switch view to plain text mode 

    could u please expain what that fn will do ?

    assuming
    Qt Code:
    1. template< class T >
    2. class LoggerThread : public QThread {
    To copy to clipboard, switch view to plain text mode 
    We can't solve problems by using the same kind of thinking we used when we created them

  14. #12
    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: templates and Q_OBJECT

    Quote Originally Posted by sunil.thaha
    could u please expain what that fn will do ?

    assuming [...]
    I don't know what it should do with your assumption, but my idea was not to make LoggerThread a template.

    Compare this two:
    Qt Code:
    1. LoggerThread *thread = new LoggerThread( new Logger< Fridge >( fridge ) );
    2. LoggerThread *thread = LoggerThread::createLoggerFor< Fridge >( fridge );
    To copy to clipboard, switch view to plain text mode 
    In the second example user doesn't have to know anything about the Logger class and yes, your source code is 1 byte shorter

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

    sunil.thaha (15th September 2006)

  16. #13
    Join Date
    Jan 2006
    Location
    Kerala
    Posts
    371
    Thanks
    76
    Thanked 37 Times in 32 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: templates and Q_OBJECT

    My assumption was wrong.

    did not notice the static function
    We can't solve problems by using the same kind of thinking we used when we created them

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.