向类添加新功能

时间:2012-10-26 20:49:02

标签: c++ qt class override derived-class

我正在研究Qt4库,我想在项目中为 QWidget 的所有孩子添加一些功能。我需要所有小部件都覆盖mousePressEvent。显然我不需要在我使用的每个特定小部件中覆盖它(我使用很多它们并且我们遵循DRY规则),而是创建一个Foo类:

class Foo : public QWidget
{
    Q_OBJECT
    protected:

        /* implementation is just a test */
        virtual void mousePressEvent(QMouseEvent*) { this->move(0,0);  }
};

从中导出我的按钮:

class FooButton : public QPushButton , public Foo
{

    public:
        FooButton (QWidget* parent) : QPushButton(parent) { };

};

但事件似乎没有被覆盖......我做错了什么? 提前谢谢。

3 个答案:

答案 0 :(得分:2)

对于mousePressEvent访问,请尝试QObject :: installEventFilter()。

http://doc.qt.digia.com/stable/qobject.html

答案 1 :(得分:1)

您现在从QWidget继承两次。这是有问题的(见diamond problem)。

相反,请放弃Foo课程并将自定义鼠标按下事件处理程序移至FooButton课程:

class FooButton : public QPushButton
{
    Q_OBJECT
protected:

    /* implementation is just a test */
    virtual void mousePressEvent(QMouseEvent*) { this->move(0,0);  }

public:
    FooButton (QWidget* parent) : QPushButton(parent) { };

};

如果这不适合您的应用程序设计,请尝试使用虚拟继承。也就是说,将Foo更改为:

class Foo : public virtual QWidget

如果这没有帮助,您应该遵循其他答案的建议并安装事件处理程序。

(您可以在Wikipedia article中了解虚拟继承。)

答案 2 :(得分:1)

我怀疑问题在于你是从QWidget继承两次,一次是通过QPushButton,一次是通过Foo。

从你提出这个问题的方式来看,我假设你想为不同类型的小部件做这个,因此不希望有子类QPushButton,QLabel,QCheckBox等。如果这不是那么你应该使用Nikos的答案。

如果没有,最好的办法就是使用event filter

class MousePressFilter : public QObject {
Q_OBJECT
    public:
        MousePressFilter(QObject *parent) : QObject(parent) { }

    protected:
        bool eventFilter(QObject *watched, QEvent *event) {
            QWidget *widget = dynamic_cast<QWidget*>(watched);
            widget->move(0,0);
            return false;
        }
};

然后在你的Foo类构造函数中:

class Foo {
    Foo() {
        installEventFilter( new MousePressFilter(this) );
    }
};