Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QGraphicsItemGroup in a QGraphicsLayout
Forum Updated to NodeBB v4.3 + New Features

QGraphicsItemGroup in a QGraphicsLayout

Scheduled Pinned Locked Moved Unsolved General and Desktop
qgraphicsitemgrqgraphicsitemqgraphicslayout
7 Posts 2 Posters 1.6k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    Clement135
    wrote on last edited by Clement135
    #1

    Hi all, I am currently trying to put QGraphicsItemGroup in a QGraphicsLayout (for instance a QGraphicsLinearLayout or a QGraphicsGridLayout). I am not able to arrange properly the items.

    I have two graphics items, each inherits QGraphicsItem and QGraphicsLayoutItem. Both graphics items are instantiated in a derived class that inherits QGraphicsItemGroup. Obviously, I have overridden the virtual methods (boundingRect, paint, sizeHint and setGeometry) for both, following the Basic Graphics Layouts Example (https://doc.qt.io/qt-5/qtwidgets-graphicsview-basicgraphicslayouts-example.html).

    When I have tried to add the derived class (GraphicsItemGroup) to a graphics layout, all the grouped items stay on top of each other at the same place.

    However, when I add the graphics items without grouping them. The graphics layout arranges the items properly.

    class LayoutItem : public QGraphicsItem, public QGraphicsLayoutItem
    {
        public:
            LayoutItem(QGraphicsItem* parent, QGraphicsLayoutItem* parentLayout)
                : QGraphicsItem(parent)
                , QGraphicsLayoutItem(parentLayout)
            {
                setGraphicsItem(this);
            }
    
            QRectF boundingRect() const override;
            void paint(QPainter* painter, const QStyleOptionGraphicsItem* option,
                             QWidget* widget) override;
            void setGeometry(const QRectF& geometry) override;
            QSizeF sizeHint(Qt::SizeHint which, const QSizeF& constraint = QSizeF()) const override;
    }
    
    class LayoutItemGroup : public QGraphicsItemGroup, public QGraphicsLayoutItem
    {
        public:
            LayoutItemGroup(QGraphicsItem* parent, QGraphicsLayoutItem* parentLayout)
                 : QGraphicsItemGroup(parent),
                 , QGraphicsLayoutItem(parentLayout)
                 , m_layoutItem(std::make_unique<LayoutItem>(this, this),
                 , m_otherLayoutItem(std::make_unique<OtherLayoutItem>(m_otherLayoutItem.get(), this)
            {
                addToGroup(m_layoutItem.get());
                addToGroup(m_otherLayoutItem.get());
    
               setFlags(ItemSendsGeometryChanges);
    
                setGraphicsItem(this);
            }
    
            void setGeometry(const QRectF& geometry) override;
            QSizeF sizeHint(Qt::SizeHint which, const QSizeF& constraint = QSizeF()) const override;
    }
    

    The OtherLayoutItem class is instantiated as a child class of LayoutItem, only the paint content is different.

    class GraphicsWidget : public QGraphicsWidget
    {
        public:
            GraphicsWidget(QGraphicsItem* parent, Qt::WindowFlags wFlags)
                : QGraphicsWidget(parent, wFlags)
                , m_linearLayout(std::make_unique<QGraphicsLinearLayout>(Qt::Horizontal, this))
                , m_layoutItemGroup0(std::make_unique<LayoutItemGroup>(this, this)
                , m_layoutItemGroup1(std::make_unique<LayoutItemGroup>(this, this)
           {
                m_linearLayout->addItem(m_layoutItemGroup0.get());
                m_linearLayout->addItem(m_layoutItemGroup1.get());
                setLayout(m_linearLayout.release());
           }
    }
    

    The GraphicsWidget is then added to the QGraphicsScene.

    Is the derived class inheriting from QGraphicsItemGroup can be added to a QGraphicsLayout?

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      What if you don't pass a parent to the QGraphicsLayoutItem base class ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • C Offline
        C Offline
        Clement135
        wrote on last edited by Clement135
        #3

        Actually it was because I have forgotten to paint depending on geometry() method... It is working now!

        1 Reply Last reply
        1
        • C Offline
          C Offline
          Clement135
          wrote on last edited by Clement135
          #4

          False alarm... Sorry. I have only solved the layout problem. Now the LayoutItemGroup items are placed as expected in the linear layout but I am facing another issue. The geometry changes of the parent (LayoutItemGroup) are not propagated to the child (LayoutItem). It means when the LayoutItemGroup is resized, the LayoutItem is not resized at all. I would have thought that set-up the child's parent would be sufficient.

          1 Reply Last reply
          0
          • C Offline
            C Offline
            Clement135
            wrote on last edited by
            #5

            Put simply, the parent of ChildLayoutItem is a LayoutItem (both inherit QGraphicsLayoutItem and QGraphicsItem). The ChildLayoutItem geometry is always { 0, 0, QSize(0, 0)) } and never changes. What can I do to fix that? It is bothering me a lot, I can not go forward without this. I really need help. Please.

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #6

              Can you share a minimal compilable example that shows that behaviour ?

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              0
              • C Offline
                C Offline
                Clement135
                wrote on last edited by Clement135
                #7

                @SGaist I have tried many things so there are a few comments

                Here the minimal code below:


                main.cpp:


                #include "QApplication"
                
                #include "graphicsitemgroup.h"
                #include "qgraphicslinearlayout.h"
                #include "qgraphicsscene.h"
                #include "qgraphicsview.h"
                #include "graphicswidget.h"
                
                int main(int argc, char *argv[])
                {
                    QApplication app(argc, argv);
                
                    auto widget = new QGraphicsWidget(nullptr, Qt::Window);
                
                    auto item_0 = new GraphicsItemGroup(widget);
                    auto item_1 = new GraphicsItemGroup(widget);
                
                    auto linearLayout = new QGraphicsLinearLayout();
                    linearLayout->addItem(item_0);
                    linearLayout->addItem(item_1);
                    widget->setLayout(linearLayout);
                
                    QGraphicsScene scene;
                    scene.addItem(widget);
                
                    QGraphicsView view(&scene);
                    view.setResizeAnchor(QGraphicsView::AnchorViewCenter);
                    view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
                    view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
                    view.show();
                
                    return app.exec();
                }
                

                graphicsitemgroup.h:


                #ifndef GRAPHICSITEMGROUP_H
                #define GRAPHICSITEMGROUP_H
                
                #include "qgraphicslayoutitem.h"
                #include "QGraphicsItemGroup"
                
                #include "qsize.h"
                
                class GraphicsItem;
                
                /**
                 * @brief   Placeholder for graphics items
                 */
                
                class GraphicsItemGroup : public QGraphicsLayoutItem, public QGraphicsItemGroup
                {
                    public:
                	GraphicsItemGroup(QGraphicsItem* parent = nullptr);
                	virtual ~GraphicsItemGroup();
                
                	void setGeometry(const QRectF& geometry) override;
                	QSizeF sizeHint(Qt::SizeHint which, const QSizeF& constraint = QSizeF()) const override;
                //	QRectF boundingRect() const override;
                	void paint(QPainter *painter, const QStyleOptionGraphicsItem* option,
                		   QWidget* widget) override;
                
                    private:
                	QSizeF m_size;
                	GraphicsItem* m_item;
                };
                
                #endif // GRAPHICSITEMGROUP_H
                

                graphicsitemgroup.cpp:


                #include "graphicsitemgroup.h"
                
                #include "graphicsitem.h"
                #include "qpainter.h"
                #include "qdebug.h"
                
                GraphicsItemGroup::GraphicsItemGroup(QGraphicsItem* parent)
                    : QGraphicsItemGroup(parent)
                    , m_size(QSize(100, 100))
                    , m_item(new GraphicsItem(QSizeF(50, 50)))
                {
                    addToGroup(m_item);
                    setGraphicsItem(this);
                }
                
                GraphicsItemGroup::~GraphicsItemGroup() = default;
                
                void GraphicsItemGroup::setGeometry(const QRectF& geometry)
                {
                    prepareGeometryChange();
                    QGraphicsLayoutItem::setGeometry(geometry);
                    setPos(geometry.topLeft());
                
                    qDebug() << __PRETTY_FUNCTION__;
                }
                
                QSizeF GraphicsItemGroup::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
                {
                    switch (which)
                    {
                	case Qt::MinimumSize:
                	case Qt::PreferredSize:
                	    return m_size;
                	case Qt::MaximumSize:
                	default:
                	    break;
                    }
                
                    return constraint;
                }
                
                //QRectF GraphicsItemGroup::boundingRect() const
                //{
                //    return QRectF(QPointF(0, 0), geometry().size());
                //}
                
                void GraphicsItemGroup::paint(QPainter* painter, const QStyleOptionGraphicsItem* option,
                			      QWidget* widget)
                {
                    painter->drawRect(QRectF(QPointF(0, 0), geometry().size()));
                }
                

                graphicsitem.h:


                #ifndef GRAPHICSITEM_H
                #define GRAPHICSITEM_H
                
                #include "qgraphicslayoutitem.h"
                #include "qgraphicsitem.h"
                
                #include "qsize.h"
                
                class QRectF;
                class QPainter;
                class QStyleOptionGraphicsItem;
                
                class GraphicsItem : /*public QGraphicsLayoutItem,*/ public QGraphicsItem
                {
                    public:
                	GraphicsItem(QSizeF size, QGraphicsItem* parent = nullptr);
                	virtual ~GraphicsItem();
                
                //	void setGeometry(const QRectF& geometry) override;
                //	QSizeF sizeHint(Qt::SizeHint which, const QSizeF& constraint = QSizeF()) const override;
                	QRectF boundingRect() const override;
                	void paint(QPainter *painter, const QStyleOptionGraphicsItem* option,
                		   QWidget* widget) override;
                
                    private:
                	QSizeF m_size;
                };
                
                #endif
                

                graphicsitem.cpp:


                #include "graphicsitem.h"
                
                #include "qpainter.h"
                #include "qrect.h"
                #include "qdebug.h"
                
                GraphicsItem::GraphicsItem(QSizeF size, QGraphicsItem* parent)
                    : QGraphicsItem(parent)
                    , m_size(size)
                {
                //    setGraphicsItem(this);
                }
                
                GraphicsItem::~GraphicsItem() = default;
                
                //void GraphicsItem::setGeometry(const QRectF& geometry)
                //{
                //    prepareGeometryChange();
                //    QGraphicsLayoutItem::setGeometry(geometry);
                //    setPos(geometry.topLeft());
                //
                //    qDebug() << __PRETTY_FUNCTION__;
                //}
                //
                //QSizeF GraphicsItem::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
                //{
                //    switch (which)
                //    {
                //	case Qt::MinimumSize:
                //	case Qt::PreferredSize:
                //	    return m_size;
                //	case Qt::MaximumSize:
                //	default:
                //	    break;
                //    }
                //
                //    return constraint;
                //}
                
                QRectF GraphicsItem::boundingRect() const
                {
                    return QRectF(QPointF(20, 20), m_size);
                }
                
                void GraphicsItem::paint(QPainter *painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
                {
                    painter->drawRect(boundingRect());
                }
                
                

                CMakeLists.txt:


                cmake_minimum_required(VERSION 3.0)
                
                project(GraphicsLayoutExample)
                
                find_package(Qt5
                    COMPONENTS
                        Core      REQUIRED
                        Widgets   REQUIRED
                        Gui       REQUIRED
                )
                
                add_executable(${CMAKE_PROJECT_NAME}
                    main.cpp
                    graphicsitemgroup.cpp
                    graphicsitem.cpp
                )
                
                target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC .)
                
                target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE Qt5::Widgets Qt5::Core Qt5::Gui)
                

                I would like to have the graphics item (here a little rectangle) to be resized depending on the a graphics item group (the latter paints another rectangle just to have a visual on what is going on). In the future, I have planned to put two graphics items (one over the other) in the group. Thanks for your help.

                1 Reply Last reply
                0

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved