// ElaWidgetTools 评估 spike(隔离 demo,不属于产品 app,仅 feat/elawidgettools 分支评估用)。 // 一锤定音验证四件事: // ① 用你们官方 Qt 6.11.1 + MSVC 经 FetchContent 能否构建 ElaWidgetTools(RainbowCandyX fork); // ② ElaWindow 的 Fluent 观感在你们机器上渲染是否正常(重点看 Qt6.11 的 Popup/弹窗); // ③ Qt Advanced Docking System(ADS) 能否内嵌进 ElaWindow; // ④ QVTKOpenGLStereoWidget 视口在 ElaWindow + ADS 内能否正常渲染。 // 结论决定是否值得对真实 app 做外壳重构。 #include #include #include #include #include #include "ElaApplication.h" #include "ElaDef.h" #include "ElaPushButton.h" #include "ElaText.h" #include "ElaTheme.h" #include "ElaWindow.h" #include #include #include #include #include #include #include #include #include #include int main(int argc, char* argv[]) { QApplication::setHighDpiScaleFactorRoundingPolicy( Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); QSurfaceFormat::setDefaultFormat(QVTKOpenGLStereoWidget::defaultFormat()); QApplication app(argc, argv); eApp->init(); // ElaApplication 初始化(Fluent 主题/字体/动画基建) ElaWindow window; window.setWindowTitle(QStringLiteral("ElaWidgetTools Spike — Fluent + ADS + VTK")); window.resize(1200, 760); // 「工作台」页内嵌 ADS 停靠管理器:验证 ADS 能否在 ElaWindow 内正常工作。 auto* dockHost = new QWidget; auto* hostLay = new QVBoxLayout(dockHost); hostLay->setContentsMargins(0, 0, 0, 0); auto* dockManager = new ads::CDockManager(dockHost); hostLay->addWidget(dockManager); // dock1:Fluent 控件样例(看观感:ElaText / ElaPushButton 与标准控件对照)。 auto* sample = new QWidget; sample->setObjectName(QStringLiteral("sampleHost")); auto* sLay = new QVBoxLayout(sample); sLay->setContentsMargins(16, 16, 16, 16); sLay->setSpacing(12); sLay->addWidget(new ElaText(QStringLiteral("ElaText —— Fluent 文本"), sample)); sLay->addWidget(new ElaPushButton(QStringLiteral("ElaPushButton 主操作"), sample)); sLay->addWidget(new QLabel(QStringLiteral("(对照)标准 QLabel"), sample)); // 浅/深主题切换:ElaWidgetTools 内置 ElaTheme,运行期一键切换整套 Fluent 主题。 auto* themeBtn = new ElaPushButton(QStringLiteral("切换 浅色 / 深色"), sample); QObject::connect(themeBtn, &QPushButton::clicked, themeBtn, [] { eTheme->setThemeMode(eTheme->getThemeMode() == ElaThemeType::Light ? ElaThemeType::Dark : ElaThemeType::Light); }); sLay->addWidget(themeBtn); sLay->addStretch(); auto* d1 = new ads::CDockWidget(QStringLiteral("Fluent 控件")); d1->setWidget(sample); dockManager->addDockWidget(ads::LeftDockWidgetArea, d1); // dock2:QVTK 视口(蓝色锥体),验证 VTK 在 ElaWindow + ADS 内渲染。 auto* vtkWidget = new QVTKOpenGLStereoWidget; vtkNew renderWindow; vtkNew renderer; renderer->SetBackground(1.0, 1.0, 1.0); vtkWidget->setRenderWindow(renderWindow); renderWindow->AddRenderer(renderer); vtkNew cone; cone->SetResolution(48); vtkNew mapper; mapper->SetInputConnection(cone->GetOutputPort()); vtkNew actor; actor->SetMapper(mapper); actor->GetProperty()->SetColor(0.18, 0.42, 0.71); // 品牌蓝 #2D6CB5 近似 renderer->AddActor(actor); renderer->ResetCamera(); auto* d2 = new ads::CDockWidget(QStringLiteral("VTK 视口(锥体)")); d2->setWidget(vtkWidget); dockManager->addDockWidget(ads::RightDockWidgetArea, d2); // 关键发现演示:ADS 停靠区与普通 QWidget 不会自动跟随 ElaTheme(只有 Ela* 控件与 // ElaWindow 外壳跟随)。这里手动把「停靠区背景 + 普通容器 + VTK 背景」同步到当前主题, // 并监听 ElaTheme::themeModeChanged。这段「同步」正是真集成时要为每个非 Ela 面板付出的成本。 auto* rendererPtr = renderer.Get(); auto* rwPtr = renderWindow.Get(); auto applyContentTheme = [dockManager, sample, rendererPtr, rwPtr](ElaThemeType::ThemeMode mode) { const bool dark = (mode == ElaThemeType::Dark); const QString bg = dark ? QStringLiteral("#1E1F22") : QStringLiteral("#FFFFFF"); const QString fg = dark ? QStringLiteral("#E3E3E3") : QStringLiteral("#1F2A3D"); dockManager->setStyleSheet( QStringLiteral("ads--CDockAreaWidget, ads--CDockContainerWidget { background:%1; }") .arg(bg)); sample->setStyleSheet( QStringLiteral("#sampleHost { background:%1; } #sampleHost QLabel { color:%2; }") .arg(bg, fg)); rendererPtr->SetBackground(dark ? 0.11 : 1.0, dark ? 0.12 : 1.0, dark ? 0.14 : 1.0); rwPtr->Render(); }; QObject::connect(eTheme, &ElaTheme::themeModeChanged, dockManager, [applyContentTheme](ElaThemeType::ThemeMode m) { applyContentTheme(m); }); applyContentTheme(eTheme->getThemeMode()); // 初始同步当前主题 window.addPageNode(QStringLiteral("工作台"), dockHost); window.show(); return app.exec(); }