#include "GvlManager.h"
#include "VPGlobal.h"
#include "WindowAppVariableTable.h"
#include "Preferences.h"
// 单例模式
GvlManager* GvlManager::m_pGvlManager = nullptr;
GvlManager::GvlManager()
{
// 创建默认的全局变量分组
this->initSystemGvl();
// 创建默认值变量分组(目前用于存储DataLink默认变量)
this->initDefaultValues();
}
///
/// 添加新的变量组
///
///
///
///
GVL* GvlManager::addNewGroup(const QString& strGroup, TOOL_TYPE varType, GVL_MODE gvlMode)
{
// 检查是否冲突
if (m_Gvls.contains(strGroup))
{
qDebug() << "[Error] GvlManager::addNewGroup - but [" << strGroup << "] is exist.";
return m_Gvls[strGroup];
}
// 添加新的空变量组
GVL* newGroup = new GVL(strGroup, varType, gvlMode);
this->m_Gvls.insert(strGroup, newGroup);
return newGroup;
}
///
/// 添加新的变量
///
///
///
///
bool GvlManager::addNewVariable(const QString& strGroup, VARIABLE* pNewVar)
{
// 获取所属变量组
GVLS::iterator it = this->m_Gvls.find(strGroup);
if (it != this->m_Gvls.end())
{
// 设置变量归属的父指针
pNewVar->setParent(it.value());
// pNewVar->pOriginalTool = it.value();
it.value()->Variables.push_back(pNewVar);
return true;
}
else
{
qWarning() << "[Error] GvlManager::addNewVariable - but [" << strGroup << "] is not exist.";
return false;
}
}
///
/// 2022-3-8添加新的默认变量(和正常变量分开存储)
///
///
///
bool GvlManager::addNewDefaultVariable(VARIABLE* pNewVar)
{
pNewVar->setParent(m_defaultValueGvl);
// pNewVar->pOriginalTool = m_defaultValueGvl;
m_defaultValueGvl->Variables.push_back(pNewVar);
return true;
}
///
/// 绑定UI和变量
///
///
///
void GvlManager::bindUIAndVariable(QTableWidget* pTable, QString& strVarFullName)
{
this->m_GvlTables.insert(strVarFullName, pTable);
}
///
/// 删除一个变量
///
///
///
void GvlManager::delVariable(const QString& strGroup, const int& nIndex)
{
VARIABLES& vars = m_Gvls[strGroup]->Variables;
// 清理此变量的内存
delete vars[nIndex]->value.Ptr;
*vars[nIndex]->value.Ptr = nullptr;
vars[nIndex]->value.Ptr = nullptr;
delete vars[nIndex];
vars[nIndex] = nullptr;
// 清理数组中的对应元素
vars.erase(vars.begin() + nIndex);
////// 删除此group下的nIndex变量
////for (QVector::iterator it = vars.begin(); it != vars.end();)
////{
//// if (it->item == pRunningBlock)
//// {
//// it = vars.erase(it);
//// }
//// else
//// {
//// it++;
//// }
////}
debugAllVariables();
}
///
/// 移除一个变量(无需释放内存)
///
///
///
void GvlManager::removeVariable(const QString& strGroup, const int& nIndex)
{
VARIABLES& vars = m_Gvls[strGroup]->Variables;
vars.erase(vars.begin() + nIndex);
// TODO:此处可能没有释放DB触发变量的Event,对应的Task端应该需要同时删除此Event的绑定
}
///
/// 移除一个变量(无需释放内存)
///
///
///
void GvlManager::removeVariable(const QString& strGroup, const QString& strName)
{
if (!m_Gvls.contains(strGroup))
{
return;
}
VARIABLES& vars = m_Gvls[strGroup]->Variables;
for (VARIABLES::iterator iter = vars.begin(); iter != vars.end();)
{
if ((* iter)->strName == strName)//进行路径匹配
{
vars.erase(iter);//删除该行
}
else
{
iter++;
}
}
// TODO:此处可能没有释放DB触发变量的Event,对应的Task端应该需要同时删除此Event的绑定
}
///
/// 变量交换顺序
///
///
///
///
void GvlManager::exchangeVariable(const QString& strGroup, const int& nIndex1, const int& nIndex2)
{
VARIABLE* varTmp = m_Gvls[strGroup]->Variables[nIndex1];
m_Gvls[strGroup]->Variables[nIndex1] = m_Gvls[strGroup]->Variables[nIndex2];
m_Gvls[strGroup]->Variables[nIndex2] = varTmp;
debugAllVariables();
}
///
/// /2022-3-2 绑定硬件组态指针和DB数据表
///
///
///
void GvlManager::bindHdwToolAndDB(TOOL* pTool, const QString& strDBGroup)
{
if ((pTool == nullptr) || (pTool->pDllPtr == nullptr))
{
return;
}
DllTool* pHdwTool = pTool->pDllPtr;
GVL* pDB = this->getGvl(strDBGroup);
if (pDB == nullptr)
{
qWarning() << "Failed to find Gvl :" << strDBGroup;
return;
}
pHdwTool->setBindDB(pDB);
pTool->strHdwInstName = strDBGroup;
pDB->strHdwInstName = pHdwTool->getInstanceName();
// 保存对应关系
m_DBToTool.insert(strDBGroup, pTool);
}
///
/// 2022-3-8 解绑硬件组态和指针
/// (此处只是添加了函数,但是尚未调用,需要额外加一下,在删除硬件工具和删除DB数据表的时候都需要调用)
///
///
///
void GvlManager::unbindHdwToolAndDB(TOOL* pTool, const QString& strDBGroup)
{
if ((pTool == nullptr) || (pTool->pDllPtr == nullptr))
{
return;
}
DllTool* pHdwTool = pTool->pDllPtr;
// DB端解绑
if (m_Gvls.contains(strDBGroup))
{
GVL* pDB = this->getGvl(strDBGroup);
if (pDB != nullptr)
{
pDB->strHdwInstName.clear();
}
}
// Dll端解绑
pHdwTool->unbindDB();
pTool->strHdwInstName.clear();
// 移除绑定信息
m_DBToTool.remove(strDBGroup);
}
///
/// 检查是否与本组变量重名
///
///
///
///
bool GvlManager::isDuplicated(const QString& strGroup, const QString& newName)
{
if (m_Gvls.find(strGroup) ==m_Gvls.end())
{
return false;
}
VARIABLES& vars = m_Gvls[strGroup]->Variables;
QVectorIterator it(vars);
while (it.hasNext())
{
const VARIABLE* var = it.next();
if (var->strName == newName)
{
return true;
}
}
return false;
}
///
/// 检查用户输入的变量类型和数值是否匹配
///
///
///
///
///
bool GvlManager::isValueValid(const QString& newType, const QString& newValue)
{
// 如果是字符串,那么所有的都合法
if (newType == Utility::getTypeString(VALUE_TYPE::Type_String))
{
return true;
}
// 如果是bool类型,只有true false 和 1 0 合法
else if (newType == Utility::getTypeString(VALUE_TYPE::Type_Bool))
{
if (newValue == "true" || newValue == "false" || newValue == "1" || newValue == "0")
{
return true;
}
else
{
return false;
}
}
// 如果是int类型
else if (newType == Utility::getTypeString(VALUE_TYPE::Type_Int))
{
return Utility::isIntString(newValue);
}
// 如果是float类型
else if (newType == Utility::getTypeString(VALUE_TYPE::Type_Float))
{
return Utility::isFloatString(newValue);
}
return true;
}
///
/// 检查用户输入的变量类型和数值是否匹配
///
///
///
///
bool GvlManager::isValueValid(const VALUE_TYPE newType, const QString& newValue)
{
// 如果是字符串,那么所有的都合法
if (newType == VALUE_TYPE::Type_String)
{
return true;
}
// 如果是bool类型,只有true false 和 1 0 合法
else if (newType == VALUE_TYPE::Type_Bool)
{
if (newValue == "true" || newValue == "false" || newValue == "1" || newValue == "0")
{
return true;
}
else
{
return false;
}
}
// 如果是int类型
else if (newType == VALUE_TYPE::Type_Int)
{
return Utility::isIntString(newValue);
}
// 如果是float类型
else if (newType == VALUE_TYPE::Type_Float)
{
return Utility::isFloatString(newValue);
}
return true;
}
///
/// 本分组是否是全局变量
///
///
///
bool GvlManager::isGlobalGvl(const QString& strGroup)
{
if (m_Gvls.contains(strGroup))
{
if (m_Gvls[strGroup]->Type == TOOL_TYPE::TOOL_TYPE_GLOBAL_VARIABLE)
{
return true;
}
}
return false;
}
///
/// 本分组是否是硬件变量
///
///
///
bool GvlManager::isHardwareGvl(const QString& strGroup)
{
return (strGroup== CATEGORY_TOOL_HARDWARE);
}
///
/// 本分组是否是Pou局部变量
///
///
///
bool GvlManager::isLocalGvl(const QString& strGroup)
{
if (m_Gvls.contains(strGroup))
{
if (m_Gvls[strGroup]->Type == TOOL_TYPE::TOOL_TYPE_LOCAL_VARIABLE)
{
return true;
}
}
return false;
}
///
/// 更新持久化状态
///
///
///
///
void GvlManager::updatePersit(const QString& strGroup, const int& nIndex, bool newValue)
{
// 有效性检查
VARIABLES& vars = m_Gvls[strGroup]->Variables;
if (nIndex >= vars.size())
{
return;
}
VARIABLE* var = m_Gvls[strGroup]->Variables[nIndex];
// 检查值是否有变动,没有变动就不更新了
if (var->bSerialized == newValue)
{
qDebug() << "[GVL] Change " << strGroup << "-Index: " << nIndex << " persistent, but is the same. ";
return;
}
var->bSerialized = newValue;
qDebug() << "[GVL] Change " << strGroup << "-Index: " << nIndex << " bPersit to " << newValue;
debugVariable(var);
}
///
/// 更新Value
///
///
///
///
bool GvlManager::updateValue(const QString& strGroup, const int& nIndex, const QString& newValue)
{
// 需要跳过不显示的变量
int nVarIndex = nIndex;
{
VARIABLES& vars = m_Gvls[strGroup]->Variables;
for (int i = 0; i< vars.size(); i++)
{
VARIABLE* var = m_Gvls[strGroup]->Variables[i];
if (!var->bShow)
{
nVarIndex++;
}
}
}
// 参数有效性检查
VARIABLES& vars = m_Gvls[strGroup]->Variables;
if (nVarIndex >= vars.size())
{
return false;
}
VARIABLE* var = m_Gvls[strGroup]->Variables[nVarIndex];
// 检查值是否和类型匹配
if (!this->isValueValid(var->value.type, newValue))
{
qDebug() << "[GVL] Change " << strGroup << "-Index: " << nVarIndex << " value, but is invalid. ";
//// 也要更新值,但是这个值是一个无效值,无法使用
//var->value.strValueString = newValue;
//var->bValid = false;
// debugVariable(var);
return false;
}
// 可以更新值了
//var->value.strValueString = newValue;
var->setValue(newValue);
//// 置为有效值
//var->bValid = true;
vDebug() << "[GVL] Change " << strGroup << "-Index: " << nVarIndex << " value to " << newValue;
// 2022-9-1,由于DB变量增加了触发Task执行的特性,如果是DB变量更新,并且带有触发特性,还需要向TaskManager发送触发信号
if (m_Gvls[strGroup]->gvlMode == GVL_MODE::GVL_DB)
{
if (var->eventTrigger != nullptr)
{
// 2022-9-25,由于WaitTool需要支持等待某一个值触发,所以ToolEvent中保存每次DB变量的最新值
var->eventTrigger->m_triggerValue = var->value;
// 发送到TaskManager触发Task执行
// NOTICE:此处注意不能用postEvent,否则会自动释放掉这个事件指针造成程序崩溃
QCoreApplication::sendEvent((QObject*)g_pTaskManager, var->eventTrigger);
vDebug() << "[GVL] Post " << var->strFullName << " event trigger to task.";
}
}
// debugVariable(var);
return true;
}
///
/// 更新Comment
///
///
///
///
bool GvlManager::updateComment(const QString& strGroup, const int& nIndex, const QString& newComment)
{
// 需要跳过不显示的变量
int nVarIndex = nIndex;
{
VARIABLES& vars = m_Gvls[strGroup]->Variables;
for (int i = 0; i < vars.size(); i++)
{
VARIABLE* var = m_Gvls[strGroup]->Variables[i];
if (!var->bShow)
{
nVarIndex++;
}
}
}
// 参数有效性检查
VARIABLES& vars = m_Gvls[strGroup]->Variables;
if (nVarIndex >= vars.size())
{
return false;
}
VARIABLE* var = m_Gvls[strGroup]->Variables[nVarIndex];
// 检查值是否有变动,没有变动就不更新了
if (var->strComment == newComment)
{
qDebug() << "[GVL] Change " << strGroup << "-Index: " << nVarIndex << " value, but is the same. ";
return true;
}
var->strComment = newComment;
qDebug() << "[GVL] Change " << strGroup << "-Index: " << nVarIndex << " Comment to " << newComment;
debugVariable(var);
return true;
}
///
/// 更新通讯地址(仅DB模式)
///
///
///
///
///
bool GvlManager::updateDbCommAddress(const QString& strGroup, const int& nIndex, const QString& newAddress)
{
// 参数有效性检查
VARIABLES& vars = m_Gvls[strGroup]->Variables;
if (nIndex >= vars.size())
{
return false;
}
VARIABLE* var = m_Gvls[strGroup]->Variables[nIndex];
// 检查值是否有变动,没有变动就不更新了
if (var->strCommAddress == newAddress)
{
qDebug() << "[GVL] Change " << strGroup << "-Index: " << nIndex << " value, but is the same. ";
return true;
}
var->strCommAddress = newAddress;
qDebug() << "[GVL] Change " << strGroup << "-Index: " << nIndex << " Comment to " << newAddress;
debugVariable(var);
return true;
}
///
/// 输出一个全局变量的详细信息(For Debug)
///
///
void GvlManager::debugVariable(const VARIABLE* var)
{
qDebug() << "[" << var->parent()->strName << "] - " << var->strName
<<"(Persis: " << var->bSerialized << ")"
<< "\n\t[Type] - " << Utility::getTypeString(var->value.type)
<< "\n\t[Value] - " << var->getValueString()
// << "\n\t[ValueString] - " << var->value.strValueString
<< "\n\t[Comment] - " << var->strComment;
}
///
/// 输出目前所有的全局变量信息
///
void GvlManager::debugAllVariables()
{
QMapIterator it(m_Gvls);
qDebug() << "================ All Variables =========================";
while (it.hasNext())
{
qDebug() << "Group: " << it.next().key();
const GVL* gvl = it.value();
QVectorIterator it2(gvl->Variables);
while (it2.hasNext())
{
const VARIABLE* var = it2.next();
qDebug() << "\t" << var->strName << " - " << var->bSerialized
<< " " << Utility::getTypeString(var->value.type)
<< " " << var->getValueString() << " " << var->strComment;
}
}
qDebug() << "=============================================================\n";
}
///
/// 根据名字获取指定变量
///
///
///
///
VARIABLE* GvlManager::getVariableByName(const QString& strGroupName, const QString& strVarName)
{
if (m_Gvls.contains(strGroupName))
{
const VARIABLES& vars = m_Gvls[strGroupName]->Variables;
for (auto var : vars)
{
if (var->strName == strVarName)
{
return var;
}
}
}
return nullptr;
}
///
/// 根据名字获取指定的默认值
///
///
///
const VARIABLE* GvlManager::getDefaultValueByName(const QString& strValueName) const
{
return m_defaultValueGvl->getInterfaceByName(strValueName);
}
///
/// 获取本分组的变量数
///
///
///
int GvlManager::getVariablesCountByGroup(const QString& strGroupName)
{
if (m_Gvls.contains(strGroupName))
{
return m_Gvls[strGroupName]->Variables.size();
}
else
{
return 0;
}
}
///
/// 2022-9-1 获取全部带有Event触发特性的变量
///
///
QHash GvlManager::getAllEventVariables()
{
QHash eventVars;
QMapIterator it(m_Gvls);
while (it.hasNext())
{
// 取出每一个变量组
const GVL* pGvl = it.next().value();
// 取出本变量组中的变量
const VARIABLES& vars = pGvl->Variables;
// 遍历所有变量,找到具有触发机制的变量,添加到界面中
for (VARIABLE* var : vars)
{
if (var->eventTrigger != nullptr)
{
eventVars.insert(var->strFullName, var);
}
}
}
return eventVars;
}
///
/// 获取需要序列化的分组(跳过系统内置变量)
///
///
QList GvlManager::getAllSerializedGvls()
{
QList gvls;
QMapIterator it(m_Gvls);
while (it.hasNext())
{
// 需要跳过系统内置变量和硬件变量
if (it.next().key() != GROUP_NAME_SYSTEM
&& it.key() != GROUP_NAME_HARDWARE
&& it.key() != GROUP_NAME_DEFAULVALUE
)
{
gvls.push_back(it.value());
}
}
return gvls;
}
///
/// 删除指定Pou分组
///
///
void GvlManager::removeGvl(const QString& strGroupName)
{
// 2022-2-22 ,此处如果是SYSTEM分组的话,需要跳过(这种情况应该不会出现才对)
if (strGroupName == GROUP_NAME_SYSTEM)
{
qWarning() << "[Warning] VariablesManager::removeVariablesGroup - name: System Group";
return;
}
// 删除变量组
m_Gvls.remove(strGroupName);
// 删除变量表格
m_GvlTables.remove(strGroupName);
// TODO: 是否需要清空相关内存?
}
///
/// 2021-11-13 接收表格中的变量刷新显示Event
///
///
void GvlManager::customEvent(QEvent* event)
{
// 只处理数值同步消息
if (event->type() == VALUE_EVENT_TYPEID)
{
qDebug() << "UiManager::event - VALUE_EVENT";
SyncValueEvent* pValueEvent = dynamic_cast (event);
// 取出参数
QList syncValues = pValueEvent->getSyncValues();
for (VARIABLE* syncVal : syncValues)
{
// 2022-3-23处理,如果是Port类型的话,这里的strFullName是错误的
// this->syncValueToTable(syncVal->strFullName, syncVal->getValueString());
if (syncVal->isBinded())
{
this->syncValueToTable(syncVal->pBindInterface->strFullName, syncVal->getValueString());
}
else
{
this->syncValueToTable(syncVal->strFullName, syncVal->getValueString());
}
}
}
}
///
/// 将变量同步更新到Table中
///
///
void GvlManager::syncValueToTable(const QString& strFullName, const QString& strValueString)
{
WindowAppVariableTable* pTableUI =
qobject_cast(this->m_GvlTables.value( strFullName));
if (pTableUI != nullptr)
{
// pTableUI->updateTableValue(pDownLinks[i]->strFullName, pDownLinks[i]->getValueString());
pTableUI->updateTableValue(strFullName, strValueString);
}
else
{
// 2022-2-17
qDebug() << "[DEBUG] VariablesManager::syncValueToTable - updateTableValue failed, reason: pTableUI is nullptr.";
}
}
///
/// 数据结构重置
///
void GvlManager::reset()
{
// m_Variables.clear();
// 2022-2-22修改,重置时需要跳过SYSTEM分组和硬件组态分组
for (GVLS::iterator it = m_Gvls.begin(); it != m_Gvls.end();)
{
if (it.key() != GROUP_NAME_SYSTEM
&& it.key() != GROUP_NAME_HARDWARE
&& it.key() != GROUP_NAME_DEFAULVALUE
)
{
// 删除分组之前,需要清理DB 组的绑定状态
if (it.value()->gvlMode == GVL_MODE::GVL_DB)
{
QString strGvlName = it.value()->strName;
TOOL* pTool = getHdwToolByDbName(strGvlName);
g_pGvlManager->unbindHdwToolAndDB(pTool, strGvlName);
}
it = m_Gvls.erase(it);
}
else
{
it++;
}
}
// TODO: 因为没有SYSTEM分组的变量表格显示,所以可以全部清除,如果后面有了SYSTEM变量表格也就需要细分一下了
m_GvlTables.clear();
// 重置SYSTEM分组变量的值
thePrefs.m_nRunningCount = 0;
thePrefs.m_strProjectPath = DEFAULT_PROJECT_PATH;
thePrefs.m_strProjectName = DEFAULT_PROJECT_NAME;
}
///
/// 2022-2-15 创建内置的全局变量组(System)
///
void GvlManager::initSystemGvl()
{
// int nIndex = getVariablesCountByGroup(GROUP_NAME_SYSTEM);
// 2022-3-2, 首先创建对应的系统变量组
this->addNewGroup(GROUP_NAME_SYSTEM, TOOL_TYPE::TOOL_TYPE_GLOBAL_VARIABLE, GVL_MODE::GVL_BASIC);
int nIndex = 0;
// 系统运行计数
VARIABLE* pNewVariable = new VARIABLE(
GROUP_NAME_SYSTEM,
false,
SYSTEMVAR_NAME_EXECCOUNT,
"int",
"0",
SYSTEMVAR_CHNAME_EXECCOUNT,
nIndex,
true
);
this->addNewVariable(GROUP_NAME_SYSTEM, pNewVariable);
// 系统项目名称
pNewVariable = new VARIABLE(
GROUP_NAME_SYSTEM,
false,
SYSTEMVAR_NAME_PROJECTNAME,
"QString",
"",
SYSTEMVAR_CHNAME_PROJECTNAME,
nIndex ++,
true
);
this->addNewVariable(GROUP_NAME_SYSTEM, pNewVariable);
// 系统项目路径
pNewVariable = new VARIABLE(
GROUP_NAME_SYSTEM,
false,
SYSTEMVAR_NAME_PROJECTPATH,
"QString",
"",
SYSTEMVAR_CHNAME_PROJECTPATH,
nIndex ++,
true
);
this->addNewVariable(GROUP_NAME_SYSTEM, pNewVariable);
// 系统时间
pNewVariable = new VARIABLE(
GROUP_NAME_SYSTEM,
false,
SYSTEMVAR_NAME_TIME,
"QString",
"00:00:00",
SYSTEMVAR_CHNAME_TIME,
nIndex ++,
true
);
this->addNewVariable(GROUP_NAME_SYSTEM, pNewVariable);
// 开机时长
pNewVariable = new VARIABLE(
GROUP_NAME_SYSTEM,
false,
SYSTEMVAR_NAME_RUNTIME,
"QString",
"00:00:00",
SYSTEMVAR_CHNAME_RUNTIME,
nIndex ++,
true
);
this->addNewVariable(GROUP_NAME_SYSTEM, pNewVariable);
// 2022-2-20,将必要的变量绑定至全局变量SYSTEM组中
this->bindSystemGvl();
}
///
/// 2022-2-20 绑定SYSTEM全局变量和类中的关键变量
///
void GvlManager::bindSystemGvl()
{
VARIABLE* pVar = getVariableByName(GROUP_NAME_SYSTEM, SYSTEMVAR_NAME_EXECCOUNT);
pVar->value.setValueByAddress((void**)&thePrefs.m_nRunningCount);
pVar = getVariableByName(GROUP_NAME_SYSTEM, SYSTEMVAR_NAME_PROJECTNAME);
pVar->value.setValueByAddress((void**)&thePrefs.m_strProjectName);
pVar = getVariableByName(GROUP_NAME_SYSTEM, SYSTEMVAR_NAME_PROJECTPATH);
pVar->value.setValueByAddress((void**)& thePrefs.m_strProjectPath);
pVar = getVariableByName(GROUP_NAME_SYSTEM, SYSTEMVAR_NAME_TIME);
pVar->value.setValueByAddress((void**)&thePrefs.m_strSystemTime);
pVar = getVariableByName(GROUP_NAME_SYSTEM, SYSTEMVAR_NAME_RUNTIME);
pVar->value.setValueByAddress((void**)&thePrefs.m_strLiveTime);
}
///
/// 2022-3-7 创建默认值的变量组,例如 0,"" 等等(DefaultValue)
/// (目前只有复杂控件的DataLink在使用,本组变量是只读的,不允许修改)
///
void GvlManager::initDefaultValues()
{
// 2022-3-2, 首先创建对应的默认值变量组
m_defaultValueGvl = new GVL(GROUP_NAME_DEFAULVALUE, TOOL_TYPE::TOOL_TYPE_GLOBAL_VARIABLE, GVL_MODE::GVL_STANDARD);
int nIndex = 0;
// int型的默认值
VARIABLE* pNewVariable = new VARIABLE(
GROUP_NAME_DEFAULVALUE,
false,
DEFAULT_VALUE_0,
"int",
"0",
"",
nIndex,
false
);
this->addNewDefaultVariable(pNewVariable);
// QString的默认值
pNewVariable = new VARIABLE(
GROUP_NAME_DEFAULVALUE,
false,
DEFAULT_VALUE_NULLSTRING,
"QString",
"",
"",
nIndex++,
false
);
this->addNewDefaultVariable(pNewVariable);
}
/////
///// 数据结构序列化
/////
/////
/////
/////
//QDataStream& operator<<(QDataStream& out, const GvlManager& w)
//{
// Q_UNUSED(w);
//
// return out;
//}
/////
///// 数据结构反序列化
/////
/////
/////
/////
//QDataStream& operator>>(QDataStream& in, GvlManager& w)
//{
// Q_UNUSED(w);
//
// return in;
//}