|
|
|
@ -5,6 +5,8 @@
|
|
|
|
#include <QtGui/QMouseEvent>
|
|
|
|
#include <QtGui/QMouseEvent>
|
|
|
|
#include <QtGui/QFont>
|
|
|
|
#include <QtGui/QFont>
|
|
|
|
#include <QScrollBar>
|
|
|
|
#include <QScrollBar>
|
|
|
|
|
|
|
|
#include <QScrollArea>
|
|
|
|
|
|
|
|
#include <QStyle>
|
|
|
|
#include <QTextDocument>
|
|
|
|
#include <QTextDocument>
|
|
|
|
#include <QList>
|
|
|
|
#include <QList>
|
|
|
|
#include <QPainter>
|
|
|
|
#include <QPainter>
|
|
|
|
@ -408,11 +410,12 @@ nmWxAutomaticfittingStart::nmWxAutomaticfittingStart(QWidget *parent)
|
|
|
|
|
|
|
|
|
|
|
|
QSize nmWxAutomaticfittingStart::sizeHint() const
|
|
|
|
QSize nmWxAutomaticfittingStart::sizeHint() const
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// 加宽进程窗口,为曲线和完整日志行留出空间,同时保留屏幕边缘。
|
|
|
|
// 默认窗口适当收紧,大屏限制推荐尺寸;仍由布局自适应并允许手动缩放。
|
|
|
|
QDesktopWidget* desktop = QApplication::desktop();
|
|
|
|
QDesktopWidget* desktop = QApplication::desktop();
|
|
|
|
if(desktop == nullptr) return iDlgBase::sizeHint();
|
|
|
|
if(desktop == nullptr) return iDlgBase::sizeHint();
|
|
|
|
const QRect available = desktop->availableGeometry(parentWidget() ? parentWidget()->window() : this);
|
|
|
|
const QRect available = desktop->availableGeometry(parentWidget() ? parentWidget()->window() : this);
|
|
|
|
return QSize(available.width() * 75 / 100, available.height() * 65 / 100);
|
|
|
|
return QSize(qMin(1440, available.width() * 65 / 100),
|
|
|
|
|
|
|
|
qMin(820, available.height() * 50 / 100));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nmWxAutomaticfittingStart::~nmWxAutomaticfittingStart()
|
|
|
|
nmWxAutomaticfittingStart::~nmWxAutomaticfittingStart()
|
|
|
|
@ -431,6 +434,7 @@ void nmWxAutomaticfittingStart::setupUI()
|
|
|
|
"#autoFittingProgress QGroupBox#fittingSummary { padding-top: 0; }"
|
|
|
|
"#autoFittingProgress QGroupBox#fittingSummary { padding-top: 0; }"
|
|
|
|
"#autoFittingProgress QGroupBox#fittingSummary QLabel { font-size: 14px; color: #46556b; }"
|
|
|
|
"#autoFittingProgress QGroupBox#fittingSummary QLabel { font-size: 14px; color: #46556b; }"
|
|
|
|
"#autoFittingProgress QWidget#parameterStrip { background: #ffffff; border-top: 1px solid #e3e8ef; }"
|
|
|
|
"#autoFittingProgress QWidget#parameterStrip { background: #ffffff; border-top: 1px solid #e3e8ef; }"
|
|
|
|
|
|
|
|
"#autoFittingProgress QWidget#parameterContent { background: #ffffff; }"
|
|
|
|
"#autoFittingProgress QWidget#parameterSeparator { background: #e3e8ef; }"
|
|
|
|
"#autoFittingProgress QWidget#parameterSeparator { background: #e3e8ef; }"
|
|
|
|
"#autoFittingProgress QLabel#parameterName { font-size: 12px; }"
|
|
|
|
"#autoFittingProgress QLabel#parameterName { font-size: 12px; }"
|
|
|
|
"#autoFittingProgress QLabel#parameterValue { color: #233247; font-size: 18px; font-weight: 500; }"
|
|
|
|
"#autoFittingProgress QLabel#parameterValue { color: #233247; font-size: 18px; font-weight: 500; }"
|
|
|
|
@ -545,16 +549,68 @@ void nmWxAutomaticfittingStart::setupParameterArea()
|
|
|
|
|
|
|
|
|
|
|
|
void nmWxAutomaticfittingStart::setupParameterStrip()
|
|
|
|
void nmWxAutomaticfittingStart::setupParameterStrip()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// 参数独占曲线和日志下方的整行,横向均分空间,不保留尾部空白。
|
|
|
|
// 标题固定,参数网格放入滚动区,避免参数数量撑大整个窗口。
|
|
|
|
parameterStrip = new QWidget(this);
|
|
|
|
parameterStrip = new QWidget(this);
|
|
|
|
parameterStrip->setObjectName("parameterStrip");
|
|
|
|
parameterStrip->setObjectName("parameterStrip");
|
|
|
|
parameterStrip->setAttribute(Qt::WA_StyledBackground, true);
|
|
|
|
parameterStrip->setAttribute(Qt::WA_StyledBackground, true);
|
|
|
|
parameterStrip->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
|
|
|
parameterStrip->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
|
|
|
// 标题与参数共用网格,竖线跨越两行,上下留白均为 4 像素。
|
|
|
|
QVBoxLayout* stripLayout = new QVBoxLayout(parameterStrip);
|
|
|
|
parameterLayout = new QGridLayout(parameterStrip);
|
|
|
|
stripLayout->setContentsMargins(22, 4, 22, 4);
|
|
|
|
parameterLayout->setContentsMargins(22, 4, 22, 4);
|
|
|
|
stripLayout->setSpacing(2);
|
|
|
|
|
|
|
|
QLabel* heading = new QLabel(tr("Current parameters"), parameterStrip);
|
|
|
|
|
|
|
|
heading->setObjectName("sectionHeading");
|
|
|
|
|
|
|
|
stripLayout->addWidget(heading);
|
|
|
|
|
|
|
|
parameterScrollArea = new QScrollArea(parameterStrip);
|
|
|
|
|
|
|
|
parameterScrollArea->setFrameShape(QFrame::NoFrame);
|
|
|
|
|
|
|
|
parameterScrollArea->setWidgetResizable(true);
|
|
|
|
|
|
|
|
parameterScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
|
|
|
|
|
|
|
parameterScrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
|
|
|
|
|
|
|
parameterContent = new QWidget;
|
|
|
|
|
|
|
|
parameterContent->setObjectName("parameterContent");
|
|
|
|
|
|
|
|
parameterContent->setAttribute(Qt::WA_StyledBackground, true);
|
|
|
|
|
|
|
|
parameterLayout = new QGridLayout(parameterContent);
|
|
|
|
|
|
|
|
parameterLayout->setContentsMargins(0, 0, 0, 0);
|
|
|
|
parameterLayout->setHorizontalSpacing(0);
|
|
|
|
parameterLayout->setHorizontalSpacing(0);
|
|
|
|
parameterLayout->setVerticalSpacing(2);
|
|
|
|
parameterLayout->setVerticalSpacing(8);
|
|
|
|
|
|
|
|
parameterLayout->setAlignment(Qt::AlignTop);
|
|
|
|
|
|
|
|
parameterScrollArea->setWidget(parameterContent);
|
|
|
|
|
|
|
|
stripLayout->addWidget(parameterScrollArea);
|
|
|
|
|
|
|
|
parameterScrollArea->viewport()->installEventFilter(this);
|
|
|
|
|
|
|
|
parameterStrip->hide();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool nmWxAutomaticfittingStart::eventFilter(QObject* watched, QEvent* event)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// 按滚动区的实际宽度重新计算换行高度,窗口缩放后仍只显示两行。
|
|
|
|
|
|
|
|
if(watched == parameterScrollArea->viewport() && event->type() == QEvent::Resize) {
|
|
|
|
|
|
|
|
updateParameterAreaHeight();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return iDlgBase::eventFilter(watched, event);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void nmWxAutomaticfittingStart::updateParameterAreaHeight()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if(parameterValues.isEmpty()) return;
|
|
|
|
|
|
|
|
const int columns = qMin(6, parameterValues.size());
|
|
|
|
|
|
|
|
const int rows = (parameterValues.size() + 5) / 6;
|
|
|
|
|
|
|
|
const int scrollWidth = rows > 2
|
|
|
|
|
|
|
|
? parameterScrollArea->style()->pixelMetric(QStyle::PM_ScrollBarExtent) : 0;
|
|
|
|
|
|
|
|
const int cellWidth = qMax(1,
|
|
|
|
|
|
|
|
(parameterScrollArea->width() - scrollWidth - (columns - 1)) / columns);
|
|
|
|
|
|
|
|
int rowHeight = 0;
|
|
|
|
|
|
|
|
foreach(QLabel* value, parameterValues) {
|
|
|
|
|
|
|
|
QLayout* layout = value->parentWidget()->layout();
|
|
|
|
|
|
|
|
rowHeight = qMax(rowHeight, qMax(layout->totalMinimumSize().height(),
|
|
|
|
|
|
|
|
layout->totalHeightForWidth(cellWidth)));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// 所有行使用相同高度,使第十三个参数开始完整地位于可滚动区域。
|
|
|
|
|
|
|
|
foreach(QLabel* value, parameterValues) value->parentWidget()->setFixedHeight(rowHeight);
|
|
|
|
|
|
|
|
for(int row = 0; row < rows; ++row) parameterLayout->setRowMinimumHeight(row, rowHeight);
|
|
|
|
|
|
|
|
const int spacing = parameterLayout->verticalSpacing();
|
|
|
|
|
|
|
|
parameterContent->setMinimumHeight(rows * rowHeight + (rows - 1) * spacing);
|
|
|
|
|
|
|
|
const int visibleRows = qMin(2, rows);
|
|
|
|
|
|
|
|
parameterScrollArea->setFixedHeight(visibleRows * rowHeight + (visibleRows - 1) * spacing);
|
|
|
|
|
|
|
|
parameterScrollArea->verticalScrollBar()->setSingleStep(rowHeight + spacing);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmWxAutomaticfittingStart::setupChartArea()
|
|
|
|
void nmWxAutomaticfittingStart::setupChartArea()
|
|
|
|
@ -786,12 +842,15 @@ void nmWxAutomaticfittingStart::setSelectedParameters(const QStringList& paramet
|
|
|
|
for(int column = 0; column < parameterLayout->columnCount(); ++column) {
|
|
|
|
for(int column = 0; column < parameterLayout->columnCount(); ++column) {
|
|
|
|
parameterLayout->setColumnStretch(column, 0);
|
|
|
|
parameterLayout->setColumnStretch(column, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
QLabel* heading = new QLabel(tr("Current parameters"), parameterStrip);
|
|
|
|
for(int row = 0; row < parameterLayout->rowCount(); ++row) {
|
|
|
|
heading->setObjectName("sectionHeading");
|
|
|
|
parameterLayout->setRowMinimumHeight(row, 0);
|
|
|
|
parameterLayout->addWidget(heading, 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
parameterContent->setMinimumHeight(0);
|
|
|
|
for(int i = 0; i < parameterNames.size(); ++i) {
|
|
|
|
for(int i = 0; i < parameterNames.size(); ++i) {
|
|
|
|
// 名称和单位在上、数值在下,相邻参数用细竖线分隔。
|
|
|
|
// 名称和单位在上、数值在下,相邻参数用细竖线分隔。
|
|
|
|
QWidget* cell = new QWidget(parameterStrip);
|
|
|
|
const int row = i / 6;
|
|
|
|
|
|
|
|
const int column = i % 6;
|
|
|
|
|
|
|
|
QWidget* cell = new QWidget(parameterContent);
|
|
|
|
cell->setAttribute(Qt::WA_StyledBackground, true);
|
|
|
|
cell->setAttribute(Qt::WA_StyledBackground, true);
|
|
|
|
QVBoxLayout* cellLayout = new QVBoxLayout(cell);
|
|
|
|
QVBoxLayout* cellLayout = new QVBoxLayout(cell);
|
|
|
|
cellLayout->setContentsMargins(12, 0, 12, 0);
|
|
|
|
cellLayout->setContentsMargins(12, 0, 12, 0);
|
|
|
|
@ -800,22 +859,24 @@ void nmWxAutomaticfittingStart::setSelectedParameters(const QStringList& paramet
|
|
|
|
QLabel* name = new QLabel(parameterNames[i] + (unit.isEmpty() ? QString() : " / " + unit), cell);
|
|
|
|
QLabel* name = new QLabel(parameterNames[i] + (unit.isEmpty() ? QString() : " / " + unit), cell);
|
|
|
|
name->setObjectName("parameterName");
|
|
|
|
name->setObjectName("parameterName");
|
|
|
|
name->setWordWrap(true);
|
|
|
|
name->setWordWrap(true);
|
|
|
|
|
|
|
|
name->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred);
|
|
|
|
name->setAlignment(Qt::AlignCenter);
|
|
|
|
name->setAlignment(Qt::AlignCenter);
|
|
|
|
QLabel* value = new QLabel("--", cell);
|
|
|
|
QLabel* value = new QLabel("--", cell);
|
|
|
|
value->setObjectName("parameterValue");
|
|
|
|
value->setObjectName("parameterValue");
|
|
|
|
value->setAlignment(Qt::AlignCenter);
|
|
|
|
value->setAlignment(Qt::AlignCenter);
|
|
|
|
|
|
|
|
value->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred);
|
|
|
|
value->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
|
|
|
value->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
|
|
|
cellLayout->addWidget(name, 1);
|
|
|
|
cellLayout->addWidget(name, 1);
|
|
|
|
cellLayout->addWidget(value);
|
|
|
|
cellLayout->addWidget(value);
|
|
|
|
parameterLayout->addWidget(cell, 1, i * 2);
|
|
|
|
parameterLayout->addWidget(cell, row, column * 2);
|
|
|
|
parameterLayout->setColumnStretch(i * 2, 1);
|
|
|
|
parameterLayout->setColumnStretch(column * 2, 1);
|
|
|
|
if(i > 0) {
|
|
|
|
if(column > 0) {
|
|
|
|
// 分隔线独立于参数单元格,避免标题导致上下间距不一致。
|
|
|
|
// 分隔线独立于参数单元格,避免标题导致上下间距不一致。
|
|
|
|
QWidget* separator = new QWidget(parameterStrip);
|
|
|
|
QWidget* separator = new QWidget(parameterContent);
|
|
|
|
separator->setObjectName("parameterSeparator");
|
|
|
|
separator->setObjectName("parameterSeparator");
|
|
|
|
separator->setAttribute(Qt::WA_StyledBackground, true);
|
|
|
|
separator->setAttribute(Qt::WA_StyledBackground, true);
|
|
|
|
separator->setFixedWidth(1);
|
|
|
|
separator->setFixedWidth(1);
|
|
|
|
parameterLayout->addWidget(separator, 0, i * 2 - 1, 2, 1);
|
|
|
|
parameterLayout->addWidget(separator, row, column * 2 - 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
parameterValues.append(value);
|
|
|
|
parameterValues.append(value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -823,6 +884,9 @@ void nmWxAutomaticfittingStart::setSelectedParameters(const QStringList& paramet
|
|
|
|
|
|
|
|
|
|
|
|
// 立即显示当前已接受的参数值。
|
|
|
|
// 立即显示当前已接受的参数值。
|
|
|
|
updateParameterValues();
|
|
|
|
updateParameterValues();
|
|
|
|
|
|
|
|
parameterContent->ensurePolished();
|
|
|
|
|
|
|
|
updateParameterAreaHeight();
|
|
|
|
|
|
|
|
parameterScrollArea->verticalScrollBar()->setValue(0);
|
|
|
|
|
|
|
|
|
|
|
|
const QString algorithmName = m_algorithmName;
|
|
|
|
const QString algorithmName = m_algorithmName;
|
|
|
|
if(!m_autoFitterLM) addLogMessage(tr("%1 selected parameters: %2").arg(algorithmName).arg(parameterNames.join(", ")));
|
|
|
|
if(!m_autoFitterLM) addLogMessage(tr("%1 selected parameters: %2").arg(algorithmName).arg(parameterNames.join(", ")));
|
|
|
|
|