feat(ui): 日期范围筛选控件(双日历面板/可清空/默认今天)替代单 QDateEdit(界面修复 1/2/3)
This commit is contained in:
parent
2e4e4b24e4
commit
c2f2b1f94c
|
|
@ -83,6 +83,7 @@ add_executable(geopro_desktop WIN32
|
|||
panels/columns/Column3DAnalysis.cpp
|
||||
panels/columns/CategorySection.cpp
|
||||
panels/columns/CategoryAnalysisTab.cpp
|
||||
panels/columns/DateRangeEdit.cpp
|
||||
panels/columns/ColumnDrawer.cpp
|
||||
panels/AnomalyTablePanel.cpp
|
||||
panels/LoadingOverlay.cpp
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include <QComboBox>
|
||||
#include <QDate>
|
||||
#include <QDateEdit>
|
||||
#include "panels/columns/DateRangeEdit.hpp"
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
|
|
@ -68,21 +68,10 @@ CategorySection::CategorySection(const CategorySpec& spec, geopro::data::Dataset
|
|||
[this](int) { rebuildList(); });
|
||||
filterRow->addWidget(arrayCombo_);
|
||||
}
|
||||
auto makeDate = [this]() {
|
||||
auto* d = new QDateEdit(body_);
|
||||
d->setCalendarPopup(true);
|
||||
d->setDisplayFormat(QStringLiteral("yyyy-MM-dd"));
|
||||
d->setSpecialValueText(QStringLiteral("不限")); // 最小日期→显示"不限"
|
||||
d->setDate(d->minimumDate());
|
||||
connect(d, &QDateEdit::dateChanged, this, [this](const QDate&) { rebuildList(); });
|
||||
return d;
|
||||
};
|
||||
fromDate_ = makeDate();
|
||||
toDate_ = makeDate();
|
||||
filterRow->addWidget(new QLabel(QStringLiteral("采集"), body_));
|
||||
filterRow->addWidget(fromDate_, 1);
|
||||
filterRow->addWidget(new QLabel(QStringLiteral("至"), body_));
|
||||
filterRow->addWidget(toDate_, 1);
|
||||
dateRange_ = new DateRangeEdit(body_);
|
||||
connect(dateRange_, &DateRangeEdit::rangeChanged, this, [this] { rebuildList(); });
|
||||
filterRow->addWidget(dateRange_, 1);
|
||||
body->addLayout(filterRow);
|
||||
|
||||
// 段体:可勾选数据树(勾选=渲染)。复用数据列表卡片委托与 populateDatasetList。
|
||||
|
|
@ -152,17 +141,17 @@ bool CategorySection::passesFilters(const DsRow& row) const {
|
|||
if (!hit) return false;
|
||||
}
|
||||
}
|
||||
// 采集时间段(collectTime 经 dict 取;缺则回退 createTime;最小日期="不限"不约束)。
|
||||
const bool hasFrom = fromDate_ && fromDate_->date() > fromDate_->minimumDate();
|
||||
const bool hasTo = toDate_ && toDate_->date() > toDate_->minimumDate();
|
||||
if (hasFrom || hasTo) {
|
||||
// 采集时间范围(collectTime 经 dict 取;缺则回退 createTime;空范围不约束)。
|
||||
const QDate from = dateRange_ ? dateRange_->from() : QDate();
|
||||
const QDate to = dateRange_ ? dateRange_->to() : QDate();
|
||||
if (from.isValid() || to.isValid()) {
|
||||
const DsTypeFields* f = dict_ ? dict_->fields(spec_.dsTypeCode) : nullptr;
|
||||
std::string ts = f ? collectTimeOf(row, *f) : std::string();
|
||||
if (ts.empty()) ts = row.createTime;
|
||||
const QDate d = QDate::fromString(QString::fromStdString(ts).left(10), QStringLiteral("yyyy-MM-dd"));
|
||||
if (d.isValid()) {
|
||||
if (hasFrom && d < fromDate_->date()) return false;
|
||||
if (hasTo && d > toDate_->date()) return false;
|
||||
if (from.isValid() && d < from) return false;
|
||||
if (to.isValid() && d > to) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ class DatasetFieldDictionary;
|
|||
|
||||
namespace geopro::app {
|
||||
|
||||
class DateRangeEdit;
|
||||
|
||||
// 单个数据类型大类段(spec §7):段头(标题/折叠 + 装置类型/日期筛选 + 「+新增三维体」)+ 段体(可勾选数据树)。
|
||||
// 勾选数据行 = 渲染(帘面/体素/切片);段头生成按钮据当前勾选源发 generateVolumeRequested。
|
||||
class CategorySection : public QWidget {
|
||||
|
|
@ -51,8 +53,7 @@ private:
|
|||
QToolButton* header_ = nullptr; // 折叠头(标题 + 箭头)
|
||||
QWidget* body_ = nullptr; // 段体容器(折叠时隐藏)
|
||||
QComboBox* arrayCombo_ = nullptr; // 装置类型筛选(仅 hasArrayTypeFilter)
|
||||
QDateEdit* fromDate_ = nullptr; // 采集时间段·起
|
||||
QDateEdit* toDate_ = nullptr; // 采集时间段·止
|
||||
DateRangeEdit* dateRange_ = nullptr; // 采集时间范围筛选(起止双日历,可清空)
|
||||
QTreeWidget* list_ = nullptr;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,97 @@
|
|||
#include "panels/columns/DateRangeEdit.hpp"
|
||||
|
||||
#include <QCalendarWidget>
|
||||
#include <QFrame>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QToolButton>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "Theme.hpp"
|
||||
|
||||
namespace geopro::app {
|
||||
|
||||
DateRangeEdit::DateRangeEdit(QWidget* parent) : QWidget(parent) {
|
||||
auto* lay = new QHBoxLayout(this);
|
||||
lay->setContentsMargins(0, 0, 0, 0);
|
||||
lay->setSpacing(0);
|
||||
btn_ = new QToolButton(this);
|
||||
btn_->setToolButtonStyle(Qt::ToolButtonTextOnly);
|
||||
btn_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
btn_->setPopupMode(QToolButton::InstantPopup);
|
||||
btn_->setToolTip(QStringLiteral("按采集时间筛选(起 ~ 止),可清空"));
|
||||
connect(btn_, &QToolButton::clicked, this, &DateRangeEdit::openPopup);
|
||||
lay->addWidget(btn_);
|
||||
updateText();
|
||||
}
|
||||
|
||||
void DateRangeEdit::openPopup() {
|
||||
if (!popup_) {
|
||||
popup_ = new QFrame(this, Qt::Popup);
|
||||
popup_->setFrameShape(QFrame::StyledPanel);
|
||||
applyTokenizedStyleSheet(
|
||||
popup_, QStringLiteral("QFrame{background:{{bg/panel}};border:1px solid {{border/default}};"
|
||||
"border-radius:8px;}"));
|
||||
auto* v = new QVBoxLayout(popup_);
|
||||
v->setContentsMargins(space::kSm, space::kSm, space::kSm, space::kSm);
|
||||
|
||||
auto* cals = new QHBoxLayout();
|
||||
auto* fromCol = new QVBoxLayout();
|
||||
fromCol->addWidget(new QLabel(QStringLiteral("起始"), popup_));
|
||||
fromCal_ = new QCalendarWidget(popup_);
|
||||
fromCol->addWidget(fromCal_);
|
||||
cals->addLayout(fromCol);
|
||||
auto* toCol = new QVBoxLayout();
|
||||
toCol->addWidget(new QLabel(QStringLiteral("结束"), popup_));
|
||||
toCal_ = new QCalendarWidget(popup_);
|
||||
toCol->addWidget(toCal_);
|
||||
cals->addLayout(toCol);
|
||||
v->addLayout(cals);
|
||||
|
||||
auto* btns = new QHBoxLayout();
|
||||
auto* clr = new QPushButton(QStringLiteral("清空"), popup_);
|
||||
auto* ok = new QPushButton(QStringLiteral("确定"), popup_);
|
||||
connect(clr, &QPushButton::clicked, this, &DateRangeEdit::clearAndClose);
|
||||
connect(ok, &QPushButton::clicked, this, &DateRangeEdit::applyAndClose);
|
||||
btns->addWidget(clr);
|
||||
btns->addStretch(1);
|
||||
btns->addWidget(ok);
|
||||
v->addLayout(btns);
|
||||
}
|
||||
// 已有范围则定位到当前值,否则日历默认今天(不再 1752)。
|
||||
if (from_.isValid()) fromCal_->setSelectedDate(from_);
|
||||
if (to_.isValid()) toCal_->setSelectedDate(to_);
|
||||
popup_->adjustSize();
|
||||
popup_->move(mapToGlobal(QPoint(0, height())));
|
||||
popup_->show();
|
||||
}
|
||||
|
||||
void DateRangeEdit::applyAndClose() {
|
||||
from_ = fromCal_->selectedDate();
|
||||
to_ = toCal_->selectedDate();
|
||||
if (from_.isValid() && to_.isValid() && from_ > to_) std::swap(from_, to_); // 起>止则交换
|
||||
if (popup_) popup_->hide();
|
||||
updateText();
|
||||
emit rangeChanged();
|
||||
}
|
||||
|
||||
void DateRangeEdit::clearAndClose() {
|
||||
from_ = QDate();
|
||||
to_ = QDate();
|
||||
if (popup_) popup_->hide();
|
||||
updateText();
|
||||
emit rangeChanged();
|
||||
}
|
||||
|
||||
void DateRangeEdit::updateText() {
|
||||
if (!from_.isValid() && !to_.isValid()) {
|
||||
btn_->setText(QStringLiteral("全部时间 ▾"));
|
||||
return;
|
||||
}
|
||||
const QString f = from_.isValid() ? from_.toString(QStringLiteral("yyyy-MM-dd")) : QStringLiteral("不限");
|
||||
const QString t = to_.isValid() ? to_.toString(QStringLiteral("yyyy-MM-dd")) : QStringLiteral("不限");
|
||||
btn_->setText(QStringLiteral("%1 ~ %2 ▾").arg(f, t));
|
||||
}
|
||||
|
||||
} // namespace geopro::app
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
#pragma once
|
||||
#include <QDate>
|
||||
#include <QWidget>
|
||||
|
||||
class QToolButton;
|
||||
class QCalendarWidget;
|
||||
class QFrame;
|
||||
|
||||
namespace geopro::app {
|
||||
|
||||
// 日期范围选择器(spec 采集时间筛选):一个按钮显示「起 ~ 止」,点开弹双日历面板选起止;
|
||||
// 可清空(回到"全部时间");默认不限,日历定位今天(不再停在 1752)。
|
||||
class DateRangeEdit : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DateRangeEdit(QWidget* parent = nullptr);
|
||||
|
||||
QDate from() const { return from_; } // 无效 QDate = 不限下限
|
||||
QDate to() const { return to_; } // 无效 QDate = 不限上限
|
||||
|
||||
signals:
|
||||
void rangeChanged();
|
||||
|
||||
private:
|
||||
void openPopup();
|
||||
void applyAndClose();
|
||||
void clearAndClose();
|
||||
void updateText();
|
||||
|
||||
QToolButton* btn_ = nullptr;
|
||||
QFrame* popup_ = nullptr;
|
||||
QCalendarWidget* fromCal_ = nullptr;
|
||||
QCalendarWidget* toCal_ = nullptr;
|
||||
QDate from_;
|
||||
QDate to_;
|
||||
};
|
||||
|
||||
} // namespace geopro::app
|
||||
Loading…
Reference in New Issue