【问题标题】:C++ : Best practice when implementing Multiple inheritanceC++:实现多重继承时的最佳实践
【发布时间】:2016-02-23 11:35:34
【问题描述】:

我必须将两种图形项(QGraphicsRectItemQGraphicsEllipseItem)的倍数添加到 QGraphicsScene(添加到 QGraphicsView)。每个图形项都应该能够与鼠标和键盘事件交互。所以最初我设计了如下的类。

初步设计:

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();
};

要了解如何避免重复的事件声明和定义,我阅读了以下答案:

最后设计的类如下。

修改设计:

头文件

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
}

实现文件

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;
}

调用代码

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

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

应用程序在这个修改后的设计中按预期工作。但是我对这个设计有些疑惑,如下:

  1. 这是处理这种情况的最佳实践还是我应该使用初始方法?还是有其他最好的方法(编写单个代码来处理事件)?
  2. QGraphicsRectItemQGraphicsEllipseItem 都继承自 QAbstractGraphicsShapeItem。那么我需要处理虚拟基类的概念吗?

【问题讨论】:

  • 我认为这应该在 [CR](codereview.stackexchange.com) 上。请注意,交叉发布不被视为“良好行为”。
  • 你可以简单的让myQGraphicsRectItem从T单独继承,从而去掉多重继承。
  • @Jonathan,试试你所说的概念......
  • 请记住,此代码工作正常,因为 *GraphicsItem 没有一个继承 QObject。来自QObject 的多重继承不起作用。
  • @Jonathan。它工作正常。我对这种方法很满意。

标签: c++ qt templates multiple-inheritance virtual-inheritance


【解决方案1】:

哇,解决问题的方法想太多了!

还有其他最好的方法吗(编写单个代码来处理事件)?

对我来说,问题并不清楚你想要实现的目标,可能是由于尝试了解决方案,所以我假设使用 QGraphicsRectItemQGraphicsEllipseItem 这两个类,你'正在尝试使用单个代码块来处理自定义事件,例如鼠标、键等。

在这种情况下,Qt 为您提供调用installSceneEventFilter 所需的一切。

只需创建一个派生自QGraphicsItem 的类并重新实现您要处理的事件。然后使用installSceneEventFilter将这个新类添加到其他实例中

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

实例化过滤器并将其添加到其他类

QGraphicsItemEventsFilter* pFilter = new QGraphicsItemEventsFilter;

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

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

现在pRectpEllipse 的所有事件都将由事件过滤器pFilter 处理。

【讨论】:

  • 看到你的答案后,是的,确实是(我的方法)过度思考了 :) 。我需要了解更多关于 QT 的信息。感谢您的宝贵时间。
【解决方案2】:

根据我使用 Qt 的经验,一个一般性的答案(没有详细阅读您的代码)是:如果您认为必须使用多重继承来处理 Qt 类和子类,那么您很可能做错了 - 这反过来是很可能表明您没有完全理解该机制。 Qt 的设计非常好,如果按预期做事,就不需要多重继承。

试着再想一想,然后去寻找你想要达到的目标的例子。

【讨论】:

  • 感谢您分享您的知识。我尝试了 Jonathan 的评论,并避免了多重继承。
  • 虽然有用的信息,但这并不试图回答问题,最好作为评论发布。
  • @TheDarkKnight 如果它为 OP 提供了一个工具来做他们想做的事情并减少痛苦,我看不出这不是一个答案(这并不意味着你的不是' t 当然更详细和具体)
  • @Gimby 选词不当——一种方法,一种路线改变
  • @Gimby 也许是——但试图让版主删除它仍然是愚蠢的,因为它不是一个答案。如果您不喜欢它,只需投反对票。
猜你喜欢
  • 1970-01-01
  • 2021-06-24
  • 2016-07-05
  • 2014-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-25
  • 1970-01-01
相关资源
最近更新 更多