You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nmWTAI-Platform/Src/nmNum/nmGUI/nmGUIComponentBase.cpp

490 lines
14 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "nmGUIComponentBase.h"
#include "nmDataAttribute.h"
#include <QHBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QComboBox>
#include "nmDataAttribute.h"
#include <QtGlobal>
#include "nmTranslationManager.h"
Q_DECLARE_METATYPE(int*)
Q_DECLARE_METATYPE(double*)
Q_DECLARE_METATYPE(QString*)
nmGUIComponentBase::nmGUIComponentBase(nmDataAttribute* pOriginValue,
bool enable, QWidget *parent) :
QWidget(parent),
m_pLayout(nullptr),
m_pNameLabel(nullptr),
m_pValueEdit(nullptr),
m_pUnitComboBox(nullptr),
m_pOriginValue(pOriginValue),
m_isEnable(enable),
m_eUIType(NM_GUI_Component_Type_LineEdit),
m_baseValue(0.0),
m_baseUnit(""),
m_currentUnit(""),
m_valueEditedByUser(false) ,
m_lastValidValue(""),
m_bIsUpdateValue(false)
{
}
bool nmGUIComponentBase::updateValueToOrigin() {
if (m_pOriginValue == nullptr) {
return false;
}
QString sValue = "";
// 获取值
if (m_eUIType == NM_GUI_Component_Type_LineEdit) {
sValue = static_cast<QLineEdit*>(m_pValueEdit)->text().trimmed();
} else if (m_eUIType == NM_GUI_Component_Type_ComboBox) {
sValue = static_cast<QComboBox*>(m_pValueEdit)->currentText().trimmed();
}
if (sValue.isEmpty()) {
return false;
}
QVariant value = m_pOriginValue->getValue();
const int typeId = value.userType();
bool conversionOk = true;
QVariant newValue;
// 处理数值类型
if (typeId == QVariant::Double || typeId == QVariant::Int) {
double inputValue = sValue.toDouble(&conversionOk);
if (!conversionOk) {
return false;
}
// 将输入值从当前单位转换为原始单位
const double baseValue = m_pOriginValue->convertValueByUnitType(inputValue, m_currentUnit, m_baseUnit);
// 根据数据类型设置新值
if (typeId == QVariant::Int) {
newValue = static_cast<int>(baseValue);
} else {
//newValue = qRound(baseValue * 100.0)/ 100.0;
newValue = baseValue;
}
}
// 处理其他类型
else {
switch (typeId) {
case QVariant::String:
newValue = sValue;
break;
case QVariant::Bool:
newValue = sValue.toInt(&conversionOk) != 0;
break;
default:
conversionOk = false;
break;
}
}
if (conversionOk) {
m_pOriginValue->setValue(newValue);
return true;
}
return false;
}
bool nmGUIComponentBase::updateValueFromOrigin() {
if (!m_pOriginValue || !m_pValueEdit)
return false;
QVariant val = m_pOriginValue->getValue();
QString s;
// 数值类型
if (val.type() == QVariant::Double || val.type() == QVariant::Int) {
double baseVal = (val.type() == QVariant::Double
? val.toDouble()
: val.toInt());
// 把基础值从 baseUnit 转到 currentUnit
double disp = m_pOriginValue->convertValueByUnitType(baseVal, m_baseUnit, m_currentUnit);
s = QString::number(disp);
}
// 字符串类型
else if (val.type() == QVariant::String) {
s = val.toString();
}
else {
s = val.toString();
}
// 设置到 QLineEdit 或 QComboBox
if (m_eUIType == NM_GUI_Component_Type_LineEdit) {
static_cast<QLineEdit*>(m_pValueEdit)->setText(s);
m_lastValidValue = s; // 更新有效值
} else {
auto cb = static_cast<QComboBox*>(m_pValueEdit);
int idx = cb->findText(s);
if (idx>=0) cb->setCurrentIndex(idx);
}
return true;
}
//bool nmGUIComponentBase::updateValueFromOrigin() {
// if (!m_pOriginValue || !m_pValueEdit)
// return false;
//
// QVariant val = m_pOriginValue->getValue();
// QString s;
//
// // 数值类型
// if (val.type() == QVariant::Double || val.type() == QVariant::Int) {
// double baseVal = (val.type() == QVariant::Double
// ? val.toDouble()
// : val.toInt());
// // 把基础值从 baseUnit 转到 currentUnit
// double disp = m_pOriginValue->convertValueByUnitType(baseVal, m_baseUnit, m_currentUnit);
// s = QString::number(disp);
// }
// // 字符串类型
// else if (val.type() == QVariant::String) {
// s = val.toString();
// }
// else {
// s = val.toString();
// }
//
// // 设置到 QLineEdit 或 QComboBox
// if (m_eUIType == NM_GUI_Component_Type_LineEdit) {
// static_cast<QLineEdit*>(m_pValueEdit)->setText(s);
// } else {
// auto cb = static_cast<QComboBox*>(m_pValueEdit);
// int idx = cb->findText(s);
// if (idx>=0) cb->setCurrentIndex(idx);
// }
// return true;
//}
void nmGUIComponentBase::init() {
this->initUI();
}
void nmGUIComponentBase::initUI() {
this->initLayout();
this->initComponents();
this->initInitValue();
}
void nmGUIComponentBase::initLayout() {
m_pLayout = new QHBoxLayout(this);
m_pLayout->setContentsMargins(0, 0, 0, 0);
m_pLayout->setSpacing(5);
}
void nmGUIComponentBase::initComponents() {
if (!m_pOriginValue) return;
QString sName = nmTranslationManager::mapToChinese(m_pOriginValue->getName());
// 初始化标签 - 使用固定宽度
m_pNameLabel = new QLabel(sName, this);
m_pNameLabel->setAlignment(Qt::AlignVCenter | Qt::AlignLeft);
m_pNameLabel->setFixedWidth(200);
m_pLayout->addWidget(m_pNameLabel);
// 在标签和输入框之间添加弹性空间
m_pLayout->addStretch();
// 初始化值控件
if (m_eUIType == NM_GUI_Component_Type_LineEdit) {
QLineEdit *le = new QLineEdit(this);
m_pValueEdit = le;
le->setAlignment(Qt::AlignVCenter | Qt::AlignLeft);
le->setFixedWidth(137); // 设置固定宽度
connect(le, SIGNAL(textEdited(const QString&)), this, SLOT(onValueEdited(const QString&)));
connect(le, SIGNAL(editingFinished()), this, SLOT(onValueEditFinish()));
m_pLayout->addWidget(m_pValueEdit);
// 初始化单位控件
const QString unitCode = m_pOriginValue->getUnit();
if (!unitCode.isEmpty()) {
m_pUnitComboBox = new QComboBox(this);
QStringList unitSelections = m_pOriginValue->getListUnitSelections();
for (int i = 0; i < unitSelections.size(); ++i) {
const QString &code = unitSelections[i];
QString disp = nmTranslationManager::mapToChinese(code);
m_pUnitComboBox->addItem(disp, QVariant(code));
}
int idx = unitSelections.indexOf(unitCode);
if (idx >= 0) {
m_pUnitComboBox->setCurrentIndex(idx);
m_currentUnit = m_pUnitComboBox->itemData(idx).toString();
} else {
m_currentUnit = unitCode;
}
connect(m_pUnitComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onUnitChanged(int)));
m_pUnitComboBox->setFixedWidth(80); // 给单位下拉框设置固定宽度
m_pLayout->addWidget(m_pUnitComboBox);
} else {
// 没有单位时,添加相同宽度的占位空间,保持对齐
QWidget* placeholder = new QWidget(this);
placeholder->setFixedWidth(80); // 与单位框宽度相同
m_pLayout->addWidget(placeholder);
}
}
else if (m_eUIType == NM_GUI_Component_Type_ComboBox) {
m_pValueEdit = new QComboBox(this);
QStringList valueSelections = m_pOriginValue->getListValueSelections();
for (int i = 0; i < valueSelections.size(); ++i) {
valueSelections[i] = nmTranslationManager::mapToChinese(valueSelections[i]);
}
static_cast<QComboBox*>(m_pValueEdit)->addItems(valueSelections);
m_pLayout->addWidget(m_pValueEdit);
}
m_pValueEdit->setEnabled(m_isEnable);
}
//void nmGUIComponentBase::initComponents() {
// if (!m_pOriginValue) return;
//
// QString sName = nmTranslationManager::mapToChinese(m_pOriginValue->getName());
//
// // 初始化标签
// m_pNameLabel = new QLabel(sName, this);
// m_pNameLabel->setAlignment(Qt::AlignVCenter | Qt::AlignLeft);
// m_pNameLabel->setMinimumWidth(200);
// m_pLayout->addWidget(m_pNameLabel, 5);
//
// // 初始化值控件
// if (m_eUIType == NM_GUI_Component_Type_LineEdit) {
// QLineEdit *le = new QLineEdit(this);
// m_pValueEdit = le;
// le->setAlignment(Qt::AlignVCenter | Qt::AlignLeft);
// connect(le, SIGNAL(textEdited(const QString&)), this, SLOT(onValueEdited(const QString&)));
// // 编辑完成
// connect(le, SIGNAL(editingFinished()), this, SLOT(onValueEditFinish()));
//
// // 初始化单位控件
// const QString unitCode = m_pOriginValue->getUnit(); // 英文单位码
// if (!unitCode.isEmpty()) {
// m_pUnitComboBox = new QComboBox(this);
// QStringList unitSelections = m_pOriginValue->getListUnitSelections(); // 英文列表
//
// // 将英文 code 存为 itemData显示中文
// for (int i = 0; i < unitSelections.size(); ++i) {
// const QString &code = unitSelections[i];
// QString disp = nmTranslationManager::mapToChinese(code);
// m_pUnitComboBox->addItem(disp, QVariant(code)); // display=中文, data=英文
// }
//
// // 设置默认索引
// int idx = unitSelections.indexOf(unitCode);
// if (idx >= 0) {
// m_pUnitComboBox->setCurrentIndex(idx);
// m_currentUnit = m_pUnitComboBox->itemData(idx).toString(); // 取英文码
// }
// else {
// m_currentUnit = unitCode;
// }
//
// connect(m_pUnitComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onUnitChanged(int)));
//
// m_pLayout->addWidget(m_pValueEdit, 4);
// m_pLayout->addWidget(m_pUnitComboBox, 1);
// } else {
// m_pLayout->addWidget(m_pValueEdit, 5);
// }
// }
// else if (m_eUIType == NM_GUI_Component_Type_ComboBox) {
// m_pValueEdit = new QComboBox(this);
// QStringList valueSelections = m_pOriginValue->getListValueSelections();
// for (int i = 0; i < valueSelections.size(); ++i) {
// valueSelections[i] = nmTranslationManager::mapToChinese(valueSelections[i]);
// }
// static_cast<QComboBox*>(m_pValueEdit)->addItems(valueSelections);
// m_pLayout->addWidget(m_pValueEdit, 5);
// }
//
// m_pValueEdit->setEnabled(m_isEnable);
//}
//void nmGUIComponentBase::initInitValue() {
// if (!m_pOriginValue) return;
//
// // 初始化基础值和单位
// m_baseUnit = m_pOriginValue->getUnit();
// m_currentUnit = m_baseUnit;
//
// const QVariant valueVar = m_pOriginValue->getValue();
// if (valueVar.userType() == QVariant::Double) {
// m_baseValue = valueVar.toDouble();
// } else if (valueVar.userType() == QVariant::Int) {
// m_baseValue = valueVar.toInt();
// }
//
// // 设置初始显示值
// if (m_eUIType == NM_GUI_Component_Type_LineEdit) {
// if (valueVar.userType() == QVariant::Double || valueVar.userType() == QVariant::Int) {
// const double displayValue = m_pOriginValue->convertValueByUnitType(m_baseValue, m_baseUnit, m_currentUnit);
// static_cast<QLineEdit*>(m_pValueEdit)->setText(QString::number(displayValue));
// } else {
// static_cast<QLineEdit*>(m_pValueEdit)->setText(valueVar.toString());
// }
// }
//}
void nmGUIComponentBase::initInitValue() {
if (!m_pOriginValue) return;
// 初始化基础值和单位
m_baseUnit = m_pOriginValue->getUnit();
m_currentUnit = m_baseUnit;
const QVariant valueVar = m_pOriginValue->getValue();
if (valueVar.userType() == QVariant::Double) {
m_baseValue = valueVar.toDouble();
} else if (valueVar.userType() == QVariant::Int) {
m_baseValue = valueVar.toInt();
}
// 设置初始显示值
if (m_eUIType == NM_GUI_Component_Type_LineEdit) {
if (valueVar.userType() == QVariant::Double || valueVar.userType() == QVariant::Int) {
const double displayValue = m_pOriginValue->convertValueByUnitType(m_baseValue, m_baseUnit, m_currentUnit);
QString valueText = QString::number(displayValue);
static_cast<QLineEdit*>(m_pValueEdit)->setText(valueText);
m_lastValidValue = valueText; // 保存初始有效值
} else {
QString valueText = valueVar.toString();
static_cast<QLineEdit*>(m_pValueEdit)->setText(valueText);
m_lastValidValue = valueText; // 保存初始有效值
}
}
}
void nmGUIComponentBase::onUnitChanged(int index) {
if (!m_pUnitComboBox || !m_pValueEdit) return;
// 只有刚才改过文本才把显示值写回baseValue
if (m_valueEditedByUser) {
updateValueToOrigin();
m_valueEditedByUser = false;
}
// 从 itemData() 读取英文单位码
m_currentUnit = m_pUnitComboBox->itemData(index).toString();
updateValueFromOrigin();
}
void nmGUIComponentBase::onValueEdited(const QString &)
{
// 用户敲入时打标记
m_valueEditedByUser = true;
}
void nmGUIComponentBase::onValueEditFinish()
{
if (m_eUIType != NM_GUI_Component_Type_LineEdit) {
return;
}
QLineEdit* pLineEdit = static_cast<QLineEdit*>(m_pValueEdit);
QString currentText = pLineEdit->text().trimmed();
// 检查是否为空
if (currentText.isEmpty()) {
pLineEdit->setText(m_lastValidValue);
return;
}
// 检查是否为有效数字
bool ok = false;
double value = currentText.toDouble(&ok);
if (!ok) {
// 不是有效数字,恢复上一个有效值
pLineEdit->setText(m_lastValidValue);
return;
}
// 是有效数字,保存并更新到数据源
m_lastValidValue = QString::number(value); // 标准化数字格式
pLineEdit->setText(m_lastValidValue);
// 根据是否实时更新数据标记来选择是否立即更新值到数据源
if (m_bIsUpdateValue) {
updateValueToOrigin();
}
}
//void nmGUIComponentBase::onValueEditFinish()
//{
// // 根据是否实时更新数据标记来选择是否立即更新值到数据源
// if (m_bIsUpdateValue)
// {
// updateValueToOrigin();
// }
//}
void nmGUIComponentBase::setIsRealTimeUpdateValue(bool isUpdate)
{
m_bIsUpdateValue = isUpdate;
}
void nmGUIComponentBase::setOriginValue(nmDataAttribute* pOriginValue)
{
m_pOriginValue = pOriginValue;
if (m_pOriginValue) {
// 重新初始化单位
m_baseUnit = m_pOriginValue->getUnit();
m_currentUnit = m_baseUnit;
// 重新初始化基础值
const QVariant valueVar = m_pOriginValue->getValue();
if (valueVar.userType() == QVariant::Double) {
m_baseValue = valueVar.toDouble();
} else if (valueVar.userType() == QVariant::Int) {
m_baseValue = valueVar.toInt();
}
// 更新单位下拉框(如果存在)
if (m_pUnitComboBox) {
const QString unitCode = m_pOriginValue->getUnit();
QStringList unitSelections = m_pOriginValue->getListUnitSelections();
// 清空并重新填充
m_pUnitComboBox->clear();
for (int i = 0; i < unitSelections.size(); ++i) {
const QString &code = unitSelections[i];
QString disp = nmTranslationManager::mapToChinese(code);
m_pUnitComboBox->addItem(disp, QVariant(code));
}
// 设置当前索引
int idx = unitSelections.indexOf(unitCode);
if (idx >= 0) {
m_pUnitComboBox->setCurrentIndex(idx);
}
}
// 更新标签名称(如果需要)
if (m_pNameLabel) {
QString sName = nmTranslationManager::mapToChinese(m_pOriginValue->getName());
m_pNameLabel->setText(sName);
}
// 更新显示值
updateValueFromOrigin();
}
}