Results 1 to 12 of 12

Thread: I cannot get QGraphicsRectItem to change colour on mousedoubleclickevent

  1. #1
    Join Date
    Jan 2020
    Posts
    13
    Qt products
    Qt5
    Platforms
    Windows

    Default I cannot get QGraphicsRectItem to change colour on mousedoubleclickevent

    Good day everyone

    I am struggling to implement a mouseDoubleClickEvent on a QGraphicsRectItems initialized in another class. I have a class called GatewayWidget where i have created the QgraphicsRectItems in a scene using myshape class, but i cannot get the mousedDoubleClickEvent to click on a QgraphicsRectItem on a scene. When i insert a breakpoint at(scene->items()) no items are returned, but the same mouseDoubleClickEvent works when I call a widget(named logWidg) on a doubleclicking of the same QGraphicsRectItem. However when I call on the QGraphicsRectItem to change colour on doubleclick it does not work. please help! I appreciate it advance! please see my code below

    Qt Code:
    1. void GatewayWidget::receivedTitlesEx(const QString &_rStrDescription, const CORE::Time &_rSimTime, const QList<std::shared_ptr<DM::Object> > &_rTitles, int _eType)
    2. { // I add my QGraphicsRectItems on the scene here
    3. myshape* shape1 = new myshape(text);
    4. //shape1->setFlag(QGraphicsItem::ItemIsMovable);
    5. shape1->setPos(0, 25);
    6. scene->addItem(shape1);
    7. shape1->setFlag(QGraphicsItem::ItemIsMovable);
    8. shape1->setFlag(QGraphicsItem::ItemIsSelectable);
    9. shape1->setFlag(QGraphicsItem::ItemIsFocusable);
    To copy to clipboard, switch view to plain text mode 
    }
    Qt Code:
    1. void myshape::mouseDoubleClick(QGraphicsSceneMouseEvent *event)
    2. {
    3.  
    4. QGraphicsItem::mousePressEvent(event);
    5.  
    6. GatewayWidget gw; //this is the class that this method is implemented, and also where i have initialized the scene and drawn qgraphicsitems
    7. gw.on_btnSelectItem_clicked(); //on_btnSelectItem_Clicked is the method implemented on Gatewaywidget that is supposed to change QGraphicsRectItem on double click, but it does not work. please help
    8.  
    9. //logWidg = new loginWidget();// but this widget can launch successfully when i click on the QGrapicsRectItem
    10. //logWidg->show();
    11.  
    12. QList<QGraphicsItem*> stackOfShapes = gw.scene->items();// I tried to check if gw can return items but the breakpoint i inserted returns zero items
    To copy to clipboard, switch view to plain text mode 

    myshape .h file is as follows:
    Qt Code:
    1. class myshape :public QObject, public QGraphicsRectItem{
    2.  
    3. public:
    4. myshape(QGraphicsItem *item) {
    5. setPen(QPen(QBrush(Qt::black), 1));
    6. setBrush(QBrush(Qt::green));
    7. setRect(0, 0, 80, 80);
    8.  
    9. }
    10.  
    11. protected:
    12.  
    13. void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
    14.  
    15. private:
    16.  
    17. GatewayWidget *gatew; //i have implemented the myshape::mousedoubleclick event on the class(GatewayWidget)
    18.  
    19.  
    20. virtual QSizeF sizeHint(Qt::SizeHint which,
    21. const QSizeF& constraint = QSizeF()) const {
    22. Q_UNUSED(which);
    23. Q_UNUSED(constraint);
    24. return boundingRect().size();
    25. }
    26.  
    27. virtual void setGeometry(const QRectF& rect) {
    28.  
    29. setPos(rect.center());
    30. }
    31.  
    32.  
    33. };
    To copy to clipboard, switch view to plain text mode 

    on_btnSelectItem_clicked() is the method i call that is supposed to change colour of QGraphicsRectItem on mouseDoubleClickEvent but it does not work

    Qt Code:
    1. void GatewayWidget::on_btnSelectItem_clicked()
    2. {
    3.  
    4. foreach(QGraphicsItem *item, scene->selectedItems())
    5. {
    6.  
    7. QGraphicsRectItem *rect = qgraphicsitem_cast<QGraphicsRectItem *>(item);
    8. if (!rect)
    9. continue;
    10.  
    11. QBrush br(Qt::SolidPattern);
    12. br.setColor(Qt::black);
    13. rect->setBrush(br);
    14. rect->update();
    15. }
    16. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Jul 2008
    Posts
    434
    Thanks
    9
    Thanked 57 Times in 55 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: I cannot get QGraphicsRectItem to change colour on mousedoubleclickevent

    Hi,

    Qt Code:
    1. GatewayWidget gw;
    To copy to clipboard, switch view to plain text mode 
    this creates a second temporary instance of class GatewayWidget. This is NOT your original instance, and it will by destroyed when the function ends.

    Ginsengelf

  3. #3
    Join Date
    Jan 2020
    Posts
    13
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: I cannot get QGraphicsRectItem to change colour on mousedoubleclickevent

    Hi

    Thank you for your response,please I would appreciate your advise on how I can access the function(on_btnSelectItem_clicked()) on GatewayWidget

  4. #4
    Join Date
    Jul 2008
    Posts
    434
    Thanks
    9
    Thanked 57 Times in 55 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: I cannot get QGraphicsRectItem to change colour on mousedoubleclickevent

    Hi, the simples would be to pass the GatewayWidget to myshape during construction, e.g.
    Qt Code:
    1. void GatewayWidget::receivedTitlesEx(...)
    2. {
    3. myshape* shape1 = new myshape(text, this);
    4. ...
    5. }
    To copy to clipboard, switch view to plain text mode 
    and store the pointer in a member.

    Ginsengelf

    EDIT: or emit a signal instead of calling the function directly

  5. #5
    Join Date
    Jan 2020
    Posts
    13
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: I cannot get QGraphicsRectItem to change colour on mousedoubleclickevent

    Quote Originally Posted by Ginsengelf View Post
    Hi, the simples would be to pass the GatewayWidget to myshape during construction, e.g.
    Qt Code:
    1. void GatewayWidget::receivedTitlesEx(...)
    2. {
    3. myshape* shape1 = new myshape(text, this);
    4. ...
    5. }
    To copy to clipboard, switch view to plain text mode 
    and store the pointer in a member.

    Ginsengelf

    EDIT: or emit a signal instead of calling the function directly
    Hi, thanks for the reply and your help. I am still a new learner ,I know I can access the shape1 pointer using shape1->scene().items in the class, but shape1 is still not recognized . I am asking if you can show me how to store this pointer? by member you mean my class GatewayWidget()?


    I also tried implementing mousedoubleclickevent() directly to the GatewayWidgetClass() but it does not respond to the mousedoubleclick(event). please see how i did it?

    Qt Code:
    1. class GatewayWidget : public VgdWidget, public QGraphicsRectItem
    2. {
    3. Q_OBJECT
    4. CORE_OBJ_EX(VgdWidget, GatewayWidget, GatewayWidget,
    5. 1.0,
    6. "Basic gatway widget for managing interoperability links.",
    7. "");
    8.  
    9. static const unsigned long WIDGET_UPDATE_PERIOD = 100; // [ms]
    10.  
    11. public:
    12. GatewayWidget(const QColor &_colorBackground = QColor(240, 240, 240));
    13. ~GatewayWidget();
    14.  
    15.  
    16. protected:
    17. virtual void timerEvent(QTimerEvent *pEvent);
    18. protected:
    19. void mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event);
    To copy to clipboard, switch view to plain text mode 

    and in my main class GatewayWidget() i call mousedoubleclick(event) like this:
    Qt Code:
    1. void GatewayWidget::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
    2. {
    3. QMessageBox::information(0, "This", "mouse doubleclick working");
    4. foreach(QGraphicsItem *item, scene->selectedItems())
    5. {
    6. QGraphicsRectItem *rect = qgraphicsitem_cast<QGraphicsRectItem *>(item);
    7. if (!rect)
    8. continue;
    9.  
    10. QBrush br(Qt::SolidPattern);
    11. br.setColor(Qt::black);
    12. rect->setBrush(br);
    13. rect->update();
    14. }
    15.  
    16. QGraphicsItem::mouseDoubleClickEvent(event);
    17. }
    To copy to clipboard, switch view to plain text mode 

    But nothing happens when i click, is it possible to implement mousedoubleclick(event) like this or it must be implemented from an outside class like I am trying to do with myshape? I would appreciate your advise oh how I can make this work work


    thank you in advance!

  6. #6
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    4,490
    Thanks
    252
    Thanked 717 Times in 707 Posts
    Qt products
    Qt5
    Platforms
    Windows Android

    Default Re: I cannot get QGraphicsRectItem to change colour on mousedoubleclickevent

    class GatewayWidget : public VgdWidget, public QGraphicsRectItem
    Why are you inheriting from QGraphicsRectItem? Is GatewayWidget actual one of your rectangles on screen, or is it the view used to display the QGraphicsScene that contains them?

    I am beginning to wonder how it is that you are working on this complex project but you seem to know so little about C++ and programming. Is this someone else's project that you have taken over and are making a GUI for it? The project uses templates, smart pointers, graph data structures, and other more advanced programming ideas, but you don't seem to show that you understand it very well.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  7. #7
    Join Date
    Jan 2020
    Posts
    13
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: I cannot get QGraphicsRectItem to change colour on mousedoubleclickevent

    Quote Originally Posted by d_stranz View Post
    Why are you inheriting from QGraphicsRectItem? Is GatewayWidget actual one of your rectangles on screen, or is it the view used to display the QGraphicsScene that contains them?

    I am beginning to wonder how it is that you are working on this complex project but you seem to know so little about C++ and programming. Is this someone else's project that you have taken over and are making a GUI for it? The project uses templates, smart pointers, graph data structures, and other more advanced programming ideas, but you don't seem to show that you understand it very well.
    No GatewayWidget is not one of my rectangles on screen, I could not call mousedoubleclick(event) on gatewayWidget and I read on Google forums that I needed to inherit QGraphicsRectItem to use mousedoubleclick(event). Maybe I got it wrong?


    Concerning your question, Yes you are correct I am a new learner, thats why I posted in this newbie section and true I do not know a lot. It was someone's project that I am tasked to implement the gui. I think I also was not aware that it will be this complex, and now I have a deadline and I am so drained.....

    I am kindly asking with my whole heart if you can please assist me to implement the mousedoubleclick(event) , how do I make mousedoubleclick(event) to work on my current QGraphicsRectItems? like I said the one I tried with :

    Qt Code:
    1. void GatewayWidget::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
    2. {
    3. QMessageBox::information(0, "This", "mouse doubleclick working");
    4. foreach(QGraphicsItem *item, scene->selectedItems())
    5. {
    6. QGraphicsRectItem *rect = qgraphicsitem_cast<QGraphicsRectItem *>(item);
    7. if (!rect)
    8. continue;
    9.  
    10. QBrush br(Qt::SolidPattern);
    11. br.setColor(Qt::black);
    12. rect->setBrush(br);
    13. rect->update();
    14. }
    15.  
    16. QGraphicsItem::mouseDoubleClickEvent(event);
    17. }
    To copy to clipboard, switch view to plain text mode 


    It does not respond to any mousedoubleclick that is why I tried to implement it with an outside class myshape(). I would appreciate your advise , and I appreciate your help thus far and your patience with my little knowledge.

  8. #8
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    4,490
    Thanks
    252
    Thanked 717 Times in 707 Posts
    Qt products
    Qt5
    Platforms
    Windows Android

    Default Re: I cannot get QGraphicsRectItem to change colour on mousedoubleclickevent

    how do I make mousedoubleclick(event) to work on my current QGraphicsRectItems?
    First, remove the inheritance from QGraphicsRectItem that you added to GatewayWidget, and remove the mouseDoubleClickEvent() code too.

    Second, the steps you need to follow are these:

    1. Derive a new class from QGraphicsRectItem and add an event handler for the mouseDoubleClickEvent to it:

    Qt Code:
    1. // .h
    2.  
    3. class GatewayRectItem : public QGraphicsRectItem
    4. {
    5. public:
    6. GatewayRectItem( QGraphicsItem * parent = nullptr ) : QGraphicsRectItem( parent ) {}
    7.  
    8. protected:
    9. void mouseDoubleClickEvent( QGraphicsSceneMouseEvent * event );
    10.  
    11. // If you want to handle other events, add handlers for those here too
    12. }
    13.  
    14. // .cpp
    15.  
    16. // Implement the event handler
    17. void GatewayRectItem::mouseDoubleClickEvent( QGraphicsSceneMouseEvent * event )
    18. {
    19. // You now have the double-click event. The rect that was clicked is "this". What do you want to do?
    20.  
    21. // If you want to also have the QGraphicsRectItem base class process this event, you must call
    22. QGraphicsRectItem::mouseDoubleClickEvent( event );
    23. }
    To copy to clipboard, switch view to plain text mode 

    2 - When you create your rect items, you call the new constructor. You also need to make sure the item is selectable so it responds to mouse clicks:

    Qt Code:
    1. GatewayRectItem * rect = new GatewayRectItem();
    2. rect->setFlags( QGraphicsItem::ItemIsSelectable );
    3. scene->addItem( rect );
    To copy to clipboard, switch view to plain text mode 

    3 - Decide what you want to do with the double-click. In this case, I would have the GatewayRectItem emit a signal that you can handle somewhere else in a slot that can determine the correct color. To do that, you need to also derive GatewayRectItem from QObject so it can send signals:

    Qt Code:
    1. // .h
    2.  
    3. class GatewayRectItem : public QObject, public QGraphicsRectItem
    4. {
    5. Q_OBJECT;
    6.  
    7. public:
    8. GatewayRectItem( QGraphicsItem * parent = nullptr );
    9.  
    10. signals:
    11. void doubleClicked( QGraphicsSceneMouseEvent * event );
    12.  
    13. protected:
    14. void mouseDoubleClickEvent( QGraphicsSceneMouseEvent * event );
    15. }
    16.  
    17. // .cpp
    18.  
    19. GatewayRectItem::GatewayRectItem( QGraphicsItem * parent )
    20. : QGraphicsRectItem( parent )
    21. {
    22. // Can just do this here, so all items have the flag set
    23. setFlags( QGraphicsItem::ItemIsSelectable );
    24. }
    25.  
    26. // Implement the event handler
    27. void GatewayRectItem::mouseDoubleClickEvent( QGraphicsSceneMouseEvent * event )
    28. {
    29. // You now have the double-click event. Emit the signal to let a slot know
    30. emit doubleClicked( event );
    31.  
    32. // If you want to also have the QGraphicsRectItem base class process this event, you must call
    33. QGraphicsRectItem::mouseDoubleClickEvent( event );
    34. }
    To copy to clipboard, switch view to plain text mode 

    4 - Add a slot to handle this signal. I assume you would want to do that in your GatewayWidget class:

    Qt Code:
    1. // .h
    2.  
    3. class GatewayWidget : public VgdWidget
    4. {
    5. // ... all the original code
    6.  
    7. public slots:
    8. void onRectDoubleClicked( QGraphicsSceneMouseEvent * event );
    9.  
    10. // ...
    11. };
    12.  
    13. // .cpp
    14.  
    15. void GatewayWidget::onRectDoubleClicked( QGraphicsSceneMouseEvent * event )
    16. {
    17. // first, get the rect instance that sent the signal
    18. GatewayRectItem * rect = qobject_cast< GatewayRectItem * >( sender() );
    19.  
    20. // Now you have the rect that was double-clicked, and you have the event details if you need them
    21. // Do whatever you need to do to determine what color the rect should be, then set the color
    22.  
    23. rect->setBrush( QBrush( theNewColor ) );
    24. }
    To copy to clipboard, switch view to plain text mode 

    5 - And finally, when you create the rect, you need to connect its signal to the GatewayWidget's slot:

    Qt Code:
    1. GatewayRectItem * rect = new GatewayRectItem();
    2.  
    3. // Don't need this now since it is set in the constructor for GatewayRectItem
    4. // rect->setFlags( QGraphicsItem::ItemIsSelectable );
    5.  
    6. scene->addItem( rect );
    7.  
    8. connect( rect, &GatewayRectItem::doubleClicked, this, &GatewayWidget::onRectDoubleClicked );
    To copy to clipboard, switch view to plain text mode 

    None of this code has been tested - I am just writing it here. There could be typos, so don't just copy and paste without checking it.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  9. #9
    Join Date
    Jan 2020
    Posts
    13
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: I cannot get QGraphicsRectItem to change colour on mousedoubleclickevent

    Thank you for your help once more, without your help I would not have progressed this far, I do not take it for granted. It is working , it changes color on doubleclick.

    May I please ask another question. Now I want that when I doubleclick on the rect, it must then pop up a widget, but the widget is looking for the index of the rect so that It can pop the widget with the information specific to that rect. I tried it like the code below to get the index of the rect, but it only pops up the widget once(with the correct information). Then nothing after that to any subsequent rect that I click. my question is should I store the indexes of each rect on creation with QLIST[] or how should I store the index of the clicked rect ? i would appreciate your assistance once more


    Qt Code:
    1. void GatewayWidget::onRectDoubleClicked(QGraphicsSceneMouseEvent * event)
    2. {
    3. // first, get the rect instance that sent the signal
    4. GatewayRectItem * rect = qobject_cast< GatewayRectItem * >(sender());
    5. // rect->setBrush(QBrush(Qt::black));
    6.  
    7. QList<QGraphicsItem*> stackOfRect = scene->items();
    8.  
    9. int indexOfShape = stackOfRect.indexOf(rect);// trying to index the clicked rect
    10. if (CORE::castPtrType<C2DM::LinkState>(m_pLinkStateListModel->getTitle(indexOfShape)))// getTitle is looking for the index clicked
    11. {
    12. // create link ctrl widget
    13. //C2DM::LinkState *pState = CORE::castPtrType<C2DM::LinkState>(indexOfShape);
    14. const C2DM::LinkState *pState = CORE::castPtrType<C2DM::LinkState>(m_pLinkStateListModel->getTitle(indexOfShape));
    15. showLinkToolBoxWidget(pState->m_strLinkId);
    16.  
    17. }
    18.  
    19.  
    20.  
    21.  
    22. }
    To copy to clipboard, switch view to plain text mode 

  10. #10
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    4,490
    Thanks
    252
    Thanked 717 Times in 707 Posts
    Qt products
    Qt5
    Platforms
    Windows Android

    Default Re: I cannot get QGraphicsRectItem to change colour on mousedoubleclickevent

    if (CORE::castPtrType<C2DM::LinkState>(m_pLinkStateLi stModel->getTitle(indexOfShape)))// getTitle is looking for the index clicked
    Why do you think that the scene index returned in the QList is a constant that won't change? The scene could change the order of items in it based on the current stacking order of things in the scene, and the order can change as you add new items to the scene. And if you have QGraphicsLineItem, QGraphicsTextItem, and QGraphicsRectItem instances in the scene, all of these will have an index, too, and the index will depend on where they are in the hierarchy of scene objects.

    The only way you can guarantee that you can look up something by an index number is if you assign the index number yourself. The easiest way to do this is to use the mechanism you are already using on your rect objects: use another setData() property to assign the index to your rects. If you are using the key "0" already, then use a different key (1) to assign an index when you create the rect. If you are only indexing the rects, then start at index 0 and increment as you add new rects.

    If you ever delete a rect, then you will have to make sure that your model and your rects remain consistent - if you remove a rect with index 42, because you have removed the title with index 42, then you have to make sure that you either re-index everything from 42 up or access title <---> rect relationship in a way that is not affected by missing index numbers. Once again, an std:: map<> would work great for this.
    Last edited by d_stranz; 6th February 2020 at 18:03.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  11. #11
    Join Date
    Jan 2020
    Posts
    13
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: I cannot get QGraphicsRectItem to change colour on mousedoubleclickevent

    Hello

    I just came to say thank you I followed your advice and it worked beautifully. I also wanted to let you know that I was able to meet my deadline on the 7th of Feb 2020, I was able to demonstrate to my boss of what I have completed so far on the gui and he was happy. I acknowledge that I would not have been able to demonstrate any functionality if not for your guidance from your generous heart, and I say thank you. I thank you for how quick you respond to questions whenever I post. You have taught me a lot and I hope to learn more from you in the future. I thank you! May God bless you!

    I also wanted to ask if there is anywhere else I can find you where you offer courses, like Pluralsight or Udemy?

  12. #12
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    4,490
    Thanks
    252
    Thanked 717 Times in 707 Posts
    Qt products
    Qt5
    Platforms
    Windows Android

    Default Re: I cannot get QGraphicsRectItem to change colour on mousedoubleclickevent

    You are welcome. I am glad you made your deadline and that your boss is happy.

    I don't teach any courses. I have been programming in C / C++ for nearly 40 years and using Qt for almost 15 years and in that time I have learned a few useful things, so I am glad I can use this forum to help others from time-to-time.

    I am sure you can search any of the online sites for C++ and Qt courses. Here is one list. KDAB also offers courses in Europe, the USA, and other places on C++ and Qt programming.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

Similar Threads

  1. Replies: 6
    Last Post: 11th January 2012, 10:11
  2. Change the colour of a table view row
    By Splatify in forum Newbie
    Replies: 0
    Last Post: 7th March 2011, 06:31
  3. Change the colour of a QT TextEdit row
    By Splatify in forum Newbie
    Replies: 3
    Last Post: 3rd March 2011, 14:09
  4. Replies: 2
    Last Post: 3rd May 2010, 12:18
  5. Change colour of QString
    By Morea in forum Newbie
    Replies: 9
    Last Post: 10th February 2006, 22:31

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.