Page 1 of 2 12 LastLast
Results 1 to 20 of 36

Thread: Minimum required to emit a signal

  1. #1
    Join Date
    Jun 2012
    Posts
    193
    Thanks
    20
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Minimum required to emit a signal

    I've been using signals and slots with classes derived from classes created in Qt Designer. In addition to inheriting from the class created with Designer, I inherit from QDialog or QWidget (monkey see monkey do).

    I dutifully add the Q_OBJECT in the derived class header file, and everything seems work. I can connect signals of built-in widgets to my own custom slots and emit (and connect) my own custom signals. I must confess I don't understand what's going on "under the covers".

    I have some utility classes that really aren't GUI oriented. But, I can see it would be handy for some of the methods in these clases to emit signals that could be connected to new widgets I'd create for displaying some diagnostic information.

    I think I need the Q_OBJECT in these class declarations to have a signals: keyword

    But, what what do should I inherit from? When I tried to public inherit only from QDialog or QWidget, the compiler complains about not being able to access private data in the base class. And that doesn't seem clean, given my derived class is only similar to a QDialog or QWidget in that it would emit a signal.

    So, what do I need just to create a signal?

    Thanks,

    Dave Thomas

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

    Default Re: Minimum required to emit a signal

    Quote Originally Posted by davethomaspilot View Post
    But, what what do should I inherit from?
    Inherit QObject.
    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.


  3. #3
    Join Date
    Jun 2012
    Posts
    193
    Thanks
    20
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Minimum required to emit a signal

    Thanks for the quick reply.

    I get similar error messages when inheriting from QObject:

    1>c:\users\dave\my software\stats helper\heat_message.h(127): error C2248: 'QObject:perator =' : cannot access private member declared in class 'QObject'
    1> c:\opencv\dep\qt\qt-everywhere-opensource-src-4.8.2\include\qtcore\../../src/corelib/kernel/qobject.h(333) : see declaration of 'QObject:perator ='
    1> c:\opencv\dep\qt\qt-everywhere-opensource-src-4.8.2\include\qtcore\../../src/corelib/kernel/qobject.h(112) : see declaration of 'QObject'
    1> This diagnostic occurred in the compiler generated function 'HeatMessage &HeatMessage:perator =(const HeatMessage &)'
    1> main_window.cpp

    1>c:\users\dave\my software\stats helper\heat_message.h(127): error C2248: 'QObject::QObject' : cannot access private member declared in class 'QObject'
    1> c:\opencv\dep\qt\qt-everywhere-opensource-src-4.8.2\include\qtcore\../../src/corelib/kernel/qobject.h(333) : see declaration of 'QObject::QObject'
    1> c:\opencv\dep\qt\qt-everywhere-opensource-src-4.8.2\include\qtcore\../../src/corelib/kernel/qobject.h(112) : see declaration of 'QObject'
    1> This diagnostic occurred in the compiler generated function 'HeatMessage::HeatMessage(const HeatMessage &)'
    1> moc_collect_stats.cpp
    1>c:\users\dave\my software\stats helper\heat_message.h(127): error C2248: 'QObject::QObject' : cannot access private member declared in class 'QObject'
    1> c:\opencv\dep\qt\qt-everywhere-opensource-src-4.8.2\include\qtcore\../../src/corelib/kernel/qobject.h(333) : see declaration of 'QObject::QObject'
    1> c:\opencv\dep\qt\qt-everywhere-opensource-src-4.8.2\include\qtcore\../../src/corelib/kernel/qobject.h(112) : see declaration of 'QObject'
    1> This diagnostic occurred in the compiler generated function 'HeatMessage::HeatMessage(const HeatMessage &)'
    1> moc_main_window.cpp
    1>c:\users\dave\my software\stats helper\heat_message.h(127): error C2248: 'QObject::QObject' : cannot access private member declared in class 'QObject'
    1> c:\opencv\dep\qt\qt-everywhere-opensource-src-4.8.2\include\qtcore\../../src/corelib/kernel/qobject.h(333) : see declaration of 'QObject::QObject'
    1> c:\opencv\dep\qt\qt-everywhere-opensource-src-4.8.2\include\qtcore\../../src/corelib/kernel/qobject.h(112) : see declaration of 'QObject'
    1> This diagnostic occurred in the compiler generated function 'HeatMessage::HeatMessage(const HeatMessage &)'
    1> Generating Code...
    1>
    1>Build FAILED.
    1>
    1>Time Elapsed 00:00:07.10

    It compiles fine without the Q_OBJECT and inheritance from QObject.

    Do I need a different constructor that passes 0 to the Bo

    Here's the relevant part of header file:
    Qt Code:
    1. #ifndef HEAT_MESSAGE_H
    2. #define HEAT_MESSAGE_H
    3.  
    4. #include <QtCore/QCoreApplication>
    5. #include <QRegExp>
    6. #include <QMap>
    7. #include <iostream>
    8. #include <fstream>
    9. #include <QTextStream>
    10. #include <QWidget>
    11.  
    12. class HeatMessage : public QObject
    13. {
    14. Q_OBJECT
    15.  
    16. public:
    17. HeatMessage(QByteArray &,QObject *parent=0);
    18. HeatMessage(void);
    19. QList<HeatRecord> heat_records;
    20. float get_time(char lane, char id);
    21. float get_sum_time(char lane);
    22. char get_result(char lane);
    23. int get_race(void) {return heat_records.begin()->get_race();};
    24. int get_heat(void) {return heat_records.begin()->get_heat();};
    25. int num_dogs(char lane);
    26. static void print_header(QTextStream &);
    27. void print(char lane, QTextStream &);
    28. void print(QTextStream &);
    To copy to clipboard, switch view to plain text mode 



    };
    #endif

  4. #4
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,593
    Thanks
    13
    Thanked 1,587 Times in 1,516 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Minimum required to emit a signal

    The QObject copy and assignment constructors are declared private. You cannot copy a QObject and will get these sort of errors if you attempt to do that.

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

    Default Re: Minimum required to emit a signal

    You can't create copies or assignments to QObject instances. You probably have an assignment operator in your class (or the compiler tries to create one for you based on your code). This is not possible.
    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.


  6. #6
    Join Date
    Jun 2012
    Posts
    193
    Thanks
    20
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Minimum required to emit a signal

    Hmm, I don't see anthing like that, unless the following fragment (which is called from a method in a different QWidget class)

    Qt Code:
    1. HeatMessage hm(msg);
    2. emit new_heat(hm);
    To copy to clipboard, switch view to plain text mode 

    Do you have a suggestion on how to find the offending code?

    Thanks,

    Dave Thomas

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

    Default Re: Minimum required to emit a signal

    What is in heat_message.h file in line 127 (and around)?
    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.


  8. #8
    Join Date
    Jun 2012
    Posts
    193
    Thanks
    20
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Minimum required to emit a signal

    That's the last line in the header file (the }

    Not very useful.

    [code]

    void print(char lane, QTextStream &);
    void print(QTextStream &);



    line 127: };

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

    Default Re: Minimum required to emit a signal

    Please post the whole file as an attachment.
    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.


  10. #10
    Join Date
    Jun 2012
    Posts
    193
    Thanks
    20
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Minimum required to emit a signal

    Here it is:


    Added after 27 minutes:


    A HeatMessage object is passed as the argument emitted signals in a couple of places in other files. If I eliminate those calls, the complaints about referencing a private assignment operator in the base class is eliminated. However, I get some unresolved externals at link time:

    1>heat_message.obj : error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall HeatMessage::metaObject(void)const " (?metaObject@HeatMessage@@UBEPBUQMetaObject@@XZ)
    1>heat_message.obj : error LNK2001: unresolved external symbol "public: virtual void * __thiscall HeatMessage::qt_metacast(char const *)" (?qt_metacast@HeatMessage@@UAEPAXPBD@Z)
    1>heat_message.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall HeatMessage::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@HeatMessage@@UAEHW4Call@QMetaObject@ @HPAPAX@Z)
    1>debug\\Stats Helper.exe : fatal error LNK1120: 3 unresolved externals
    1>

    Maybe those are result of my quick hack to eliminate code that perhaps caused an implicit copy of a HeatMessage object.

    But, now I'm thinking this isn't such a good idea, if I can't pass QObjects as arguments of emitted signals. Is that, in fact, a limitation I need to deal with. Would passing by reference avoid the issue?

    Thanks,
    Attached Files Attached Files
    Last edited by davethomaspilot; 21st February 2013 at 13:08.

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

    Default Re: Minimum required to emit a signal

    How are you using both these classes? Can you show us some code that creates instances of them, etc.?

    One thing that I can immediately see that it is incorrect is this:

    Qt Code:
    1. QList<HeatRecord> heat_records;
    To copy to clipboard, switch view to plain text mode 

    This requires HeatRecord to be copyable, which it is not. You can only have this:

    Qt Code:
    1. QList<HeatRecord*> heat_records;
    To copy to clipboard, switch view to plain text mode 
    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.


  12. #12
    Join Date
    Jun 2012
    Posts
    193
    Thanks
    20
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Minimum required to emit a signal

    Changing the signal prototypes to use HeatMessage & instead of HeatMessage (and one of my methods with a HeatMessage arg) also eliminated the private data compile errors. However, i still get the unresolved externals. Chasing that now.

    heat_message.obj : error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall HeatMessage::metaObject(void)const " (?metaObject@HeatMessage@@UBEPBUQMetaObject@@XZ)
    1>heat_message.obj : error LNK2001: unresolved external symbol "public: virtual void * __thiscall HeatMessage::qt_metacast(char const *)" (?qt_metacast@HeatMessage@@UAEPAXPBD@Z)
    1>heat_message.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall HeatMessage::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@HeatMessage@@UAEHW4Call@QMetaObject@ @HPAPAX@Z)
    1>debug\\Stats Helper.exe : fatal error LNK1120: 3 unresolved externals

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

    Default Re: Minimum required to emit a signal

    Always pass pointers to QObjects in signals, never references nor copies.

    The errors you posted are related to not running qmake after adding Q_OBJECT macro to a class.
    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.


  14. #14
    Join Date
    Jun 2012
    Posts
    193
    Thanks
    20
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Minimum required to emit a signal

    Example usage:

    connect(this,SIGNAL(new_heat(HeatMessage &)),collect_stats,SLOT(new_heat(HeatMessage &)));

    Signal emitted after constructing the HeatMessage like this:
    Qt Code:
    1. if (msg[len - 7] == 'X')
    2. i
    3. {
    4. HeatMessage hm(msg);
    5. emit new_heat(hm);
    6. fd = fopen("console_data.txt","a");
    7.  
    8. fprintf(fd,"%s\n", msg.data());
    9. fclose(fd);
    10.  
    11. msg.clear();
    12. }
    To copy to clipboard, switch view to plain text mode 

    That's after changing the signal to use a HeatMessage & instead of a HeatMessage. Compiles now, doesn't link. And, I think it would segfault anyway, since hm will go out of scope before it's used in the slot.

    Always pass pointers to QObjects in signals, never references nor copies.
    Our posts crossed. I'll try that, and

    DOH! of course. I'll redo the qmake.

    Thanks,

    Dave Thomas

    So, I guess I'd have to do a "new" to create a HeatMessage, pass the resulting pointer in the signal, then delete in the slot?

    Or, will some other memory management mechanism try to handle it since it's a Q_OBJECT?

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

    Default Re: Minimum required to emit a signal

    Quote Originally Posted by davethomaspilot View Post
    So, I guess I'd have to do a "new" to create a HeatMessage, pass the resulting pointer in the signal, then delete in the slot?
    It depends on the object. HeatMessage doesn't need to inherit QObject as far as your code is concerned. It doesn't have any signals or slots. Same goes for HeatRecord. Maybe we misunderstood each other. I understood that you wanted some objects of yours to be able to emit signals but now I see that you wanted them to be emitted as arguments to signals. Is that correct?
    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.


  16. #16
    Join Date
    Jun 2012
    Posts
    193
    Thanks
    20
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Minimum required to emit a signal

    No, I want methods in the HeatRecord and/or HeatMessage to emit signals in addition to objects of these types to be passed as arguments.

    Those classes parse text data and understand a specific text data format. I'm adding some new syntax to include additional diagnostics about the RF channel integrity and locating the new code that recognizes the new packet signatures seem to make the most sense.

    Rather than just printing to QDebug(), I was going to add a widget with slots to display that data.

    So, yes I DO want to send signals from methods in a HeatMessage and/or HeatRecord class. But, maybe it's not worth it, if doing that implies more complicated memory management, since I now know signals can contain only pointers to QObjects, not references or copies.

    Thanks,

    Dave Thomas

    Sorry for the confusion--I just deleted the signals: from the header file until I got a successful build with the Q_Object.

    The method I'd add would simply send a HeatRecord to a slot in a different class if the content matched a specified RegExp.

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

    Default Re: Minimum required to emit a signal

    Quote Originally Posted by davethomaspilot View Post
    No, I want methods in the HeatRecord and/or HeatMessage to emit signals in addition to objects of these types to be passed as arguments.
    So what sense does it make to create an object just to emit it in a signal and destroy it right away? What signals could it possibly emit? I think you have a serious design problem... Maybe instead of inheritance you should use composition? I mean have some persistent object that emits signals "on behalf" of value-based HeatRecord and HeatMessage objects.
    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.


  18. #18
    Join Date
    Jun 2012
    Posts
    193
    Thanks
    20
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Minimum required to emit a signal

    I don't create an object just to emit a signal. The object consists of data and methods to parse the data to get interesting data.

    The entire object is passed to slots. Not just the data, but the methods to access the data in convenient ways are encapsulated with the data--standard object oriented design. The objects don't exist for long, but so what? You're suggesting that they shouldn't be objects because of this?

    But maybe that's a consideration for QObjects? And for that reason, don't create them in situations like this?

    I think you're saying it doesn't make sense to inherit from QObject just to send a signal. Fair enough.

    Thanks,

    Dave Thomas

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

    Default Re: Minimum required to emit a signal

    Quote Originally Posted by davethomaspilot View Post
    I don't create an object just to emit a signal. The object consists of data and methods to parse the data to get interesting data.
    You said yourself:
    So, I guess I'd have to do a "new" to create a HeatMessage, pass the resulting pointer in the signal, then delete in the slot?
    Which means you want to create an object, emit it and destroy it. So the only two objects that could possibly connect to a signal emitted by this short-lived object are the sender and the receiver. And both of them can query the state of the object directly, without signals.

    The objects don't exist for long, but so what? You're suggesting that they shouldn't be objects because of this?
    I'm suggesting they shouldn't be emitting any signals.

    I think you're saying it doesn't make sense to inherit from QObject just to send a signal. Fair enough.
    No, that's not what I'm saying. I'm saying it doesn't make sense to emit a signal that nobody can use.
    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. #20
    Join Date
    Jun 2012
    Posts
    193
    Thanks
    20
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Minimum required to emit a signal

    The constructor for the HeatMessage looks at the passed QByteArray to see if it looks like a set of valid HeatRecords This includes making sure it has an integral number of 16 bytes, and finding record boundaries for creating HeatRecords.

    HeatRecords are constructed from data passed to the HeatMessage constructor and added to a list of all the HeatRecords found in the HeatMessage.

    The HeatRecord constructor parses the bytes passed and saves data in private data members. Methods of the HeatRecord class allow encapsulate access of things like race number, heat number, win/loss--insulating code that wants that information from having to know the byte layout of a HeatRecord or HeatMessage. Sure, code that creates the HeatMessage could dive right into the data, but knowledge of the data format should be encapsulted in the HeatMessage class. That's the motivation for creating an object, not for simply creating a signal.

    However, I'm now adding a new record to a communication protocol, that's sort of like "out of band" data. It contains things like "number of retries", RF signal strength, "number of dropped pakets" It isn't a valid HeatRecord (which is a data format I can't modify), and I'd like to show its data in another Widget (to be developed). I'm considering using a signal, so a connect can be used to send these new type records to a widget that extracts data from and displays these new type of records.

    So, the motivation for creating a signal is to allow the data parsed in the HeatMessage/HeatRecord constructor to be consumed by other widgets as defined in the widgets that create the HeatMessages.

    So, yes, the object would get created, used in the slot code, then discarded. But much more is going on than simply sending the signal. Performance is not an issue-- the HeatMessages are only a few hundred bytes and get created no more frequently than a few minutes apart.

    Why shouldn't I be emitting any signals? Isn't this what they are designed fo? The signal indicates "bytes matching this signature were found", and provides the object which has this data along with the surrounding records and accessor methods for display by unspecified widget. Association with a widget(s) is done not by the HeatMessage/HeatRecord class, but in classes that create them.

    Thanks,


    Added after 19 minutes:


    "No, that's not what I'm saying. I'm saying it doesn't make sense to emit a signal that nobody can use."

    Thinking about it some more--I guess the problem is the connect, since it would need to be done before the object got created for signals emitted during construction to be handled. But, I'd need the pointer to the newly created object to do the connect.

    Obviously, I can get it done without using a signal. Just thought that was a "slick" way of doing it. Not so much now.

    Thanks,

    Dave Thomas
    Last edited by davethomaspilot; 21st February 2013 at 16:58.

Similar Threads

  1. Emit signal outside run() in QThread
    By naturalpsychic in forum Qt Programming
    Replies: 4
    Last Post: 26th March 2012, 16:31
  2. How to decide which SIGNAL to emit?
    By TheIndependentAquarius in forum Qt Programming
    Replies: 2
    Last Post: 22nd November 2011, 15:09
  3. Replies: 2
    Last Post: 3rd May 2011, 20:22
  4. how to know which button emit the signal?
    By coder1985 in forum Qt Programming
    Replies: 2
    Last Post: 12th January 2008, 14:26
  5. emit a signal
    By Morea in forum Qt Programming
    Replies: 2
    Last Post: 27th February 2006, 11:14

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.