为啥可以从 QWidget 创建一个对象而不在 C++ 程序的开头包含它

Posted

技术标签:

【中文标题】为啥可以从 QWidget 创建一个对象而不在 C++ 程序的开头包含它【英文标题】:Why is it possible to create a object from QWidget without including it at the beginning of the C++ program为什么可以从 QWidget 创建一个对象而不在 C++ 程序的开头包含它 【发布时间】:2015-07-22 08:31:44 【问题描述】:

这是一个创建 GUI 的简单 Qt C++ 程序。我是一名学生,我对 C++ 的熟悉程度也不如 Java。在下面显示的代码中,有一个名为*window 的类QWidget 的窗口对象引用,它没有包含在代码的开头。据我所知,所有包含的小部件都在 QWidget(QSlider & QSpinBox) 下。 QWidget 的基类是什么。 (如果 QObject 和 QWidget 之间有基类)?为什么可以从 QWidget 创建一个对象而不包含它?为什么 QWidget base classwhole object 会显示为一个窗口,如果其他 Widget 类在它下面(见下图)。

图片来自C++-GUI-Programming-with-Qt-4-1st-ed ebook

#include <QApplication>
#include <QHBoxLayout>
#include <QSlider>
#include <QSpinBox>

int main(int argc, char *argv[])

  QApplication app(argc, argv);

  QWidget *window = new QWidget;
  window->setWindowTitle("select your age");


  QSlider *slider = new QSlider(Qt::Horizontal);
  QSpinBox *spin = new QSpinBox;
  slider->setRange(0, 130);
  spin->setRange(0, 130);

  QObject::connect( spin, SIGNAL(valueChanged(int)), slider, SLOT(setValue(int)) );
  QObject::connect( slider, SIGNAL(valueChanged(int)), spin, SLOT(setValue(int)) );

  spin->setValue(30);

  QHBoxLayout *layout = new QHBoxLayout;

  layout->addWidget(spin);
  layout->addWidget(slider);
  window->setLayout(layout);

  window->show();

  return app.exec();

【问题讨论】:

你检查过doc.qt.io/qt-5/qwidget.html#details 吗? “没有嵌入到父小部件中的小部件称为窗口。” 【参考方案1】:

QSlider 继承自 QAbstractSlider,而 QAbstractSlider 本身继承自 QWidget。所以QSlider的包含间接包含QWidget,让你创建一个。 QSpinBox 与任何其他小部件一样,也继承自 QWidget

正如in the doc 解释的那样:

没有父小部件的小部件始终是一个独立的窗口 (***小部件)。

所以QWidget *window 实际上创建了一个带有标题栏的窗口。

【讨论】:

【参考方案2】:

来自Qt documentation:

小部件是用户界面的原子。 (...) 小部件是 被它的父级和它前面的小部件剪裁。

未嵌入到父窗口小部件中的窗口小部件称为窗口。 (...)

没有父小部件的小部件始终是一个独立的窗口 (***小部件)。

希望这会有所帮助。

【讨论】:

这并不能真正回答问题。问题是:“为什么在代码中没有#include &lt;QWidget&gt; 的情况下可以使用QWidget。”【参考方案3】:

QWidget的基类是什么。

QWidget 继承自 QObject 和 QPaintDevice。

为什么可以在不包含 QWidget 的情况下从 QWidget 创建对象?

我猜&lt;QSlider&gt; 和/或&lt;QSpinBox&gt; 包括&lt;QWidget&gt;。是的,为了这个例子,如果还有一个明确的#include &lt;QWidget&gt;,它可能会“更干净”,但显然没有必要。

如果其他 Widget 类在它下面,为什么整个 QWidget 会显示为一个窗口。

抱歉,我不确定你在这里问的是什么。

【讨论】:

【参考方案4】:

QWidget 的基类是什么。 (如果QObject和QWidget之间有基类)?

我不知道。 QWidget 是基本的 GUI 类。我的意思是所有其他 GUI 类都必须从它派生。因此,层次链中位于其之上的内容实际上并不重要。

为什么可以在不包含 QWidget 的情况下创建对象?

我假设你的意思是#include QWidget.h。 QSpinBox 和 QSlider 从它派生,所以我推测它们的头文件包括 QWidget.h。包括是可传递的。

如果其他 Widget 类在它下面,为什么整个 QWidget 会显示为一个窗口。 这个真的不清楚。如果一个小部件不包含其他小部件,那么它作为一个窗口是没有意义的。

【讨论】:

以上是关于为啥可以从 QWidget 创建一个对象而不在 C++ 程序的开头包含它的主要内容,如果未能解决你的问题,请参考以下文章

为啥这个 for 循环在某些平台上退出而不在其他平台上退出?

从 Parse.com 启动 - 为啥 cURL POST 到解析服务器在本地工作而不在 Heroku 上工作?

C语言中已经有了malloc和free,为啥还需要new和delete?

如果'C'从'B'公开继承,B私下从'A'继承,为啥我不能在'C'内部创建'A'的对象? [复制]

为啥 python 模块在 shell 中工作而不在脚本中工作?

如何使用 QWidget 在 QTabWidget 中包含 QList