Hi, I am working in Train Traffic Controller software project. My responsibility in this project is to develop the visual railroad GUI.

We are implementing the project with Qt. By now I am using QGraphicsLinearLayout to hold my items. I am using the layout because I do not want to calculate coordinates of each item. So far I wrote item classes to add the layout. For instance SwitchItem class symbolizes railroad switch in real world. Each item class is responsible for its own painting and events. So far so good.
Now I need a composite item that can contain two or more item. This class is going to be responsible for painting the items contained in it. I need this class because I have to put two or more items inside same layout cell. If I don' t put them in same cell I can' t use layout. See the image below.

BlockSegmentItem and SignalItem inside same cell.

Here is my compositeitem implementation.

Qt Code:
  1. #include "compositeitem.h"
  2.  
  3. CompositeItem::CompositeItem(QString id,QList<FieldItem *> _children)
  4. {
  5. children = _children;
  6. }
  7.  
  8. CompositeItem::~CompositeItem()
  9. {
  10. }
  11.  
  12. QRectF CompositeItem::boundingRect() const
  13. {
  14. //Not carefully thinked about it
  15. return QRectF(QPointF(-50,-150),QSizeF(250,250));
  16. }
  17.  
  18. void CompositeItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget )
  19. {
  20. FieldItem *child;
  21. foreach(child,children)
  22. {
  23. child->paint(painter,option,widget);
  24. }
  25. }
  26.  
  27. QSizeF CompositeItem::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
  28. {
  29. QSizeF itsSize(0,0);
  30. FieldItem *child;
  31. foreach(child,children)
  32. {
  33. // if its size empty set first child size to itsSize
  34. if(itsSize.isEmpty())
  35. itsSize = child->sizeHint(Qt::PreferredSize);
  36. else
  37. {
  38. QSizeF childSize = child->sizeHint(Qt::PreferredSize);
  39. if(itsSize.width() < childSize.width())
  40. itsSize.setWidth(childSize.width());
  41. itsSize.setHeight(itsSize.height() + childSize.height());
  42. }
  43. }
  44. return itsSize;
  45. }
  46.  
  47. void CompositeItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
  48. {
  49. qDebug()<<"Test";
  50. }
To copy to clipboard, switch view to plain text mode 

This code works good with painting but when it comes to item events it is problematic. QGraphicsScene treats the composite item like a single item which is right for layout but not for events. Because each item has its own event implementation.(e.g. SignalItem has its special context menu event.)

I have to handle item events seperately. Also I need a composite item implementation for the layout. How can I overcome this dilemma?