#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "sparkline_plotitem.h" #include "backend.h" #include "data_frame.h" #include "glwidget.h" #include "translation_manager.h" #include "src/sparkline_plotitem.h" int main(int argc, char *argv[]) { QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL); // 统一OpenGL格式 QSurfaceFormat fmt; fmt.setRenderableType(QSurfaceFormat::OpenGL); fmt.setVersion(3, 3); fmt.setProfile(QSurfaceFormat::CoreProfile); fmt.setDepthBufferSize(24); fmt.setStencilBufferSize(8); fmt.setSwapInterval(1); QSurfaceFormat::setDefaultFormat(fmt); QApplication a(argc, argv); QQuickStyle::setStyle("Material"); { QOpenGLContext probeCtx; probeCtx.setFormat(QSurfaceFormat::defaultFormat()); if (!probeCtx.create()) { qCritical().noquote() << "Failed to create an OpenGL context " "(required: OpenGL 3.3 Core)."; return 1; } QOffscreenSurface probeSurface; probeSurface.setFormat(probeCtx.format()); probeSurface.create(); if (!probeCtx.makeCurrent(&probeSurface)) { qCritical().noquote() << "Failed to make the OpenGL context current. This usually " "means the requested format is unsupported by the current " "graphics driver."; return 1; } const QSurfaceFormat actual = probeCtx.format(); const bool versionOk = (actual.majorVersion() > 3) || (actual.majorVersion() == 3 && actual.minorVersion() >= 3); if (!versionOk || actual.profile() != QSurfaceFormat::CoreProfile) { probeCtx.doneCurrent(); qCritical().noquote() << "OpenGL context is not OpenGL 3.3 Core (got: " << actual.majorVersion() << "." << actual.minorVersion() << ", profile=" << actual.profile() << ")."; return 1; } probeCtx.doneCurrent(); } auto *win = new QMainWindow; auto *root = new QWidget; auto *rootLayout = new QVBoxLayout(root); rootLayout->setContentsMargins(0, 0, 0, 0); rootLayout->setSpacing(0); AppBackend backend; TranslationManager i18n; qmlRegisterSingletonInstance("TactileIPC", 1, 0, "Backend", &backend); qmlRegisterSingletonInstance("TactileIPC", 1, 0, "I18n", &i18n); qmlRegisterType("LiveTrend", 1, 0, "SparklinePlot"); i18n.setLanguage(backend.language()); QObject::connect( &backend, &AppBackend::languageChanged, &i18n, [&backend, &i18n]() { i18n.setLanguage(backend.language()); }); auto *qmlEngine = new QQmlEngine(root); auto createQuickWidget = [&](const QUrl &sourceUrl) -> QQuickWidget * { auto *view = new QQuickWidget(qmlEngine, root); view->setResizeMode(QQuickWidget::SizeRootObjectToView); view->setSource(sourceUrl); return view; }; auto *navView = createQuickWidget(QUrl("qrc:/qml/content/NavBar.qml")); navView->setFixedHeight(56); auto *splitter = new QSplitter; splitter->setOrientation(Qt::Horizontal); splitter->setHandleWidth(1); auto *leftView = createQuickWidget(QUrl("qrc:/qml/content/LeftPanel.qml")); leftView->setFixedWidth(350); auto *glw = new GLWidget; glw->setSpec(12, 7, 0.1f, 0.03f); glw->setPanelThickness(0.08f); glw->setRange(backend.rangeMin(), backend.rangeMax()); glw->setColorLow(backend.colorLow()); glw->setColorMid(backend.colorMid()); glw->setColorHigh(backend.colorHigh()); /* backend.data()->setLiveRenderCallback([glw](const DataFrame& frame) { if (frame.data.size() != glw->dotCount()) return; glw->submitValues(frame.data); }); */ backend.data()->setLiveRenderCallback([glw](const DataFrame &frame) { if (frame.data.size() != 0) { glw->submitValues(frame.data); } }); // TODO:待实现内容(将frame数据分发给右侧曲线/指标的QML接口) auto *rightView = createQuickWidget(QUrl("qrc:/qml/content/RightPanel.qml")); splitter->addWidget(leftView); splitter->addWidget(glw); splitter->addWidget(rightView); splitter->setStretchFactor(0, 0); splitter->setStretchFactor(1, 1); splitter->setStretchFactor(2, 0); splitter->setSizes({320, 640, 320}); auto applySplitterStyle = [&backend, splitter]() { const QString handleColor = backend.lightMode() ? QStringLiteral("#E0E0E0") : QStringLiteral("#2C2C2C"); splitter->setStyleSheet( QStringLiteral("QSplitter::handle { background: %1; }") .arg(handleColor)); }; applySplitterStyle(); QObject::connect(&backend, &AppBackend::lightModeChanged, splitter, [applySplitterStyle]() { applySplitterStyle(); }); auto applyQuickTheme = [&backend, navView, leftView, rightView]() { const QColor navColor = backend.lightMode() ? QColor(QStringLiteral("#F5F7F5")) : QColor(QStringLiteral("#2B2F2B")); const QColor panelColor = backend.lightMode() ? QColor(QStringLiteral("#F5F5F5")) : QColor(QStringLiteral("#2C2C2C")); navView->setClearColor(navColor); leftView->setClearColor(panelColor); rightView->setClearColor(panelColor); }; applyQuickTheme(); QObject::connect(&backend, &AppBackend::lightModeChanged, navView, [applyQuickTheme]() { applyQuickTheme(); }); QObject::connect(&backend, &AppBackend::lightModeChanged, glw, [&backend, glw]() { bool m = backend.lightMode() ? true : false; glw->setLightMode(m); }); QObject::connect(&backend, &AppBackend::showGridChanged, glw, &GLWidget::setShowGrid); QObject::connect(&backend, &AppBackend::sensorRowChanged, glw, &GLWidget::setRow); QObject::connect(&backend, &AppBackend::sensorColChanged, glw, &GLWidget::setCol); QObject::connect(&backend, &AppBackend::rangeChanged, glw, &GLWidget::setRange); QObject::connect(&backend, &AppBackend::colorLowChanged, glw, &GLWidget::setColorLow); QObject::connect(&backend, &AppBackend::colorMidChanged, glw, &GLWidget::setColorMid); QObject::connect(&backend, &AppBackend::colorHighChanged, glw, &GLWidget::setColorHigh); rootLayout->addWidget(navView); rootLayout->addWidget(splitter); win->setCentralWidget(root); win->resize(1280, 720); win->show(); return QApplication::exec(); }