【问题标题】:Proper subclassing with Qt Creator forms?使用 Qt Creator 表单进行正确的子类化?
【发布时间】:2014-07-15 17:43:27
【问题描述】:

我正在尝试创建一个类 (AgilentSweeper),它是 QDockWidget 的子类,以便我可以在 Qt Creator 的表单设计器中为其设计布局。该类的标题如下所示:

// agilentsweeper.h
#ifndef AGILENTSWEEPER_H
#define AGILENTSWEEPER_H

#include <QDockWidget>

namespace Ui {
class AgilentSweeper;
}

class AgilentSweeper : public QDockWidget
{
    Q_OBJECT

public:
    explicit AgilentSweeper(QWidget *parent = 0);
    ~AgilentSweeper();

private:
    Ui::AgilentSweeper *ui;
};

#endif // AGILENTSWEEPER_H

来源看起来像

// agilentsweeper.cpp
#include "agilentsweeper.h"
#include "ui_agilentsweeper.h"
#include <QDockWidget>

AgilentSweeper::AgilentSweeper(QWidget *parent) :
    QDockWidget(parent),
    ui(new Ui::AgilentSweeper)
{
    ui->setupUi(this);
}

AgilentSweeper::~AgilentSweeper()
{
    delete ui;
}

在我的主类 h 文件中,我使用

声明了一个 AgilentSweeper 实例
#ifndef UTILSWEEP_H
#define UTILSWEEP_H

#include <QMainWindow>
#include <QDockWidget>
#include "agilentsweeper.h"

namespace Ui {
class UtilSweep;
}

class UtilSweep : public QMainWindow
{
    Q_OBJECT

public:
    explicit UtilSweep(QWidget *parent = 0);
    ~UtilSweep();

private:
    Ui::UtilSweep *ui;
    AgilentSweeper sweeper;
};

#endif // UTILSWEEP_H

在主类的构造函数中,我尝试在主窗口的一侧显示“清扫器”

#include "utilsweep.h"
#include "ui_utilsweep.h"
#include "agilentsweeper.h"
#include <QDockWidget>
#include <QMainWindow>

UtilSweep::UtilSweep(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::UtilSweep)
{
    ui->setupUi(this);
    addDockWidget(Qt::LeftDockWidgetArea,sweeper);
}

UtilSweep::~UtilSweep()
{
    delete ui;
}

但是,我收到一个错误

In constructor 'UtilSweep::UtilSweep(QWidget*)':  utilsweep.cpp:12: error: no matching function for call to 'UtilSweep::addDockWidget(Qt::DockWidgetArea, AgilentSweeper&)'
 addDockWidget(Qt::LeftDockWidgetArea,sweeper);

提示

candidates are:  void QMainWindow::addDockWidget(Qt::DockWidgetArea, QDockWidget*)
 void addDockWidget(Qt::DockWidgetArea area, QDockWidget *dockwidget);

环顾四周,我发现其他几个人也有类似的错误,但在他们的情况下,似乎某些地方没有包含 QDockWidget,或者他们没有使用 Q_OBJECT。这里出了什么问题?

【问题讨论】:

    标签: c++ qt qt-creator subclass


    【解决方案1】:

    addDockWidget() 需要一个指向 QDockWidget 对象的指针作为第二个参数。您的类变量sweeper 是对象本身,而不是指针。您添加addDockWidget() 的电话应该是:

    addDockWidget(Qt::LeftDockWidgetArea, &sweeper);
    

    【讨论】:

    • 我没有检查,所以可能是错的,但是......主窗口在被破坏时不会尝试delete停靠小部件吗?而且由于sweeper 没有分配给new,所以当程序退出时主窗口被销毁时,这应该会崩溃。
    • 请参阅qt-project.org/doc/qt-4.8/…,了解有关在堆栈和堆上声明 QObjects 的详细信息。秩序很重要。上述工作是在孩子之前声明父母。我测试确认。 @hyde 建议的解决方案,用new 声明AgilentSweeper,是声明QObjects 时的典型约定。
    • @esorton 嗯,是的。 sweeperUtilSweep 的成员,因此在调用 QObject 超类析构函数(删除剩余的子对象)之前将被破坏(并将自身作为对象的子对象移除)。
    【解决方案2】:

    你应该把sweeper改成指针,用new分配:

    class UtilSweep : public QMainWindow
    {
        ...
        AgilentSweeper *sweeper;
    };
    

    UtilSweep::UtilSweep(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::UtilSweep),
        sweeper(new AgilentSweeper(this))
    {
        ui->setupUi(this);
        addDockWidget(Qt::LeftDockWidgetArea, sweeper);
    }
    

    【讨论】:

    • 有什么理由以这种方式分配扫地机而不是像ui-&gt;setupUi(this); sweeper = new AgilentSweeper(this);那样稍后分配?
    猜你喜欢
    • 1970-01-01
    • 2016-11-05
    • 1970-01-01
    • 2015-07-29
    • 1970-01-01
    • 1970-01-01
    • 2019-02-16
    • 1970-01-01
    • 2018-06-03
    相关资源
    最近更新 更多