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++

#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();
}
}