从自定义小部件继承

Posted

技术标签:

【中文标题】从自定义小部件继承【英文标题】:Inheriting from Custom Widget 【发布时间】:2014-06-17 01:05:36 【问题描述】:

我有一个抽象类 TableWidget,它继承自 QWidget。它实现了paintEvent。

class TableWidget : public QWidget

    Q_OBJECT

private:
    int width;
    int height;

public:
    explicit TableWidget(QWidget *parent = 0);

    virtual int getWidthInCells() = 0;
    virtual int getHeightInCells() = 0;

    virtual QString getCellText(byte x, byte y) = 0;
    virtual QString getColumnLabel(byte a) = 0;
    virtual QString getRowLabel(byte a) = 0;
    byte getCellHighlight(byte x, byte y);
    void setCellHighlight(byte x, byte y, bool highlighted);

    void setHeight(int h);
    void setWidth(int w);

protected:
    void paintEvent(QPaintEvent *e);

signals:

public slots:

;

我尝试用一​​个几乎没有任何功能的虚拟类来测试 TableWidget。

class DummyTable : public TableWidget 

public:
    explicit DummyTable(QWidget *parent = 0) 

    int getWidthInCells() return 2;
    int getHeightInCells() return 2;

    QString getCellText(byte x, byte y) return "0";
    QString getColumnLabel(byte a) return QString(a);
    QString getRowLabel(byte a) return QString(a);

;

问题是paintEvent(在TableWidget.cpp 中实现)从未被调用。我注意到的第一个错误是 DummyTable 中没有 Q_OBJECT 宏。我将其添加并对其进行了测试,但这导致无法正确终止。我必须完全退出 QT 才能终止该进程。我查看了QPushButton,它似乎做的事情和我一样,除了包含 Q_OBJECT。

那么,我怎样才能正确调用paintEvent?

【问题讨论】:

【参考方案1】:

您是如何将 DummyTable 实例添加到父窗口的?

您可以尝试在父窗口上调用调试方法 dumpObjectTree (http://qt-project.org/doc/qt-4.8/qobject.html#dumpObjectTree) 以检查您的实例是否正确地作为父窗口。

您也可以尝试实现 showEvent(...) 并对其进行检测以检查小部件是否正在实际显示。

你看过 QTableWidget 吗?它不能满足您的需要吗? http://qt-project.org/doc/qt-4.8/qtablewidget.html

关于 QObject 宏,您只需要在创建信号和插槽连接的类中,或使用 Qt 的其他一些元编程功能(例如属性)。它不太可能是您的问题的根本原因。

【讨论】:

【参考方案2】:

您可能需要为小部件提供适当的宽度和高度。如果它没有大小,则不会调用paintEvent。

【讨论】:

我读到过这种可能性,但事实并非如此; .ui 文件给它一个宽度和高度。我也尝试过手动操作,但没有成功。【参考方案3】:

结果证明这是一个非常愚蠢的错误。我没有调用父类的构造函数。

【讨论】:

以上是关于从自定义小部件继承的主要内容,如果未能解决你的问题,请参考以下文章

Flutter 如何从自定义小部件中获取价值

从自定义主题继承所需的 XML 属性

如何让 qt 设计器自定义 QOpenGLWidget 小部件背景透明?

Flutter:继承自抽象的无状态小部件

如何在 Qt-Designer 中使用自定义小部件

我们如何从自定义列表中的项目中删除默认的蓝色背景?