1.main.cpp
#include "themewidget.h" #include <QtWidgets/QApplication> #include <QtWidgets/QMainWindow> int main(int argc, char *argv[]) { QApplication a(argc, argv); QMainWindow window; ThemeWidget *widget = new ThemeWidget(); window.setCentralWidget(widget); window.resize(900, 600); window.show(); return a.exec(); }
关于window.setCentralWidget(widget);
QT帮助:
void QMainWindow::setCentralWidget(QWidget *widget)
//将给定的小部件设置为主窗口的*小部件
Sets the given widget to be the main window's central widget.
//注意:QMainWindow拥有窗口小部件指针的所有权,并在适当的时间将其删除。另请参见centralWidget()。
Note: QMainWindow takes ownership of the widget pointer and deletes it at the appropriate time. See also centralWidget().
QWidget *QMainWindow::centralWidget() const
//返回主窗口的*窗口小部件。如果尚未设置*窗口小部件,则此函数返回零。
Returns the central widget for the main window. This function returns zero if the central widget has not been set.
2.themewidget.h
#ifndef THEMEWIDGET_H #define THEMEWIDGET_H #include <QtWidgets/QWidget> #include <QtCharts/QChartGlobal> QT_BEGIN_NAMESPACE class QComboBox; class QCheckBox; class Ui_ThemeWidgetForm; QT_END_NAMESPACE QT_CHARTS_BEGIN_NAMESPACE class QChartView; class QChart; QT_CHARTS_END_NAMESPACE typedef QPair<QPointF, QString> Data; typedef QList<Data> DataList; typedef QList<DataList> DataTable; QT_CHARTS_USE_NAMESPACE class ThemeWidget: public QWidget { Q_OBJECT public: explicit ThemeWidget(QWidget *parent = 0); ~ThemeWidget(); private Q_SLOTS: void updateUI(); private: DataTable generateRandomData(int listCount, int valueMax, int valueCount) const; void populateThemeBox(); void populateAnimationBox(); void populateLegendBox(); void connectSignals(); QChart *createAreaChart() const; QChart *createBarChart(int valueCount) const; QChart *createPieChart() const; QChart *createLineChart() const; QChart *createSplineChart() const; QChart *createScatterChart() const; private: int m_listCount; int m_valueMax; int m_valueCount; QList<QChartView *> m_charts; DataTable m_dataTable; Ui_ThemeWidgetForm *m_ui; }; #endif /* THEMEWIDGET_H */
1)关于#ifnde XXX f#define XXX #endif
其作用是“防止头文件被重复引用。”
“被重复引用”是指一个头文件在同一个cpp文件中被include了多次,这种错误常常是由于include嵌套造成的。比如:存在a.h文件#include "c.h"而此时b.cpp文件导入了#include "a.h" 和#include "c.h"此时就会造成c.h重复引用。
头文件被重复引用引起的后果:
有些头文件重复引用只是增加了编译工作的工作量,不会引起太大的问题,仅仅是编译效率低一些,但是对于大工程而言编译效率低下那将是一件多么痛苦的事情。
有些头文件重复包含,会引起错误,比如在头文件中定义了全局变量(虽然这种方式不被推荐,但确实是C规范允许的)这种会引起重复定义。
是不是所有的头文件中都要加入#ifndef/#define/#endif 这些代码?
答案:不是一定要加,但是不管怎样,用#ifnde xxx #define xxx #endif或者其他方式避免头文件重复包含,只有好处没有坏处。个人觉得培养一个好的编程习惯是学习编程的一个重要分支。
下面给一个#ifndef/#define/#endif的格式:
#ifndef A_H意思是"if not define a.h" 如果不存在a.h
接着的语句应该#define A_H 就引入a.h
最后一句应该写#endif 否则不需要引入
2)关于QT_BEGIN_NAMESPACE
对于QT_BEGIN_NAMESPACE宏的作用
QT_BEGIN_NAMESPACE其实就是个宏,以前Qt4是没有命令空间的,后来才加上的,编译Qt源码时会有选项,是否将这些类放到专用的Qt命令空间内,默认是没有的。这就出来问题了,为了统一,如果你的代码在默认没有Qt命令空间的SDK中编译,那你就不用在前面加上命令空间,反之则需要。
为了屏蔽上面这个差异,使得你的代码能在这两种情况下都进行编译,Qt就提供了QT_BEGIN_NAMESPACE宏,这样开发者就省的自己来用程序或宏进行处理了。
补充:关于namespace
假设这样一种情况,当一个班上有两个名叫 Zara 的学生时,为了明确区分它们,我们在使用名字之外,不得不使用一些额外的信息,比如他们的家庭住址,或者他们父母的名字等等。
同样的情况也出现在 C++ 应用程序中。例如,您可能会写一个名为 xyz() 的函数,在另一个可用的库中也存在一个相同的函数 xyz()。这样,编译器就无法判断您所使用的是哪一个 xyz() 函数。
因此,引入了命名空间这个概念,专门用于解决上面的问题,它可作为附加信息来区分不同库中相同名称的函数、类、变量等。使用了命名空间即定义了上下文。本质上,命名空间就是定义了一个范围。
我们举一个计算机系统中的例子,一个文件夹(目录)中可以包含多个文件夹,每个文件夹中不能有相同的文件名,但不同文件夹中的文件可以重名。
关于QT_CHARTS_BEGIN_NAMESPACE同理。