From 452f7c8e5f13b7570641998205a2bf506c1ce5e8 Mon Sep 17 00:00:00 2001 From: tangchao0503 <735056338@qq.com> Date: Tue, 10 Mar 2026 17:21:21 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=8A=9F=E8=83=BD=EF=BC=9A?= =?UTF-8?q?=E6=94=B9=E5=8F=98=E5=9B=BE=E5=83=8F=E6=98=BE=E7=A4=BA=E7=9A=84?= =?UTF-8?q?rgb=E6=B3=A2=E6=AE=B5=EF=BC=9B=201=E3=80=81=E5=8F=AF=E6=94=B9?= =?UTF-8?q?=E5=8F=98=E5=9B=BE=E5=83=8F=E6=98=BE=E7=A4=BA=E6=B3=A2=E6=AE=B5?= =?UTF-8?q?=EF=BC=8C=E5=BD=93=E4=BF=AE=E6=94=B9=E5=AE=8C=E6=88=90=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E6=97=B6=E5=AE=9E=E6=97=B6=E5=88=B7=E6=96=B0=E5=9B=BE?= =?UTF-8?q?=E5=83=8F=EF=BC=9B=202=E3=80=81TOC=E4=B8=AD=E5=88=87=E6=8D=A2?= =?UTF-8?q?=E9=80=89=E4=B8=AD=E7=9A=84=E5=A4=9A=E5=9B=BE=E5=B1=82=E6=97=B6?= =?UTF-8?q?=EF=BC=8C=E5=88=B7=E6=96=B0=E6=B8=B2=E6=9F=93=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=EF=BC=9B=203=E3=80=81=E7=95=8C=E9=9D=A2=E4=B8=AD=E4=BF=9D?= =?UTF-8?q?=E5=AD=98=E5=9B=BE=E5=83=8F=E7=9A=84=E6=B3=A2=E9=95=BF=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=EF=BC=8C=E5=8F=82=E6=95=B0=E4=BF=AE=E6=94=B9=E6=97=B6?= =?UTF-8?q?=E7=9A=84=E9=80=89=E9=A1=B9=E5=B0=B1=E6=98=AF=E5=87=86=E7=A1=AE?= =?UTF-8?q?=E7=9A=84=E6=B3=A2=E9=95=BF=E4=BF=A1=E6=81=AF=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HPPA/HPPA.cpp | 6 +- HPPA/ImageViewer.cpp | 18 +++- HPPA/ImageViewer.h | 8 +- HPPA/RasterLayer.cpp | 30 ++++++ HPPA/RasterLayer.h | 11 ++ HPPA/imageControl.cpp | 239 +++++++++++++++++++++++++++++++----------- HPPA/imageControl.h | 33 ++++-- HPPA/imgControl.ui | 69 ++++++++++-- 8 files changed, 330 insertions(+), 84 deletions(-) diff --git a/HPPA/HPPA.cpp b/HPPA/HPPA.cpp index 27df1cf..0438f61 100644 --- a/HPPA/HPPA.cpp +++ b/HPPA/HPPA.cpp @@ -483,10 +483,6 @@ sizePolicy1.setHeightForWidth(graphicsView_delete->sizePolicy().hasHeightForWidt initControlTabwidget(); m_tabManager = new TabManager(ui.controlTabWidget, this); - // Connect ImageControl band change to re-render (m_ic created in initControlTabwidget) - connect(m_ic, SIGNAL(bandSelectionChanged(double,double,double)), - this, SLOT(onBandSelectionChanged(double,double,double))); - //3D模型看板 ui.mDockWidgetSimulator->setTile(QString::fromLocal8Bit("3D模型")); //ui.mDockWidgetSimulator->show(); @@ -726,6 +722,8 @@ void HPPA::initControlTabwidget() //图像控制 m_ic = new ImageControl(); m_ic->setWindowFlags(Qt::Widget); + connect(m_ic, SIGNAL(bandSelectionChanged(double, double, double)), + this, SLOT(onBandSelectionChanged(double, double, double))); ui.controlTabWidget->addTab(m_ic, QString::fromLocal8Bit("图像控制")); //升降桌dock diff --git a/HPPA/ImageViewer.cpp b/HPPA/ImageViewer.cpp index e00b72b..794f221 100644 --- a/HPPA/ImageViewer.cpp +++ b/HPPA/ImageViewer.cpp @@ -220,12 +220,28 @@ void Mapcavas::setLayers(RasterLayer* layer) m_rasterLayer = layer; } +RasterLayer* Mapcavas::rasterLayer() const +{ + return m_rasterLayer; +} + // new: refresh the map by rendering using the RasterLayer's render method void Mapcavas::freshmap() { if (!m_rasterLayer) return; - RasterLayer::RenderParams params; // default params; could be extended + RasterLayer::RenderParams params = m_rasterLayer->currentRenderParams(); + QImage img = m_rasterLayer->render(params); + if (img.isNull()) return; + + QPixmap pm = QPixmap::fromImage(img); + SetImage(&pm); +} + +void Mapcavas::freshmap(const RasterLayer::RenderParams& params) +{ + if (!m_rasterLayer) return; + QImage img = m_rasterLayer->render(params); if (img.isNull()) return; diff --git a/HPPA/ImageViewer.h b/HPPA/ImageViewer.h index ec68447..bc1df68 100644 --- a/HPPA/ImageViewer.h +++ b/HPPA/ImageViewer.h @@ -4,8 +4,7 @@ #include "QGraphicsView" #include "qlabel.h" #include - -class RasterLayer; // forward +#include "RasterLayer.h" class Mapcavas : public QGraphicsView { @@ -46,6 +45,9 @@ public: // new: set raster layer and refresh map void setLayers(RasterLayer* layer); void freshmap(); + void freshmap(const RasterLayer::RenderParams& params); + + RasterLayer* rasterLayer() const; protected: QGraphicsScene *m_qtGraphicsScene; @@ -65,4 +67,4 @@ private: signals: void leftMouseButtonPressed(int, int, QVector, QVector); }; -#endif \ No newline at end of file +#endif diff --git a/HPPA/RasterLayer.cpp b/HPPA/RasterLayer.cpp index 7c652c0..7751f88 100644 --- a/HPPA/RasterLayer.cpp +++ b/HPPA/RasterLayer.cpp @@ -1,6 +1,7 @@ #include "RasterLayer.h" #include "RasterDataProvider.h" #include "RasterRenderer.h" +#include RasterLayer::RasterLayer(const QString& name, const QString& uri) : MapLayer(name, uri) @@ -84,3 +85,32 @@ QImage RasterLayer::render(const RenderParams& params) p.maxValue = params.maxValue; return m_renderer->render(p); } + +RasterLayer::RenderParams RasterLayer::currentRenderParams() const +{ + return m_currentParams; +} + +void RasterLayer::setCurrentRenderParams(const RenderParams& params) +{ + m_currentParams = params; +} + +bool RasterLayer::wavelengthRange(double& minWave, double& maxWave) const +{ + auto wl = bandWavelengths(); + if (wl.empty()) return false; + minWave = *std::min_element(wl.begin(), wl.end()); + maxWave = *std::max_element(wl.begin(), wl.end()); + return true; +} + +std::vector RasterLayer::bandWavelengths() const +{ + if (!m_provider) { + // need to open provider to read wavelengths - cast away const for lazy init + auto* self = const_cast(this); + if (!self->openDataProvider()) return {}; + } + return m_provider->bandWavelengths(); +} diff --git a/HPPA/RasterLayer.h b/HPPA/RasterLayer.h index d1e15f4..462a3fe 100644 --- a/HPPA/RasterLayer.h +++ b/HPPA/RasterLayer.h @@ -38,7 +38,18 @@ public: // Render the raster using current provider and renderer. Returns an empty QImage on failure. QImage render(const RenderParams& params); + // Current render params stored per layer + RenderParams currentRenderParams() const; + void setCurrentRenderParams(const RenderParams& params); + + // Get wavelength range from data provider (min, max). Returns false if unavailable. + bool wavelengthRange(double& minWave, double& maxWave) const; + + // Get all band wavelengths + std::vector bandWavelengths() const; + private: std::unique_ptr m_provider; std::unique_ptr m_renderer; + RenderParams m_currentParams; }; diff --git a/HPPA/imageControl.cpp b/HPPA/imageControl.cpp index 4afc784..5bc5803 100644 --- a/HPPA/imageControl.cpp +++ b/HPPA/imageControl.cpp @@ -1,24 +1,42 @@ #include "imageControl.h" #include "RasterLayer.h" +#include +#include ImageControl::ImageControl(QWidget* parent) : QDialog(parent) { ui.setupUi(this); - // Connect spinboxes - connect(ui.spinRed, QOverload::of(&QDoubleSpinBox::valueChanged), this, &ImageControl::onSpinRedChanged); - connect(ui.spinGreen, QOverload::of(&QDoubleSpinBox::valueChanged), this, &ImageControl::onSpinGreenChanged); - connect(ui.spinBlue, QOverload::of(&QDoubleSpinBox::valueChanged), this, &ImageControl::onSpinBlueChanged); + // Spinbox valueChanged: only sync the paired slider (no render) + connect(ui.spinRed, QOverload::of(&QDoubleSpinBox::valueChanged), this, &ImageControl::onSpinRedValueChanged); + connect(ui.spinGreen, QOverload::of(&QDoubleSpinBox::valueChanged), this, &ImageControl::onSpinGreenValueChanged); + connect(ui.spinBlue, QOverload::of(&QDoubleSpinBox::valueChanged), this, &ImageControl::onSpinBlueValueChanged); - // Connect sliders - connect(ui.sliderRed, &QSlider::valueChanged, this, &ImageControl::onSliderRedChanged); - connect(ui.sliderGreen, &QSlider::valueChanged, this, &ImageControl::onSliderGreenChanged); - connect(ui.sliderBlue, &QSlider::valueChanged, this, &ImageControl::onSliderBlueChanged); + // Spinbox editingFinished: commit on Enter key / focus lost (trigger render) + connect(ui.spinRed, &QDoubleSpinBox::editingFinished, this, &ImageControl::onSpinRedEditingFinished); + connect(ui.spinGreen, &QDoubleSpinBox::editingFinished, this, &ImageControl::onSpinGreenEditingFinished); + connect(ui.spinBlue, &QDoubleSpinBox::editingFinished, this, &ImageControl::onSpinBlueEditingFinished); + + // Slider valueChanged: only sync the paired spinbox (no render) + // Slider now represents band index (0 .. N-1) + connect(ui.sliderRed, &QSlider::valueChanged, this, &ImageControl::onSliderRedValueChanged); + connect(ui.sliderGreen, &QSlider::valueChanged, this, &ImageControl::onSliderGreenValueChanged); + connect(ui.sliderBlue, &QSlider::valueChanged, this, &ImageControl::onSliderBlueValueChanged); + + // Slider sliderReleased: commit on mouse release (trigger render) + connect(ui.sliderRed, &QSlider::sliderReleased, this, &ImageControl::onSliderRedReleased); + connect(ui.sliderGreen, &QSlider::sliderReleased, this, &ImageControl::onSliderGreenReleased); + connect(ui.sliderBlue, &QSlider::sliderReleased, this, &ImageControl::onSliderBlueReleased); // Connect preset buttons connect(ui.btnTrueColor, &QPushButton::clicked, this, &ImageControl::onTrueColorClicked); connect(ui.btnColorInfrared, &QPushButton::clicked, this, &ImageControl::onColorInfraredClicked); + + // Spinbox only commits on Enter, not on every keystroke + ui.spinRed->setKeyboardTracking(false); + ui.spinGreen->setKeyboardTracking(false); + ui.spinBlue->setKeyboardTracking(false); } ImageControl::~ImageControl() @@ -31,46 +49,71 @@ void ImageControl::setActiveLayer(RasterLayer* layer) if (!layer) { setEnabled(false); + m_wavelengths.clear(); return; } setEnabled(true); - // Get wavelength range from the layer - double minW = 374.5, maxW = 948.1; - if (layer->wavelengthRange(minW, maxW)) { - m_minWave = minW; - m_maxWave = maxW; + // Get band wavelengths from the layer's header + m_wavelengths = layer->bandWavelengths(); + std::sort(m_wavelengths.begin(), m_wavelengths.end()); + + if (m_wavelengths.empty()) { + setEnabled(false); + return; + } + + m_minWave = m_wavelengths.front(); + m_maxWave = m_wavelengths.back(); + + // Compute spinbox step as the average wavelength interval between adjacent bands + double step = 1.0; + if (m_wavelengths.size() >= 2) { + step = (m_maxWave - m_minWave) / (m_wavelengths.size() - 1); } blockAllSignals(true); - // Configure spinbox ranges + // Configure spinbox ranges and step ui.spinRed->setMinimum(m_minWave); ui.spinRed->setMaximum(m_maxWave); + ui.spinRed->setSingleStep(step); ui.spinGreen->setMinimum(m_minWave); ui.spinGreen->setMaximum(m_maxWave); + ui.spinGreen->setSingleStep(step); ui.spinBlue->setMinimum(m_minWave); ui.spinBlue->setMaximum(m_maxWave); + ui.spinBlue->setSingleStep(step); - // Configure slider ranges (integer, multiply by 10 for 0.1 nm resolution) - int sliderMin = static_cast(m_minWave * 10.0); - int sliderMax = static_cast(m_maxWave * 10.0); - ui.sliderRed->setMinimum(sliderMin); - ui.sliderRed->setMaximum(sliderMax); - ui.sliderGreen->setMinimum(sliderMin); - ui.sliderGreen->setMaximum(sliderMax); - ui.sliderBlue->setMinimum(sliderMin); - ui.sliderBlue->setMaximum(sliderMax); + // Slider now represents band index (0 .. N-1), step = 1 + int maxIdx = static_cast(m_wavelengths.size()) - 1; + ui.sliderRed->setMinimum(0); + ui.sliderRed->setMaximum(maxIdx); + ui.sliderRed->setSingleStep(1); + ui.sliderRed->setPageStep(1); + ui.sliderGreen->setMinimum(0); + ui.sliderGreen->setMaximum(maxIdx); + ui.sliderGreen->setSingleStep(1); + ui.sliderGreen->setPageStep(1); + ui.sliderBlue->setMinimum(0); + ui.sliderBlue->setMaximum(maxIdx); + ui.sliderBlue->setSingleStep(1); + ui.sliderBlue->setPageStep(1); // Set current values from layer's render params auto params = layer->currentRenderParams(); - ui.spinRed->setValue(params.rWave); - ui.spinGreen->setValue(params.gWave); - ui.spinBlue->setValue(params.bWave); - ui.sliderRed->setValue(static_cast(params.rWave * 10.0)); - ui.sliderGreen->setValue(static_cast(params.gWave * 10.0)); - ui.sliderBlue->setValue(static_cast(params.bWave * 10.0)); + int rIdx = nearestBandIndex(params.rWave); + int gIdx = nearestBandIndex(params.gWave); + int bIdx = nearestBandIndex(params.bWave); + + ui.spinRed->setValue(m_wavelengths[rIdx]); + ui.spinGreen->setValue(m_wavelengths[gIdx]); + ui.spinBlue->setValue(m_wavelengths[bIdx]); + + ui.sliderRed->setValue(rIdx); + ui.sliderGreen->setValue(gIdx); + ui.sliderBlue->setValue(bIdx); blockAllSignals(false); } @@ -80,66 +123,136 @@ RasterLayer* ImageControl::activeLayer() const return m_activeLayer; } -void ImageControl::onSpinRedChanged(double val) +int ImageControl::nearestBandIndex(double wave) const { + if (m_wavelengths.empty()) return 0; + int best = 0; + double bestDiff = std::abs(m_wavelengths[0] - wave); + for (int i = 1; i < static_cast(m_wavelengths.size()); ++i) { + double d = std::abs(m_wavelengths[i] - wave); + if (d < bestDiff) { + bestDiff = d; + best = i; + } + } + return best; +} + +void ImageControl::setControlsToBandIndex(QDoubleSpinBox* spin, QSlider* slider, int idx) +{ + if (idx < 0 || idx >= static_cast(m_wavelengths.size())) return; + double wv = m_wavelengths[idx]; + spin->blockSignals(true); + spin->setValue(wv); + spin->blockSignals(false); + slider->blockSignals(true); + slider->setValue(idx); + slider->blockSignals(false); +} + +// --- Spinbox valueChanged: snap to nearest band, sync slider, no render --- + +void ImageControl::onSpinRedValueChanged(double val) +{ + int idx = nearestBandIndex(val); ui.sliderRed->blockSignals(true); - ui.sliderRed->setValue(static_cast(val * 10.0)); + ui.sliderRed->setValue(idx); ui.sliderRed->blockSignals(false); - emitBandChange(); } -void ImageControl::onSpinGreenChanged(double val) +void ImageControl::onSpinGreenValueChanged(double val) { + int idx = nearestBandIndex(val); ui.sliderGreen->blockSignals(true); - ui.sliderGreen->setValue(static_cast(val * 10.0)); + ui.sliderGreen->setValue(idx); ui.sliderGreen->blockSignals(false); - emitBandChange(); } -void ImageControl::onSpinBlueChanged(double val) +void ImageControl::onSpinBlueValueChanged(double val) { + int idx = nearestBandIndex(val); ui.sliderBlue->blockSignals(true); - ui.sliderBlue->setValue(static_cast(val * 10.0)); + ui.sliderBlue->setValue(idx); ui.sliderBlue->blockSignals(false); - emitBandChange(); } -void ImageControl::onSliderRedChanged(int val) +// --- Slider valueChanged: map band index to wavelength, sync spinbox, no render --- + +void ImageControl::onSliderRedValueChanged(int val) { - double wv = val / 10.0; + if (val < 0 || val >= static_cast(m_wavelengths.size())) return; ui.spinRed->blockSignals(true); - ui.spinRed->setValue(wv); + ui.spinRed->setValue(m_wavelengths[val]); ui.spinRed->blockSignals(false); - emitBandChange(); } -void ImageControl::onSliderGreenChanged(int val) +void ImageControl::onSliderGreenValueChanged(int val) { - double wv = val / 10.0; + if (val < 0 || val >= static_cast(m_wavelengths.size())) return; ui.spinGreen->blockSignals(true); - ui.spinGreen->setValue(wv); + ui.spinGreen->setValue(m_wavelengths[val]); ui.spinGreen->blockSignals(false); +} + +void ImageControl::onSliderBlueValueChanged(int val) +{ + if (val < 0 || val >= static_cast(m_wavelengths.size())) return; + ui.spinBlue->blockSignals(true); + ui.spinBlue->setValue(m_wavelengths[val]); + ui.spinBlue->blockSignals(false); +} + +// --- Spinbox editingFinished: snap to nearest band wavelength, then commit --- + +void ImageControl::onSpinRedEditingFinished() +{ + int idx = nearestBandIndex(ui.spinRed->value()); + setControlsToBandIndex(ui.spinRed, ui.sliderRed, idx); emitBandChange(); } -void ImageControl::onSliderBlueChanged(int val) +void ImageControl::onSpinGreenEditingFinished() { - double wv = val / 10.0; - ui.spinBlue->blockSignals(true); - ui.spinBlue->setValue(wv); - ui.spinBlue->blockSignals(false); + int idx = nearestBandIndex(ui.spinGreen->value()); + setControlsToBandIndex(ui.spinGreen, ui.sliderGreen, idx); emitBandChange(); } +void ImageControl::onSpinBlueEditingFinished() +{ + int idx = nearestBandIndex(ui.spinBlue->value()); + setControlsToBandIndex(ui.spinBlue, ui.sliderBlue, idx); + emitBandChange(); +} + +// --- Slider sliderReleased: commit on mouse release --- + +void ImageControl::onSliderRedReleased() +{ + emitBandChange(); +} + +void ImageControl::onSliderGreenReleased() +{ + emitBandChange(); +} + +void ImageControl::onSliderBlueReleased() +{ + emitBandChange(); +} + +// --- Preset buttons --- + void ImageControl::onTrueColorClicked() { blockAllSignals(true); - ui.spinRed->setValue(665.0); - ui.spinGreen->setValue(560.0); - ui.spinBlue->setValue(490.0); - ui.sliderRed->setValue(static_cast(665.0 * 10.0)); - ui.sliderGreen->setValue(static_cast(560.0 * 10.0)); - ui.sliderBlue->setValue(static_cast(490.0 * 10.0)); + int rIdx = nearestBandIndex(665.0); + int gIdx = nearestBandIndex(560.0); + int bIdx = nearestBandIndex(490.0); + setControlsToBandIndex(ui.spinRed, ui.sliderRed, rIdx); + setControlsToBandIndex(ui.spinGreen, ui.sliderGreen, gIdx); + setControlsToBandIndex(ui.spinBlue, ui.sliderBlue, bIdx); blockAllSignals(false); emitBandChange(); } @@ -147,12 +260,12 @@ void ImageControl::onTrueColorClicked() void ImageControl::onColorInfraredClicked() { blockAllSignals(true); - ui.spinRed->setValue(800.0); - ui.spinGreen->setValue(665.0); - ui.spinBlue->setValue(560.0); - ui.sliderRed->setValue(static_cast(800.0 * 10.0)); - ui.sliderGreen->setValue(static_cast(665.0 * 10.0)); - ui.sliderBlue->setValue(static_cast(560.0 * 10.0)); + int rIdx = nearestBandIndex(800.0); + int gIdx = nearestBandIndex(665.0); + int bIdx = nearestBandIndex(560.0); + setControlsToBandIndex(ui.spinRed, ui.sliderRed, rIdx); + setControlsToBandIndex(ui.spinGreen, ui.sliderGreen, gIdx); + setControlsToBandIndex(ui.spinBlue, ui.sliderBlue, bIdx); blockAllSignals(false); emitBandChange(); } @@ -183,4 +296,4 @@ void ImageControl::blockAllSignals(bool block) ui.sliderRed->blockSignals(block); ui.sliderGreen->blockSignals(block); ui.sliderBlue->blockSignals(block); -} \ No newline at end of file +} diff --git a/HPPA/imageControl.h b/HPPA/imageControl.h index b7d60ba..8b89720 100644 --- a/HPPA/imageControl.h +++ b/HPPA/imageControl.h @@ -4,6 +4,7 @@ #include #include #include +#include #include "ui_imgControl.h" @@ -28,12 +29,26 @@ Q_SIGNALS: void bandSelectionChanged(double rWave, double gWave, double bWave); private Q_SLOTS: - void onSpinRedChanged(double val); - void onSpinGreenChanged(double val); - void onSpinBlueChanged(double val); - void onSliderRedChanged(int val); - void onSliderGreenChanged(int val); - void onSliderBlueChanged(int val); + // Sync slider position while dragging spinbox (no render) + void onSpinRedValueChanged(double val); + void onSpinGreenValueChanged(double val); + void onSpinBlueValueChanged(double val); + + // Sync spinbox display while dragging slider (no render) + void onSliderRedValueChanged(int val); + void onSliderGreenValueChanged(int val); + void onSliderBlueValueChanged(int val); + + // Commit: spinbox Enter key pressed / focus lost + void onSpinRedEditingFinished(); + void onSpinGreenEditingFinished(); + void onSpinBlueEditingFinished(); + + // Commit: slider mouse released + void onSliderRedReleased(); + void onSliderGreenReleased(); + void onSliderBlueReleased(); + void onTrueColorClicked(); void onColorInfraredClicked(); @@ -41,8 +56,14 @@ private: void emitBandChange(); void blockAllSignals(bool block); + // Find the band index whose wavelength is closest to the given value + int nearestBandIndex(double wave) const; + // Set spinbox and slider to wavelength of the given band index + void setControlsToBandIndex(QDoubleSpinBox* spin, QSlider* slider, int idx); + Ui::ImageControl ui; RasterLayer* m_activeLayer = nullptr; double m_minWave = 374.5; double m_maxWave = 948.1; + std::vector m_wavelengths; // band wavelengths from header }; diff --git a/HPPA/imgControl.ui b/HPPA/imgControl.ui index 6530c09..10e2da9 100644 --- a/HPPA/imgControl.ui +++ b/HPPA/imgControl.ui @@ -13,17 +13,72 @@ Color Adjust + + QLabel { + color: rgb(255, 255, 255); +} + +QSlider::groove:horizontal { + height: 10px; + background: #1e2a44; + border-radius: 3px; +} + +/* 已滑过:渐变蓝 */ +QSlider::sub-page:horizontal { + background: qlineargradient( + x1:0, y1:0, x2:1, y2:0, + stop:0 #1f4fff, + stop:0.5 #2f6bff, + stop:1 #5fa0ff + ); + border-radius: 3px; +} + +/* 未滑过 */ +QSlider::add-page:horizontal { + height: 10px; + background: #2a3550; + border-radius: 3px; +} + +/* ===== 滑块按钮 ===== */ +QSlider::handle:horizontal { + width: 15px; + height: 10px; + + /* 蓝色实心 */ + background: #2f6bff; + + /* 白色外圈 */ + border: 2px solid #ffffff; + border-radius: 5px; + + /* 垂直居中 */ + margin: -5px 0; +} + +/* 悬停 */ +QSlider::handle:horizontal:hover { + background: #4d8dff; +} + +/* 按下 */ +QSlider::handle:horizontal:pressed { + background: #1f4fff; +} + - Adjustments + 调整 - Red + @@ -57,7 +112,7 @@ - Green + 绿 @@ -91,7 +146,7 @@ - Blue + @@ -128,20 +183,20 @@ - Presets + 预设 - True Color + 真彩色 - Color Infrared + 假彩色