QT项目-Chart Themes Example学习(一)

时间:2024-01-28 20:39:58

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同理。