Results 1 to 14 of 14

Thread: QGraphicRectItem update colour in foreach statement

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,328
    Thanks
    317
    Thanked 871 Times in 858 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QGraphicRectItem update colour in foreach statement

    is there a way I can setdata() without creating a new rect? how do i call setdata() for an existing rect on the scene?
    Of course you can call setData() on an existing rect.

    I think your basic problem is that you do not have any connection between the data you are trying to model (your data tree of links and nodes) and the graphical items you are using to display the model on the screen (the QGraphicsRectItem and QGraphicsLineItem instances).

    If you want the graphics items on the screen to reflect the status of the data items in your model, then you have to create another data structure that connects a specific item from your model with the graphics item that represents it on screen. This is what I meant several replies ago when I said:

    So what you need to do is to add an association between each rect and its specific LinkState value.
    You can't add items to your graphics scene and then just forget about them. If they represent something in your model, you need to create an explicit association between the model and the graphics item.

    What I would do is create something like this:

    Qt Code:
    1. std::map< DM::Object *, QGraphicsItem * >
    To copy to clipboard, switch view to plain text mode 

    as a data structure in the GatewayWidget class (or some other class if it is more appropriate). Each time you create a new graphics item, you add an entry to the map that associates the Object with the graphics item. When you need to update a graphics item because the Object status has changed, you use the map to retrieve the graphics item pointer using the Object pointer as the key.
    <=== 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.

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

    Default Re: QGraphicRectItem update colour in foreach statement

    Hello

    Thank you for your help one again. I used std::map and it updates correctly. I have a problem with the routes(source and destination). I sometimes have multiple source address(string) going to different destinations and I read that with std::map() i cannot have multiple keys. The mapping that worked for the links(unique keys and values) is
    Qt Code:
    1. std::map< std::string, QGraphicsItem * > QgraphicRectItems;//declared in my .h file
    2.  
    3. rectangleColor->setData(0, int(pState->m_eState));
    4. QgraphicRectItems.insert(std::make_pair(pState->m_strLinkId, rectangleColor));//make a pair of QGraphicRect items on the scene and their link IDs
    To copy to clipboard, switch view to plain text mode 

    then on my update function i call the mappings like this:
    Qt Code:
    1. std::map< std::string, QGraphicsItem *>::iterator it = QgraphicRectItems.find(pState->m_strLinkId);
    2. if (it != QgraphicRectItems.end()) {
    3. QGraphicsItem *name = it->second;
    4. name->setData(0, int(pState->m_eState));
    5. QGraphicsRectItem *rect = qgraphicsitem_cast<QGraphicsRectItem *>(name);
    6. getTitleDescriptionColor(pState, m_backgroundColor, rect);
    To copy to clipboard, switch view to plain text mode 

    But for the routes this doesn't work because sometimes i have multiple keys, so I implemented std::multimap like this:
    Qt Code:
    1. std::multimap<std::string, QGraphicsItem *> RouteSourceDuplicates;//declared on my .h file
    2.  
    3. else if (CORE::checkPtrType<C2DM::RouteState>(_pTitle) == true)
    4. {
    5. C2DM::RouteState *pRoute = (C2DM::RouteState*)_pTitle;
    6.  
    7. rectangle = new QGraphicsRectItem(QRectF(0, 0, 60, 60), text);
    8.  
    9. rectangle->setData(0, int(pRoute->m_eTxLinkState));
    10. RouteSourceDuplicates.insert(std::make_pair(pRoute->m_strSource, rectangle));//make a pair of QGraphicRect items on the scene and their source IDs
    To copy to clipboard, switch view to plain text mode 

    then on my calling function i did like this:
    Qt Code:
    1. else if (_eType == QSubscription::UPDATED_TITLES)
    2. {
    3. C2DM::RouteState *pRoute = (C2DM::RouteState*)objPtr->_clone();
    4.  
    5. for (std::multimap<std::string, QGraphicsItem *>::iterator Values = RouteSourceDuplicates.begin();
    6. Values != RouteSourceDuplicates.end(); ++Values)
    7. {
    8.  
    9. QGraphicsItem *nameSource = Values->second;
    10. nameSource->setData(0, int(pRoute->m_eTxLinkState));
    11. QGraphicsRectItem *rectSource = qgraphicsitem_cast<QGraphicsRectItem *>(nameSource);//it breaks on this qgraphicitem_cast
    12.  
    13. getTitleDescriptionColor(pRoute, m_backgroundColor, rectSource);
    14.  
    15. }
    To copy to clipboard, switch view to plain text mode 

    It only works the first time i load the data, second time it just crushes. it gives an Access violation executing location error(please see attachment,it has the error where it breaks). I am struggling to fix it. I am asking for your guidance once again to make it work, please.
    the duplicate keys in my data is like this:

    Qt Code:
    1. pRoute->m_strSource[Node A] pRoute->m_strDestination[Node B] //same source address but different destinations
    2. pRoute->m_strSource[Node A] pRoute->m_strDestination [Node C]
    To copy to clipboard, switch view to plain text mode 
    and I am using pRoute->m_strSource as my key and QgraphicsItem as a value in std::multimap
    Attached Images Attached Images

  3. #3
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,328
    Thanks
    317
    Thanked 871 Times in 858 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QGraphicRectItem update colour in foreach statement

    second time it just crushes.
    The error seems to be due to an invalid QGraphicsRectItem pointer. Either you are storing a NULL pointer in your map / multimap or you have deleted a QGraphicsRectItem and you have not updated the map / multimap to remove that pointer. So when qgraphicsitem_cast() tries to access the item (the rect pointer) it is accessing a NULL or invalid pointer and it crashes.

    I still do not understand why you are calling clone() every time you access one of your DM:: Object instances. Why? You don't save these cloned copies anywhere. Just cast the "objPtr" to whatever it should be and use it. Don't clone it, because you are simply wasting time and fragmenting memory by repeatedly creating new instances of things, only to throw them away a few lines later when the pointer goes out of scope at the end of the else if() clause.
    <=== 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.

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

    Default Re: QGraphicRectItem update colour in foreach statement

    Thank you for your help once more, its working now, it was an invalid pointer like you said. Concerning the clone() , its the only way I knew how to retrieve the object instances, I am still newbie in this. I am going to try and implement as you advise.Thank you.

    I got another question please if I am still allowed. The nodes(QGraphicsRectItems) in the scene keeps crossing paths. I know I am supposed to set the setPos() for each of the nodes on the scene but I do not how to store the items so that I can set individual setPos(). I read my data from the object instance like this:

    Qt Code:
    1. void GatewayWidget::addRect(DM::Object *_pTitle)
    2. {
    3.  
    4. C2DM::RouteState *pRoute = (C2DM::RouteState*)_pTitle;
    5. QGraphicsRectItem *rectangle;
    6.  
    7. text = scene->addText(QString::fromStdString(pRoute->m_strSource));// pRoute->Source may contain 4, 8 or any number of nodes that are retried from the data
    8. text->setPos(600, (qrand() % 400)); //try to setpos() but its ugly
    9. rectangle = new QGraphicsRectItem(QRectF(0, 0, 60, 60), text); //then put it in QGraphicsRectItems
    To copy to clipboard, switch view to plain text mode 

    I tried to set randomly position them, which is not ideal. Now this makes the QGraphicsLineItems *line that I use to connect source and destination to cross paths(please see attachment). So I am asking for your guidance, on how I can store the nodes(pRoute->Source) ,which will enable me to retrieve and setPos() for each QGraphicRectItem?
    Attached Images Attached Images

  5. #5
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,328
    Thanks
    317
    Thanked 871 Times in 858 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QGraphicRectItem update colour in foreach statement

    how I can store the nodes
    I think you need to do some research online. Start by using Google for "directed graph c++" and read about the different ways to implement graph data structures. (Your DM Object trees and the matching QGraphicsItem tree) are directed graphs in computer science / mathematics terminology.

    Next you need to use Google to find information on "directed graph layout". There are many ways to lay out graphs, but this Wikipedia article on "Layered graph drawing" might be good for your needs. To draw a layered graph, you create a "row" for each level in your tree. You then count the number of nodes at each level, and the divide the row up into that many boxes and put one node in each box, under the parent it belongs to. You can see an example on the Wikipedia page.
    <=== 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. foreach or alike
    By prophet0 in forum Qt Programming
    Replies: 18
    Last Post: 5th January 2012, 17:03
  2. foreach error while compiling
    By smanoj in forum Newbie
    Replies: 4
    Last Post: 24th November 2011, 05:32
  3. Help with QT, SQLite, Update Statement
    By chetu1984 in forum Newbie
    Replies: 3
    Last Post: 17th March 2011, 22:24
  4. lifetime of foreach
    By BalaQT in forum Newbie
    Replies: 4
    Last Post: 4th March 2010, 15:55
  5. Foreach performance
    By jano_alex_es in forum General Programming
    Replies: 2
    Last Post: 17th November 2009, 13:26

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
  •  
Qt is a trademark of The Qt Company.