使用 Qt Creator 表单进行正确的子类化?
Posted
技术标签:
【中文标题】使用 Qt Creator 表单进行正确的子类化?【英文标题】:Proper subclassing with Qt Creator forms? 【发布时间】: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。这里出了什么问题?
【问题讨论】:
【参考方案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 嗯,是的。 sweeper
是 UtilSweep
的成员,因此在调用 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->setupUi(this); sweeper = new AgilentSweeper(this);
那样稍后分配?以上是关于使用 Qt Creator 表单进行正确的子类化?的主要内容,如果未能解决你的问题,请参考以下文章
Qt Creator 2.6.2 和 Qt 4.8.4:Qt 版本未正确安装