Results 1 to 12 of 12

Thread: Problem emitting singal with object-pointer as argument

  1. #1
    Join Date
    May 2007
    Posts
    91
    Thanks
    60
    Qt products
    Qt4
    Platforms
    Windows

    Default Problem emitting singal with object-pointer as argument

    The code is as below,
    Qt Code:
    1. class MyRectItem : public QObject, public QGraphicsRectItem
    2. {
    3. Q_OBJECT
    4. public:
    5. ...
    6. MyElement* pE;
    7. signals:
    8. void itemSelected(MyElement* pE);
    9. };
    10.  
    11. class MyView : public QMainWindow
    12. {
    13. Q_OBJECT
    14. public slots:
    15. void toTreeWidget(MyElement* pE);
    16. };
    To copy to clipboard, switch view to plain text mode 

    In myview.cpp,
    Qt Code:
    1. MyRectItem *i = new MyRectItem(x, y, w, h);
    2. QObject::connect(i, SIGNAL(itemSelected(pE)), this, SLOT(toTreeWidget(i->pE)));
    To copy to clipboard, switch view to plain text mode 

    Why this doesn't work ??
    Does this have something to do with using the object-pointer as argument of signal?

  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: Problem emitting singal with object-pointer as argument

    First use qRegisterMetaType to register the MyElement* type. This is required when passing custom types between signals and slots.

    Second, when connecting signals and slots, don't pass the objects as arguments:
    Qt Code:
    1. QObject::connect(i, SIGNAL(itemSelected(MyElement*)), this, SLOT(toTreeWidget(MyElement)));
    To copy to clipboard, switch view to plain text mode 

    When you emit the itemSelected signal you are responsible to pass the appropriate MyElement*.

    Regards

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

    Shawn (3rd September 2007)

  4. #3
    Join Date
    May 2007
    Posts
    91
    Thanks
    60
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Problem emitting singal with object-pointer as argument

    Quote Originally Posted by marcel View Post
    First use qRegisterMetaType to register the MyElement* type. This is required when passing custom types between signals and slots.

    Second, when connecting signals and slots, don't pass the objects as arguments:
    Qt Code:
    1. QObject::connect(i, SIGNAL(itemSelected(MyElement*)), this, SLOT(toTreeWidget(MyElement)));
    To copy to clipboard, switch view to plain text mode 

    When you emit the itemSelected signal you are responsible to pass the appropriate MyElement*.

    Regards
    I did what u suggested,
    Qt Code:
    1. qRegisterMetaType<MyElement>("MyElement");
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. error C2512: 'MyElement' : no appropriate default constructor available
    To copy to clipboard, switch view to plain text mode 

    Actually,
    Qt Code:
    1. class MyElement
    2. {
    3. public:
    4. MyElement(const QString &type)
    5. :ElementType(type)
    6. {
    7. content.clear();
    8. }
    9.  
    10. ~MyElement(void) {}
    11. }
    To copy to clipboard, switch view to plain text mode 

    BTW, the pE above was declared as MyElement*, which has already been pointer as your suggested
    Last edited by Shawn; 3rd September 2007 at 10:19.

  5. #4
    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: Problem emitting singal with object-pointer as argument

    Add right after the class, in the header: Q_REGISTER_METATYPE(MyElement*);
    And next you should have:
    qRegisterMetaType<MyElement*>("MyElement*");

    I think...

    Regards

  6. #5
    Join Date
    Aug 2006
    Location
    Switzerland
    Posts
    52
    Thanked 13 Times in 11 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Problem emitting singal with object-pointer as argument

    Quote Originally Posted by Shawn View Post
    Qt Code:
    1. error C2512: 'MyElement' : no appropriate default constructor available
    To copy to clipboard, switch view to plain text mode 
    Have you tried adding default constructor?
    The Wheel weaves as the Wheel wills.

  7. #6
    Join Date
    May 2007
    Posts
    91
    Thanks
    60
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Problem emitting singal with object-pointer as argument

    Quote Originally Posted by marcel View Post
    Add right after the class, in the header: Q_REGISTER_METATYPE(MyElement*);
    And next you should have:
    qRegisterMetaType<MyElement*>("MyElement*");

    I think...

    Regards
    What do you mean by "right after the class" ? like this?
    Qt Code:
    1. class MyElement
    2. {
    3. [INDENT]...[/INDENT]
    4. };
    5. Q_REGISTER_METATYPE(MyElement*);
    6. qRegisterMetaType<MyElement*>("MyElement*");
    To copy to clipboard, switch view to plain text mode 

  8. #7
    Join Date
    Aug 2006
    Posts
    221
    Thanks
    3
    Thanked 29 Times in 19 Posts

    Default Re: Problem emitting singal with object-pointer as argument

    My advice might not help for your concrete problem, but you really should ponder a bit whether you can redesign you code that you don't need to signal pointers. Technically nothing is wrong with that, but it might require a higher effort to keep ownership matters in check. For my taste it simply smells not 'robust' enough.

  9. The following user says thank you to Kumosan for this useful post:

    Shawn (3rd September 2007)

  10. #8
    Join Date
    May 2007
    Posts
    91
    Thanks
    60
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Problem emitting singal with object-pointer as argument

    Quote Originally Posted by Kumosan View Post
    My advice might not help for your concrete problem, but you really should ponder a bit whether you can redesign you code that you don't need to signal pointers. Technically nothing is wrong with that, but it might require a higher effort to keep ownership matters in check. For my taste it simply smells not 'robust' enough.

    Thanks very much for this advice.

    Actually what bothers me most is how to "design" code. Obviously I am lack of this very "taste" now. I am not a professional programmer...

    What I tried to implement is to show a hirachy tree structure in a treeWidget. If I click any item in this treeWidget, it's additional information can be shown in a tableWidget.
    My idea is subclass treeWidgetItem and make the data structrue to be memeber of this MyTreeWidgetItem. And so, I may have to singal object-pointers to see which item has been clicked.

    Is there any advice for this? I think my situation is commom...

  11. #9
    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: Problem emitting singal with object-pointer as argument

    Q_REGISTER_METATTYPE goes in the header and qRegisterMetaType in the source.

    What I tried to implement is to show a hirachy tree structure in a treeWidget. If I click any item in this treeWidget, it's additional information can be shown in a tableWidget.
    My idea is subclass treeWidgetItem and make the data structrue to be memeber of this MyTreeWidgetItem. And so, I may have to singal object-pointers to see which item has been clicked.
    You could emit only the index but having the object is always better.
    As for the ownership, you could solve that by making the class where you create the elements the parent and have it destroy them as they aren't needed anymore. Or even in the destructor.

    Regards

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

    Shawn (3rd September 2007)

  13. #10
    Join Date
    May 2007
    Posts
    91
    Thanks
    60
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Problem emitting singal with object-pointer as argument

    This is my first thought,
    note: MyView* w; Element* pE;

    item is clicked ---> emit MyRectItem::a_signal ---> MyRectItem::a_slot ---> call w->showTree(pE)

    then I wander this one may be better,
    item is clicked ---> emit MyRectItem::b_signal(pE) ---> MyView::shot: showTree(pE)

    Actually which one is better ?
    How should I design my code ?
    Last edited by Shawn; 3rd September 2007 at 15:57.

  14. #11
    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: Problem emitting singal with object-pointer as argument

    The second is better. This is closer to the purpose of signals and slots -- transparently calling functions across different objects.

    Your first solution does not make much sense - you connect a signal to a slot in the same object and then call some function in the view. You might have as well called the function in the view in the first place.

    So, go with the second one.

    Regards

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

    Shawn (3rd September 2007)

  16. #12
    Join Date
    May 2007
    Posts
    91
    Thanks
    60
    Qt products
    Qt4
    Platforms
    Windows

    Question Re: Problem emitting singal with object-pointer as argument

    OK, 1:16am now but I have finish it the second way

    The next problem is:
    How can I know which item in QTreeWidget has been clicked? Since I have subclassed QTreeWidgetItem to MyTreeWidgetItem, which contains an Element* . How can I emit a signal like itemSelected(Element*) ?

    When I subclass the QGraphicsrectItem I implement it like this
    Qt Code:
    1. class MyRectItem : public QObject, public QGraphicsRectItem
    2. {
    3. Q_OBJECT
    4. public:
    5. ...
    6. Element* pE;
    7. signals:
    8. void itemisSelected(bool newState);
    9. void itemSelected(Element* pE);
    10. protected:
    11. QVariant itemChange(GraphicsItemChange change, const QVariant &value)
    12. {
    13. if (change == QGraphicsItem::ItemSelectedChange)
    14. {
    15. bool newState = value.toBool();
    16. if (newState == true)
    17. {
    18. emit itemisSelected(newState);
    19. }
    20. }
    21. return QGraphicsItem::itemChange(change, value);
    22. }
    23. };
    To copy to clipboard, switch view to plain text mode 

    And I connected the signal itemis Selected(bool) with signal itemSelected(Element*) right after I new a MyRectItem. It works well.

    Is there any similar way to emit a signal(Element*) in MyTreeWidgetItem?

Similar Threads

  1. Replies: 3
    Last Post: 15th April 2007, 19:16

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.