先确认是 Qt 5 还是 Qt 6
跳转到“先确认是 Qt 5 还是 Qt 6”包含 <QtCharts/QPolarChart> 解决“声明从哪里来”;写不写 QtCharts:: 则取决于该版本把 C++ 类型放在哪个命名空间。Qt 模块名、头文件目录名和 C++ 命名空间不是同一个概念。
| 版本或场景 | 类型的写法 |
|---|---|
| Qt 5 的 Qt Charts | 常见写法是 QtCharts::QPolarChart;旧例子也使用 QT_CHARTS_USE_NAMESPACE |
| Qt 6 的 Qt Charts | 不再有专用 QtCharts 命名空间;普通 Qt 构建直接使用 QPolarChart |
| 自行配置了 Qt 全局命名空间的构建 | 还需遵循该 Qt 构建的命名空间设置,不能假定所有 Qt 都在全局作用域 |
Qt 6 的迁移说明明确说明了这项变化。因此,不能把旧项目中的 using namespace QtCharts 或 QT_CHARTS_USE_NAMESPACE 原样移植到 Qt 6。Qt Charts 的 Qt 6 变更
Qt Charts 自 Qt 6.10 起被标记为弃用,新项目可评估 Qt Graphs;本页保留 Qt Charts,是为了解释并维护原来的 QWidget 极坐标图代码,迁移框架需要另外评估控件、渲染和 API 差异。Qt Charts 模块说明
using 不会减少冲突
跳转到“using 不会减少冲突”using namespace 让未限定名称查找考虑整个命名空间,可能引入歧义。Qt 5 中可用限定名,或在实现文件/较小作用域里只引入需要的名称;不宜在公共头文件全局放置整个命名空间的 using 指令,以免影响每个包含它的文件。
前置声明只声明类型存在,不能靠它调用构造函数、成员或按值保存完整对象。在第三方命名空间里自行补声明还可能与库的宏命名空间设置不一致;优先使用对应官方头文件。
原头文件的 __POLARCHART_H 使用了保留标识符,类定义还省略内容和结尾分号。下面改为完整程序,继续使用 BalancingPolarChart、QFrame、QPolarChart、QChartView、QLineSeries、QValueAxis 和布局。
Qt 6 极坐标窗口的完整例子
跳转到“Qt 6 极坐标窗口的完整例子”main.cpp:
#include <QApplication>#include <QFrame>#include <QImage>#include <QPainter>#include <QVBoxLayout>#include <QtCharts/QChartView>#include <QtCharts/QLineSeries>#include <QtCharts/QPolarChart>#include <QtCharts/QValueAxis>#include <cassert>#include <iostream>
class BalancingPolarChart final : public QFrame {public: explicit BalancingPolarChart(QWidget *parent = nullptr) : QFrame(parent) { auto *chart = new QPolarChart; chart->setTitle(QStringLiteral("Balance sample")); auto *series = new QLineSeries; series->append(0, 4); series->append(90, 7); series->append(180, 3); series->append(270, 6); series->append(360, 4); chart->addSeries(series); // Chart owns the series after addition.
auto *angle = new QValueAxis; angle->setRange(0, 360); angle->setTickCount(9); angle->setLabelFormat("%.0f"); chart->addAxis(angle, QPolarChart::PolarOrientationAngular); auto *radius = new QValueAxis; radius->setRange(0, 10); radius->setTickCount(6); chart->addAxis(radius, QPolarChart::PolarOrientationRadial); const bool angleAttached = series->attachAxis(angle); const bool radiusAttached = series->attachAxis(radius); assert(angleAttached && radiusAttached); assert(series->count() == 5 && chart->axes().size() == 2); assert(angle->max() == 360 && radius->max() == 10);
auto *view = new QChartView(chart, this); // View takes chart ownership. view->setRenderHint(QPainter::Antialiasing); auto *layout = new QVBoxLayout(this); layout->addWidget(view); }};
int main(int argc, char **argv) { QApplication app(argc, argv); BalancingPolarChart widget; widget.resize(640, 480); if (app.arguments().contains(QStringLiteral("--interactive"))) { widget.show(); return app.exec(); } QImage frame(widget.size(), QImage::Format_ARGB32); frame.fill(Qt::transparent); widget.render(&frame); assert(!frame.isNull()); std::cout << "polar series, axes and widget render passed\n";}CMakeLists.txt:
cmake_minimum_required(VERSION 3.20)project(PolarChartExample LANGUAGES CXX)set(CMAKE_CXX_STANDARD 17)set(CMAKE_CXX_STANDARD_REQUIRED ON)find_package(Qt6 REQUIRED COMPONENTS Widgets Charts)add_executable(polar_chart main.cpp)target_link_libraries(polar_chart PRIVATE Qt6::Widgets Qt6::Charts)没有自定义信号、属性或槽,因此此类不需要 Q_OBJECT。示例使用 QApplication,因为 QChartView 是 QWidget;只链接模块还不等于配置了需要的类声明。缺少 Charts 模块时应安装与 Kit 匹配的组件,而不是尝试用 using 指令修复链接错误。
程序默认完成结构断言和一次绘制后退出,传入 --interactive 可查看窗口。示意数据没有平衡算法、角度校准或真实测量含义;它只验证原问题涉及的命名、所有权、轴与布局连接。