Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ : Best practice when implementing Multiple inheritance

I have to add multiples of two types of Graphics Items (QGraphicsRectItem and QGraphicsEllipseItem) to a QGraphicsScene (which is added to QGraphicsView). Each graphics item should be able to interact with the mouse and keyboard events. So initially I designed the classes as below.

Initial design:

class myQGraphicsRectItem : public QGraphicsRectItem
{
public:
    explicit myQGraphicsRectItem();
private:
    void mousePressEvent(QGraphicsSceneMouseEvent *event);
    void keyPressEvent(QKeyEvent *event);
    void focusOutEvent(QFocusEvent *event);
    //Many events goes here
    void fnCreateRect();
};

class myQGraphicsRectItem : public QGraphicsEllipseItem
{
public:
    explicit myQGraphicsRectItem();
private:
    void mousePressEvent(QGraphicsSceneMouseEvent *event);
    void keyPressEvent(QKeyEvent *event);
    void focusOutEvent(QFocusEvent *event);
    //Many events goes here
   void fnCreateCircle();
};

To know how to avoid duplicate event declaration and definition, I read the answers to:

  • Multiple Inheritance Ambiguous Call
  • Templates only be implemented in the header file?
  • Virtual base class

and finally designed the class as below .

Modified design:

header file

template <class T>
class myQGraphicsRectItem : public QGraphicsRectItem , public QGraphicsEllipseItem{
     /*commented the below event methods in the base classes*/
     void mousePressEvent(QGraphicsSceneMouseEvent *event);
     void keyPressEvent(QKeyEvent *event);
     void focusOutEvent(QFocusEvent *event);
     //Many events goes here
}

implementation file

template <class T> myGraphicsItem<T>::myGraphicsItem()
{
    this->T::setFlags(QGraphicsItem::ItemIsMovable|QGraphicsItem::ItemIsFocusable);
    this->T::setFocus();
}     

//**All event function definition goes here....**     

template <class T> QGraphicsItem *myGraphicsItem<T>::fnGetRectObject()
{
    fnCreateRect();
    return (T*)this;
}

calling code

#include "mygraphicsitem.h"
#include "mygraphicsitem.cpp"

void MainWindow::on_PushButton_clicked()
{
    myGraphicsItem<myQGraphicsRectItem> *rr = new myGraphicsItem<myQGraphicsRectItem>();
    scene->addItem(rr->fnGetRectObject());
}

And the application is working as expected with this modified design. But I have some doubts with this design, as follows:

  1. Is this a best practice to handle this scenario or should I go with the initial method? or any other best method is there (to write single code to handle events)?
  2. Both the QGraphicsRectItem and QGraphicsEllipseItem inherit from QAbstractGraphicsShapeItem. So do I need to handle the virtual base class concept?
like image 631
Jeet Avatar asked Mar 14 '23 04:03

Jeet


1 Answers

Wow, that's over thinking the solution to the problem!

any other best method is there (to write single code to handle events)?

For me, the question is not clear in what you're trying to achieve, possibly due to the attempted solution, so I'm going to assume that with the two classes, QGraphicsRectItem and QGraphicsEllipseItem, you're trying to have a single block of code to handle custom events, such as mouse, keys etc.

In this case, Qt provides you with all you need in the call to installSceneEventFilter.

Simply create a class that's derived from QGraphicsItem and reimplement the events you want to handle. Then add this new class to the other instances with installSceneEventFilter

class QGraphicsItemEventsFilter : public QGraphicsItem
{
    private:
        void mousePressEvent(QGraphicsSceneMouseEvent *event);
        void keyPressEvent(QKeyEvent *event);
        void focusOutEvent(QFocusEvent *event);
};

Instantiate the filter and add it to the other classes

QGraphicsItemEventsFilter* pFilter = new QGraphicsItemEventsFilter;

QGraphicsRectItem* pRect = new QGraphicsRectItem;
pRect->installSceneEventFilter(pFilter);

QGraphicsEllipseItem* pEllipse = new QGraphicsEllipseItem;
pEllipse->installSceneEventFilter(pFilter);

Now all events for both pRect and pEllipse will be handled by the event filter, pFilter.

like image 88
TheDarkKnight Avatar answered Mar 16 '23 00:03

TheDarkKnight