Results 1 to 13 of 13

Thread: Problem emiting signal in QTreeWidgetItem's subclass

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

    Default Problem emiting signal in QTreeWidgetItem's subclass

    Since this is totally new question which has nothing to do with the title of my provious post, I post it here.

    I have subclassed QTreeWidgetItem to MyTreeWidgetItem, which contains an Element* .
    Then how can I know which item in QTreeWidget has been clicked?
    Can I emit a signal like itemSelected(Element*) ?

    I used to subclass the QGraphicsrectItem and emit a signal contains this Element* 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 
    I connected the signal itemisSelected(bool) with signal itemSelected(Element*) right after I new a MyRectItem. And it works well.

    Is there any similar way to emit a signal(Element*) or signal(MyTreeWidgetItem*) in MyTreeWidgetItem?
    Last edited by Shawn; 3rd September 2007 at 18:59.

  2. #2
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Problem emiting signal in QTreeWidgetItem's subclass

    Does MyTreeWidgetItem inherit QObject? What did you try so far?
    J-P Nurmi

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

    Shawn (4th September 2007)

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

    Default Re: Problem emiting signal in QTreeWidgetItem's subclass

    Quote Originally Posted by jpn View Post
    Does MyTreeWidgetItem inherit QObject? What did you try so far?
    Yes, it inherits QObject
    Qt Code:
    1. class MyTreeWidgetItem : public QObject, public QTreeWidgetItem
    2. {
    3. Q_OBJECT
    4.  
    5. public:
    6. MyTreeWidgetItem(QTreeWidget* parent);
    7. MyTreeWidgetItem(MyTreeWidgetItem* parent);
    8. ~MyTreeWidgetItem();
    9.  
    10. Element* pE;
    11. signals:
    12. void itemClicked(MyTreeWidgetItem* item, int column);
    13.  
    14. private slots:
    15. void slot_itemSelected();
    16. };
    17. int Q_REGISTER_METATYPE(MyTreeWidgetItem*);
    To copy to clipboard, switch view to plain text mode 

    In QGraphicsItem, the enum QGraphicsItem::GraphicsItemChangeare sent as the state changes, and I can catch this and emit a signal, which "carrys" the Element* .

    But in QTreeWidgetItem I can not find anything like GraphicsItemChange.

    I tried to used the signal void itemClicked(QTreeWidgetItem* item, int column) in QTreeWidget, but it can only "return" QTreeWidgetItem*...
    Last edited by Shawn; 4th September 2007 at 01:29.

  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 emiting signal in QTreeWidgetItem's subclass

    You can find that by reimplementing QTreeWidget's mouse press event. In this function you should verify what QTreeWidget::itemAt(QMouseEvent:: pos()) returns. If it is not null means that you clicked on an item and you can emit that. Otherwise you clicked somewhere in the view, not on an item and you can act accordingly.

    Regards

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

    Shawn (4th September 2007)

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

    Default Re: Problem emiting signal in QTreeWidgetItem's subclass

    Quote Originally Posted by marcel View Post
    You can find that by reimplementing QTreeWidget's mouse press event. In this function you should verify what QTreeWidget::itemAt(QMouseEvent:: pos()) returns. If it is not null means that you clicked on an item and you can emit that. Otherwise you clicked somewhere in the view, not on an item and you can act accordingly.

    Regards
    Maybe this is a stupid question.
    How can I reimplement QTreeWidget's mouse press event? Should I subclass the QTreeWidget and reimplement the event there ? OR I can reimplement this mose event in MyTreeWidgetItem ?

  8. #6
    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 emiting signal in QTreeWidgetItem's subclass

    No, you have to subclass QTreeWidget. Remember that mousePressEvent is virtual protected.

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

    Shawn (4th September 2007)

  10. #7
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Problem emiting signal in QTreeWidgetItem's subclass

    Perhaps you could even use the built-in signal QTreeWidget::itemClicked(QTreeWidget* item, int column) and simply cast the passed item:
    Qt Code:
    1. connect(treeWidget, SIGNAL(itemClicked(QTreeWidget*, int)), receiver, SLOT(doSomething(QTreeWidget*, int)));
    2.  
    3. void Receiver::doSomething(QTreeWidget* item, int column)
    4. {
    5. MyTreeWidgetItem* myItem = dynamic_cast<MyTreeWidgetItem*>(item);
    6. if (myItem)
    7. {
    8. // yes, it's a "MyTreeWidgetItem", do something with it's "element"
    9. }
    10. }
    To copy to clipboard, switch view to plain text mode 
    Actually you could store the element information as QTreeWidgetItem's user data, without the need of subclassing QTreeWidgetItem.
    J-P Nurmi

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

    Shawn (4th September 2007)

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

    Default Re: Problem emiting signal in QTreeWidgetItem's subclass

    Quote Originally Posted by jpn View Post
    Perhaps you could even use the built-in signal QTreeWidget::itemClicked(QTreeWidget* item, int column) and simply cast the passed item:
    Qt Code:
    1. connect(treeWidget, SIGNAL(itemClicked(QTreeWidget*, int)), receiver, SLOT(doSomething(QTreeWidget*, int)));
    2.  
    3. void Receiver::doSomething(QTreeWidget* item, int column)
    4. {
    5. MyTreeWidgetItem* myItem = dynamic_cast<MyTreeWidgetItem*>(item);
    6. if (myItem)
    7. {
    8. // yes, it's a "MyTreeWidgetItem", do something with it's "element"
    9. }
    10. }
    To copy to clipboard, switch view to plain text mode 
    Actually you could store the element information as QTreeWidgetItem's user data, without the need of subclassing QTreeWidgetItem.
    I did what you said,
    Qt Code:
    1. QObject::connect(ui.treeWidget, SIGNAL(itemClicked(QTreeWidgetItem*, int)), this, SLOT(testslot(QTreeWidgetItem*, int)));
    2. void test::testslot(QTreeWidgetItem* item, int column)
    3. {
    4. QString str = item->text(column);
    5. QMessageBox::information(0, "testslot", str, QMessageBox::Ok);
    6. }
    To copy to clipboard, switch view to plain text mode 
    The strange thing is that the message box appears many times when I click on any item. 22 times on my laptop and 38 or 39 times on my workstation...

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

    Default Re: Problem emiting signal in QTreeWidgetItem's subclass

    Quote Originally Posted by Shawn View Post
    The strange thing is that the message box appears many times when I click on any item. 22 times on my laptop and 38 or 39 times on my workstation...
    I test it using a local static variable, and found that the exact times the testslot has been called is 22. Why it behaves like this ?

  14. #10
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Problem emiting signal in QTreeWidgetItem's subclass

    Do you call QObject::connect() in a loop?
    J-P Nurmi

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

    Shawn (4th September 2007)

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

    Default Re: Problem emiting signal in QTreeWidgetItem's subclass

    Sorry, stupid mistake

    I connected in a recursion function...

    After replace it to the constractor, it works well

    Thanks very much for your help!

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

    Default Re: Problem emiting signal in QTreeWidgetItem's subclass

    Quote Originally Posted by jpn View Post
    Perhaps you could even use the built-in signal QTreeWidget::itemClicked(QTreeWidget* item, int column) and simply cast the passed item:
    Qt Code:
    1. connect(treeWidget, SIGNAL(itemClicked(QTreeWidget*, int)), receiver, SLOT(doSomething(QTreeWidget*, int)));
    2.  
    3. void Receiver::doSomething(QTreeWidget* item, int column)
    4. {
    5. MyTreeWidgetItem* myItem = dynamic_cast<MyTreeWidgetItem*>(item);
    6. if (myItem)
    7. {
    8. // yes, it's a "MyTreeWidgetItem", do something with it's "element"
    9. }
    10. }
    To copy to clipboard, switch view to plain text mode 
    Actually you could store the element information as QTreeWidgetItem's user data, without the need of subclassing QTreeWidgetItem.
    The program works now, but I still doesn't understand your code. Especially for the dynamic_cast function, how can it get the "element" information only by MyTreeWidgetItem's parent class ?

    If you have time, can you explain it a little bit? If you can recommend some metarial that I can study this by myself, I will appreciate it as well.

  18. #13
    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 emiting signal in QTreeWidgetItem's subclass

    Go to this address and download Thinking in C++( Bruce Eckel) and read the chapter on polymorphism: http://www.mindview.net/Books/DownloadSites.

    Regards

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

    Shawn (4th September 2007)

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.