当前位置: 首页 > news >正文

动易网站中添加邮箱沈阳网站建设报价

动易网站中添加邮箱,沈阳网站建设报价,在线教育网站开发,网站内部链接建设QT-自定义参数设计框架软件 Chapter1 QT-自定义参数设计框架软件前言一、演示效果二、使用步骤1.应用进行参数注册2.数据库操作单例对象3.参数操作单例对象 三、下载链接 Chapter2 Qt中管理配置参数#xff08;QSettings、单例模式#xff09;1 前言2 QSettings类ini文件写in… QT-自定义参数设计框架软件 Chapter1 QT-自定义参数设计框架软件前言一、演示效果二、使用步骤1.应用进行参数注册2.数据库操作单例对象3.参数操作单例对象 三、下载链接 Chapter2 Qt中管理配置参数QSettings、单例模式1 前言2 QSettings类ini文件写ini文件读取Ini文件 3 单例模式4 参考文献 Chapter3 基于QT的参数设置界面介绍使用方法1.在你自己的工程中定义一个参数的结构体2.在你自己工程的界面中拖入一个QTableView控件将其提升为DBTableParamView.h3.Test_TableView.h4.Test_TableView.cpp Chapter4 QT实现一个系统参数管理窗口1. 配置参数类2. 管理界面 QWidget3. 主程序代码说明1. ConfigManager 类:2. ConfigWidget 类:3. 主程序: Chapter5 Qt平台自动化项目开发基础框架一、程序框架结构二、GUI界面开发1登录界面2主界面3手动控制界面Qwidget 三、主控制线程1多线程之间的数据共享2主控制逻辑 四、外设模块线程五、日志1)头文件2调用方法 Chapter1 QT-自定义参数设计框架软件 原文链接https://blog.csdn.net/u013083044/article/details/137160536 前言 常用本地数据参数通常使用的是xml等文本的格式进行本地的数据参数的存储。这种参数的保存方式有个致命的一点就是可以存在参数的丢失。特别是在软件异常退出的情况下发生。 针对此等情况我们现在使用的是sqllite的本地存储方式进行设计并且尽量将参数的格式通用化。 一、演示效果 二、使用步骤 1.应用进行参数注册 代码如下 void QSettingTools::registerParams() {if (1){QString strGroupName u8用户参数;cParamOperator::getInstance()-registerQString(strGroupName, User, sa, QString(u8用户名称));cParamOperator::getInstance()-registerQString(strGroupName, Passord, 123456, QString(u8用户密码));cParamOperator::getInstance()-registerInt(strGroupName, Index, 0, 0, 10000, QString(u8序号));cParamOperator::getInstance()-registerFloat(strGroupName, Time, 1.5, 0, 10000, QString(u8时间单位秒));}if (1){QString strGroupName u8系统参数;cParamOperator::getInstance()-registerQString(strGroupName, FactoryId, 123433ad, QString(u8工厂ID));}cParamOperator::getInstance()-autoRemoveInvialParams();} 2.数据库操作单例对象 代码如下 #include ParamOperator.h #include SqlLiteDatabase.h #include QFile #include QMutex #include QXmlStreamWriter #include QDebug #include QCoreApplication #include QDomDocument #include QApplicationcParamOperator g_userParam; // 用户参数struct cAppBaserData {QHashQString, QString strScrTranHash; };cParamOperator::cParamOperator(): d_ptr(new cParamManagerData) {m_strConfig Setting.db; }cParamOperator::~cParamOperator() {delete d_ptr;d_ptr nullptr; }// 获取一个实例 cParamOperator *cParamOperator::getInstance() {static cParamOperator manager;return manager; }// 设置app安装目录 void cParamOperator::setAppExePath(QString strPath) {m_strAppExePath strPath;cSqlLiteDatabase::getInstance()-setAppExePath(strPath);initialParams(); }// 注册整形参数 void cParamOperator::registerInt(QString strGroup, QString strName, int nMin, int nSet, int nMax, QString strDescribe) {sParamItem_t paramItem; paramItem.strGroupName strGroup;paramItem.strParamType PARAM_TYPE_INT; paramItem.strName strName;paramItem.strDescribe strDescribe;paramItem.minVal nMin;paramItem.setVal nSet;paramItem.maxVal nMax;registerParam(paramItem); }// 注册浮点型参数 void cParamOperator::registerFloat(QString strGroup, QString strName, float fMin, float fSet, float fMax, QString strDescribe) {sParamItem_t paramItem;paramItem.strGroupName strGroup;paramItem.strParamType PARAM_TYPE_FLOAT;paramItem.strName strName;paramItem.strDescribe strDescribe;paramItem.minVal fMin;paramItem.setVal fSet;paramItem.maxVal fMax;registerParam(paramItem); }// 注册字符串参数 void cParamOperator::registerQString(QString strGroup, QString strName, QString strSet, QString strDescribe) {sParamItem_t paramItem;paramItem.strGroupName strGroup;paramItem.strParamType PARAM_TYPE_STRING;paramItem.strName strName;paramItem.strDescribe strDescribe;paramItem.minVal ;paramItem.setVal strSet;paramItem.maxVal ;registerParam(paramItem); }// 修改参数值 void cParamOperator::setParam(QString strName, QVariant var) {auto pParam getParam(strName);if (pParam ! nullptr){pParam-setVal var;g_userParam.updateParam(*pParam);} }// 获取整数 int cParamOperator::getParamInt(QString strName) {auto param getParam(strName);if (param ! nullptr){return param-setVal.toInt();}return -12345; }// 获取浮点数 float cParamOperator::getParamFloat(QString strName) {auto param getParam(strName);if (param ! nullptr){return param-setVal.toFloat();}return -12345; }// 获取字符串 QString cParamOperator::getParamString(QString strName) {auto param getParam(strName);if (param ! nullptr){return param-setVal.toString();}return Error; }// 获取参数组名链表 QStringList cParamOperator::getGroupNameList() {QStringList strNameList;auto paramList params();for (size_t i 0; i paramList-size(); i){auto item paramList-at(i);if (!strNameList.contains(item.strGroupName)){strNameList item.strGroupName;}}return strNameList; }// 获取某个组的所有参数 QVectorsParamItem_t cParamOperator::getGroupParam(QString strGroupName) {QVectorsParamItem_t list;auto paramList params();for (size_t i 0; i paramList-size(); i){auto item paramList-at(i);if (item.strGroupName strGroupName){list item;}}return list; }// 初始化一个参数插入内存中 int cParamOperator::initialParamItem(sParamItem_t param) {// 注册过的就直接返回就行了if (d_ptr-mapName.contains(param.strName))return d_ptr-mapName.value(param.strName);// 链表没有插入链表记录auto index d_ptr-vecParam.count();d_ptr-vecParam.append(param);d_ptr-mapName.insert(param.strName, index);// 如果有组名直接插入到组名对应得链表里面if (d_ptr-mapGroup.contains(param.strGroupName)){for (auto iter d_ptr-mapGroup.begin(); iter ! d_ptr-mapGroup.end(); iter){if (iter.key() param.strGroupName){iter.value().insert(param.strName, index);break;}}}else{// 重新建立一个组名链表QHashQString, int groupItem;groupItem.insert(param.strName, index);d_ptr-mapGroup.insert(param.strGroupName, groupItem);}return index; }// 刷新参数 bool cParamOperator::updateParam(sParamItem_t param, bool bUpdateAll) {bool bRet false;if (!param.strName.isEmpty()){if (bUpdateAll){// 整个项都更新cSqlLiteDatabase::getInstance()-update(d_ptr-strTableName, g_strTagName, param.strName, g_strTagSetVal, param.setVal.toString());cSqlLiteDatabase::getInstance()-update(d_ptr-strTableName, g_strTagName, param.strName, g_strTagGroupName, param.strGroupName);cSqlLiteDatabase::getInstance()-update(d_ptr-strTableName, g_strTagName, param.strName, g_strTagType, param.strParamType);cSqlLiteDatabase::getInstance()-update(d_ptr-strTableName, g_strTagName, param.strName, g_strTagMinVal, param.minVal.toString());cSqlLiteDatabase::getInstance()-update(d_ptr-strTableName, g_strTagName, param.strName, g_strTagMaxVal, param.maxVal.toString());}else{cSqlLiteDatabase::getInstance()-update(d_ptr-strTableName, g_strTagName, param.strName, g_strTagSetVal, param.setVal.toString());}}return bRet; }// 通过参数名获取参数 sParamItem_t *cParamOperator::getParam(QString strName) {return getParam(d_ptr-mapName.value(strName, -1)); }// 通过索引获取参数 sParamItem_t *cParamOperator::getParam(int nIndex) {if (nIndex 0 nIndex d_ptr-vecParam.count())return d_ptr-vecParam[nIndex];return nullptr; }// 所有的参数 QVectorsParamItem_t* cParamOperator::params() {return d_ptr-vecParam; }// 删除参数 bool cParamOperator::removeParam(QString strName) {for (int i 0; i d_ptr-vecParam.size(); i){if (d_ptr-vecParam[i].strName strName){d_ptr-vecParam.removeAt(i);break;}}return cSqlLiteDatabase::getInstance()-remove(m_strTableName, g_strTagName, strName); }// 注册参数 int cParamOperator::registerParam(sParamItem_t param) {// 缓存起来if (!m_strResisterNameList.contains(param.strName))m_strResisterNameList param.strName;// 注册过组名不同得话就重新修改所属得组名如果没有就直接返回if (d_ptr-mapName.contains(param.strName)){auto paramTemp getParam(param.strName);// 如果组名不同就换新注册得组名if (paramTemp-strGroupName ! param.strGroupName){auto itGroup d_ptr-mapGroup.find(paramTemp-strGroupName);if (itGroup ! d_ptr-mapGroup.end()){// 删掉旧的再插入新得auto qTempHash itGroup.value();d_ptr-mapGroup.erase(itGroup);d_ptr-mapGroup.insert(param.strGroupName, qTempHash);}// 更新为最新注册得paramTemp-strGroupName param.strGroupName;cSqlLiteDatabase::getInstance()-update(d_ptr-strTableName, g_strTagName, param.strName, g_strTagGroupName, param.strGroupName);}cSqlLiteDatabase::getInstance()-update(d_ptr-strTableName, g_strTagName, param.strName, g_strTagMinVal, param.minVal.toString());cSqlLiteDatabase::getInstance()-update(d_ptr-strTableName, g_strTagName, param.strName, g_strTagMaxVal, param.maxVal.toString());auto pItem getParam(param.strName);if (pItem ! nullptr){pItem-strDescribe param.strDescribe;pItem-minVal param.minVal;pItem-maxVal param.maxVal;if (pItem-strDescribe.indexOf(《****)! -1){param.strRemarks ;}pItem-strRemarks param.strRemarks;}return d_ptr-mapName.value(param.strName);}// 链表没有插入链表记录auto index d_ptr-vecParam.count();d_ptr-vecParam.append(param);d_ptr-mapName.insert(param.strName, index);QHashQString, QString itemHash;// 同时插入数据表itemHash.insert(g_strTagGroupName, param.strGroupName);itemHash.insert(g_strTagType, param.strParamType);itemHash.insert(g_strTagName, param.strName);itemHash.insert(g_strTagSetVal, param.setVal.toString());itemHash.insert(g_strTagMinVal, param.minVal.toString());itemHash.insert(g_strTagMaxVal, param.maxVal.toString());itemHash.insert(g_strTagDescribe, param.strDescribe);cSqlLiteDatabase::getInstance()-insert(d_ptr-strTableName,itemHash);// 如果有组名直接插入到组名对应得链表里面if (d_ptr-mapGroup.contains(param.strGroupName)){for (auto iter d_ptr-mapGroup.begin(); iter ! d_ptr-mapGroup.end(); iter){if (iter.key() param.strGroupName){iter.value().insert(param.strName, index);break;}}}else{// 重新建立一个组名链表QHashQString, int groupItem;groupItem.insert(param.strName, index);d_ptr-mapGroup.insert(param.strGroupName, groupItem);}return index; }// 全部注册后删除无效参数注意所有的参数要全部注册完成后调用 void cParamOperator::autoRemoveInvialParams() {for (auto itSqlName:m_strSqlParamNameList){// 如果程序注册的链表不存在就需要删除数据库的参数if (!m_strResisterNameList.contains(itSqlName)){removeParam(itSqlName);}}// 重新排序按注册顺序显示QVectorsParamItem_t tempAllParam d_ptr-vecParam;d_ptr-vecParam.clear();d_ptr-mapName.clear();d_ptr-mapGroup.clear();for (auto itRegister:m_strResisterNameList){for (auto itFind : tempAllParam){if (itFind.strName itRegister){initialParamItem(itFind);break;}}}}// 初始化数据参数 int cParamOperator::initialParams(QString strTableName) {if (strTableName.isEmpty())return -1;// 先打开数据库cSqlLiteDatabase::getInstance()-openDb(m_strConfig);m_strTableName strTableName;static QMutex mutex;mutex.lock();// 创建数据库表QStringList strList;strList g_strTagGroupName g_strTagType g_strTagName g_strTagSetVal g_strTagMinVal g_strTagMaxVal g_strTagDescribe g_strTagIsTemp;d_ptr-strTableName strTableName;cSqlLiteDatabase::getInstance()-createTable(strTableName, strList);// 查找数据库表的所有参数auto dataHashList cSqlLiteDatabase::getInstance()-select(strTableName);for (int i 0; i dataHashList.size(); i){auto hash dataHashList[i];sParamItem_t paramItem;paramItem.strGroupName hash.find(g_strTagGroupName) ! hash.end() ? hash.find(g_strTagGroupName).value() : ;paramItem.strParamType hash.find(g_strTagType) ! hash.end() ? hash.find(g_strTagType).value() : ;paramItem.strName hash.find(g_strTagName) ! hash.end() ? hash.find(g_strTagName).value() : ;paramItem.setVal hash.find(g_strTagSetVal) ! hash.end() ? hash.find(g_strTagSetVal).value() : ;paramItem.minVal hash.find(g_strTagMinVal) ! hash.end() ? hash.find(g_strTagMinVal).value() : ;paramItem.maxVal hash.find(g_strTagMaxVal) ! hash.end() ? hash.find(g_strTagMaxVal).value() : ;paramItem.strDescribe hash.find(g_strTagDescribe) ! hash.end() ? hash.find(g_strTagDescribe).value() : ;// 缓存数据库的参数名称if (!m_strSqlParamNameList.contains(paramItem.strName))m_strSqlParamNameList paramItem.strName;initialParamItem(paramItem);}mutex.unlock();return 0; } 3.参数操作单例对象 代码如下 #include SqlLiteDatabase.h #include QDir #include QDateTime #include QApplicationcSqlLiteDatabase::cSqlLiteDatabase(QObject *parent): QObject(parent) {}cSqlLiteDatabase::~cSqlLiteDatabase() {closeDb(); }// 设置appExe安装目录 void cSqlLiteDatabase::setAppExePath(QString strPath) {m_strExePath strPath;createDir(); }// 获取实例 cSqlLiteDatabase *cSqlLiteDatabase::getInstance() {static cSqlLiteDatabase obj;return obj; }// 创建配置文件夹 void cSqlLiteDatabase::createDir() {QDir dir;m_strConfigPath m_strExePath QString(/Config);if (!dir.exists(m_strConfigPath))dir.mkpath(m_strConfigPath);m_strDbDirPath m_strConfigPath; }// 打开数据库 QSqlDatabase cSqlLiteDatabase::openDb(QString strDatabaseName, QString strDbDirPath) {if (!strDbDirPath.isEmpty())m_strDbDirPath strDbDirPath;m_strDatabaseName strDatabaseName;QSqlDatabase db;if (QSqlDatabase::contains(m_strDatabaseName))db QSqlDatabase::database(m_strDatabaseName);else{QString strTempName m_strDbDirPath /strDatabaseName;db QSqlDatabase::addDatabase(QSQLITE, m_strDatabaseName);db.setDatabaseName(strTempName);db.setPassword(8888);db.setHostName(root);db.setUserName(root);}if (!db.open())qDebug() db.lastError().text();elsem_bConnected true;return db;}// 关闭数据库 bool cSqlLiteDatabase::closeDb() {QSqlDatabase::removeDatabase(m_strDatabaseName);return true; }// 创建表 bool cSqlLiteDatabase::createTable(QString strTableName, QStringList strHeaderNameList) {bool bRet true;if (true){if (strTableName.isEmpty() || strHeaderNameList.size() 0){bRet false;return bRet;}auto findItem m_strTableNameHeaderHash.find(strTableName);if (findItem m_strTableNameHeaderHash.end())m_strTableNameHeaderHash.insert(strTableName, strHeaderNameList);QString strCreateTable QString(u8CREATE TABLE %1().arg(strTableName);for (int i 0; i strHeaderNameList.size(); i){if (i (strHeaderNameList.size() - 1))strCreateTable strCreateTable strHeaderNameList[i] QString(u8 VARCHAR(256)) QString(,);elsestrCreateTable strCreateTable strHeaderNameList[i] QString(u8 VARCHAR(256)) QString());}bRet excute(strCreateTable);}return bRet; }// 删除表 bool cSqlLiteDatabase::dropTable(QString strTableName) {if (strTableName.isEmpty())return false;QString strDrop QString(DROP TABLE %1).arg(strTableName);return excute(strDrop); }// 执行sql语句 bool cSqlLiteDatabase::excute(QString strSql) {static QMutex mutex;mutex.lock();bool bRet true;QSqlDatabase db openDb(m_strDatabaseName);QString strConnectionName db.connectionName();QSqlQuery query(db);query.prepare(strSql);bool success query.exec(strSql);if (!success){qDebug() Error: query.lastError();bRet false;}closeDb();mutex.unlock();return bRet; }// 查找 QListQStringList cSqlLiteDatabase::seach(QString strTableName, QString strSql) {QListQStringList temp;QSqlDatabase db openDb(m_strDatabaseName);QString strConnectionName db.connectionName();db.transaction(); // 开启事务查询QSqlQuery query(, db);query.exec(strSql);db.commit(); // 提交事务while (query.next()){QStringList keyValueHash;int nCount query.record().count();for (size_t i 0; i nCount; i)keyValueHash query.record().value(i).toString();if (keyValueHash.size() 0)temp keyValueHash;}closeDb();return temp; }// 查找 QList QHashQString/*name*/, QString/*value*/ cSqlLiteDatabase::select(QString strTableName, QString strName, QString strValue) {QList QHashQString, QString temp;if (strTableName.isEmpty() || strTableName.isEmpty())return temp;QSqlDatabase db openDb(m_strDatabaseName);QString strConnectionName db.connectionName();QString strSelect();if (!strValue.isEmpty() !strName.isEmpty())strSelect QString(SELECT * FROM %1 WHERE %2 %3;).arg(strTableName).arg(strName).arg(strValue);elsestrSelect QString(SELECT * FROM %1;).arg(strTableName);db.transaction(); // 开启事务查询QSqlQuery query(, db);query.exec(strSelect);db.commit(); // 提交事务while (query.next()){QHashQString, QString keyValueHash;int nCount query.record().count();for (size_t i 0; i nCount; i)keyValueHash.insert(query.record().fieldName(i), query.record().value(i).toString());if (keyValueHash.size() 0)temp keyValueHash;}closeDb();return temp; }// 插入数据 bool cSqlLiteDatabase::insert(QString strTableName, QHashQString/*name*/, QString/*value*/ dataHash) {bool bRet false;if (strTableName.isEmpty())return bRet;QStringList strHeaderList;auto findItem m_strTableNameHeaderHash.find(strTableName);if (findItem m_strTableNameHeaderHash.end())return bRet;elsestrHeaderList m_strTableNameHeaderHash[strTableName];if (true){QString strInsert QString(u8INSERT INTO %1 VALUES().arg(strTableName);for (size_t j 0; j strHeaderList.size(); j){QString strName strHeaderList[j];QString strValue ;auto findName dataHash.find(strName);if (findName ! dataHash.end())strValue findName.value();if (j (strHeaderList.size() - 1))strInsert strInsert QString(u8%1).arg(strValue) QString(,);elsestrInsert strInsert QString(u8%1).arg(strValue) QString());}bRet excute(strInsert);} return bRet; }// 更新数据 bool cSqlLiteDatabase::update(QString strTableName, QString strWhereName, QString strWhereValue, QString strUpdateName, QString strUpdateValue) {bool bRet false;if (strTableName.isEmpty())return bRet;QStringList strHeaderList;auto findItem m_strTableNameHeaderHash.find(strTableName);if (findItem m_strTableNameHeaderHash.end())return bRet;if (true){QString strUpdate QString(u8UPDATE %1 SET %2%3 WHERE %4%5;).arg(strTableName).arg(strUpdateName).arg(strUpdateValue).arg(strWhereName).arg(strWhereValue);bRet excute(strUpdate);}return bRet; }// 删除数据 bool cSqlLiteDatabase::remove(QString strTableName, QString strWhereName, QString strWhereValue) {bool bRet false;if (strTableName.isEmpty())return bRet;QStringList strHeaderList;auto findItem m_strTableNameHeaderHash.find(strTableName);if (findItem m_strTableNameHeaderHash.end())return bRet;if (true){QString strUpdate QString(u8DELETE FROM %1 WHERE %2%3;).arg(strTableName).arg(strWhereName).arg(strWhereValue);bRet excute(strUpdate);}return bRet; }// 模糊查询 QStringList cSqlLiteDatabase::fuzzySearch(QString strTableName, QString strName, QString strLike) {QStringList temp;if (strTableName.isEmpty() || strTableName.isEmpty())return temp;QSqlDatabase db openDb(m_strDatabaseName);QString strConnectionName db.connectionName();QString strSelect();if (!strLike.isEmpty())strSelect QString(SELECT %1 FROM %2 WHERE %3 LIKE %%4% LIMIT 0,10;).arg(strName).arg(strTableName).arg(strName).arg(strLike);elsereturn temp;db.transaction(); // 开启事务查询QSqlQuery query(, db);query.exec(strSelect);while (query.next()){QHashQString, QString keyValueHash;for (size_t i 0; i query.record().count(); i){QString strName query.record().fieldName(i);QString strValue query.record().value(i).toString();if (!temp.contains(strValue) (strLike ! strValue))temp strValue;}}db.commit(); // 提交事务closeDb();return temp; } 三、下载链接 https://download.csdn.net/download/u013083044/89053778 Chapter2 Qt中管理配置参数QSettings、单例模式 原文链接https://blog.csdn.net/yunshu0_0/article/details/133132431 1 前言 描述为什么需要配置类以及为什么使用单利 工作过程中总是需要修改用于内网本地测试的版本或者外网测试版本此时如果将参数直接导出到配置文件config.ini只修改单个参数即可。当然很多地方也是如此如修改用户界面主题等使用配置文件保存配置参数是比较好的做法。在Qt中提供了QSettings类来格式导出和导入配置文件。 另外我希望能够全局访问配置文件并且要考虑多线程访问的情况因此考虑实现为单例在单例中需要考虑如何避免出现竞态条件如何析构此单例类 因此本篇文章的主要目的是 1. 创建单例类可应对多线程情况且能够正确析构 2. 结合QSettings生成配置文件和读取配置文件 2 QSettings类 此处只描述本次使用的情景还有额外的其他使用方法如设置写入的位置是用户范围还是系统范围设置公司、机构、软件名等等。 ini文件 .ini 文件是Initialization File的缩写即初始化文件。INI文件被用来对操作系统或特定程序初始化或进行参数设置以实现不同用户的要求。一般不用直接编辑这些.ini文件应用程序的图形界面即可操作以实现相同的功能。 Qt中可使用QSettings存储.ini文件.ini文件有[section]、keyvalue组成。其中section表示段用于区分项目中不同的部分配置参数key和value为键值对value为QVariant类型。 [transmitData] port9600 station1[canvas] gridStyletrue width500 height400写ini文件 将配置参数写入QSettings对象如下 //创建此对象也可创建在堆上 QSettings settings(/home/petra/misc/myapp.ini, QSettings::IniFormat);//此处直接填写的是文件路径 setting.setIniCodec(QTextCodec::codecForName(UTF-8));//设置文件编码配置文件中使用中文时这是必须的否则乱码//beginGroup和endGroup可设置一级标题中间的setValue为设置的参数 settings.beginGroup(mainwindow); settings.setValue(size, win-size()); settings.setValue(fullScreen, win-isFullScreen()); settings.endGroup();QSettings::Format取值为 QSettings::NativeFormat在windows平台可以读写windows注册表 QSettings::IniFormat可以读写ini格式的配置文件 小心使用分号和逗号 分号在ini配置文件中是注释符号 逗号在ini配置文件中被解析为数组分隔符 层级结构除了使用上述的写法也可以使用前缀的方式 settings.setValue(“mainwindow/size”, win-size()); 编码 配置文件如果有中文就需要设置为setting.setIniCodec(QTextCodec::codecForName(“UTF-8”)) 保存float有问题将其转换为double就好 其他 创建QSettings后如果指定文件不存在则创建文件 setValue不会立刻写入本地磁盘只是修改了缓冲参数因此在修改参数后可调用settings-sync()或者syncFlushFileBuffers来同步 QSettings* setting new QSettings(config.ini, QSettings::IniFormat); setting-setIniCodec(QTextCodec::codecForName(UTF-8)); setting-beginGroup(Transmit); setting-setValue(port, 9600); setting-setValue(width, 500); setting-setValue(height, 400); setting-endGroup(); setting-sync();读取Ini文件 QSettings settings(/home/petra/misc/myapp.ini, QSettings::IniFormat);//此处直接填写的是文件路径//beginGroup和endGroup可设置一级标题中间的setValue为设置的参数 settings.beginGroup(mainwindow); QSize size settings.value(size).toSize(); QColor settings.value(color).valueQColor(); settings.endGroup();也可使用前缀读取方式 QSize size settings.value(mainwindow\size).toSize();默认值 如果不存在该标签项则可以在第二个参数处填写默认值否则就直接返回空QVariant() 对于QGUI的部分类型如QPixmap、QColor等无法直接toColor可使用QVariant.value来实现 自定义类型可以使用qRegisterMetaType(MyStruct)注册 3 单例模式 为了在全局使用同一个配置文件或者日志文件使用单例模式是比较适合的。使用步骤 私有化构造函数、拷贝构造函数、析构函数、operator等内部创建静态对象指针并创建静态函数返回该对象指针 注意 如何避免多线程形成竞态条件 如何更好的析构该单例对象 class ConfigParam { public:static ConfigParam* GetInstance(){if(m_pInstance nullptr)//采用双判断是为了减少不断的加锁、解锁的操作{static QMutex mutex;mutex.lock();if(m_pInstance nullptr)m_pInstance new ConfigParam;//加锁是为了避免线程检查条件后开始创建对象还未创建时切换线程其他线程也继续创建对象mutex.unlock();}return m_pInstance;}class Deletor{public:~Deletor(){delete m_pInstance;m_pInstance nullptr;}};private:static ConfigParam* m_pInstance;static Deletor deleter;//创建为静态对象在清理全局区时调用该软件的析构函数会释放单例对象private:ConfigParam(){}~ConfigParam(){}ConfigParam(const ConfigParam){}ConfigParam operator(const ConfigParam){return *this;} };ConfigParam* ConfigParam::m_pInstance nullptr; ConfigParam::Deletor ConfigParam::deleter; 4 参考文献 【1】总结Qt读写ini配置文件(QSettings) 【2】QT学习之如何读写配置文件QSettings 【3】QSettings 【4】单例模式——讲解比较通透 Chapter3 基于QT的参数设置界面 原文链接https://blog.csdn.net/db7328537/article/details/127085940 介绍 在一些工业开发的软件中需要对一些硬件或者算法进行参数的设置但是QT官方给出的QtTreeProperty控件在一些程度上不足以满足我们的需求比如说单独的按钮以及一些选择文件夹和文件路径等。在次基础上利用QT5.14.2的QTableView控件来制作一款参数设置控件。界面效果如下 说明 参数1 代表 int型整数 参数2 代表 double型参数 参数3 代表 QString型参数 参数4 代表 true or false参数 参数5 代表 下拉框型参数 参数6 代表 枚举型参数 参数7 代表 QPoint型参数 参数8 代表 矩形参数(row1, col1, row2, col2) 参数9 代表 旋转矩形参数(row,col,phi,length1,length2) 参数10 代表 QSize型参数 参数11 代表 QPushButton型 参数12 代表 QColor型参数 参数13 代表 QFont型参数 参数14 代表 选择文件路径 参数15 代表 选择文件及路径 使用方法 1.在你自己的工程中定义一个参数的结构体 struct STBaseParam //算法输入的基本参数 {STBaseParam(){nParamClassify 1;sParamName ;sParamLabel ;sParamTip ;nParamType 0;sParamDefault ;sParamValueRange ;sParamValue ;sParamRemark ;}~STBaseParam(){nParamClassify 1;sParamName ;sParamLabel ;sParamTip ;nParamType 0;sParamDefault ;sParamValueRange ;sParamValue ;sParamRemark ;}STBaseParam operator(STBaseParam pInfo){this-nParamClassify pInfo.nParamClassify;this-sParamName pInfo.sParamName;this-sParamLabel pInfo.sParamLabel;this-sParamTip pInfo.sParamTip;this-nParamType pInfo.nParamType;this-sParamDefault pInfo.sParamDefault;this-sParamValueRange pInfo.sParamValueRange;this-sParamValue pInfo.sParamValue;this-sParamRemark pInfo.sParamRemark;return (*this);}friend QDataStream operator (QDataStream output, const STBaseParam Obj){output Obj.nParamClassify;if (Obj.sParamName ) output QString(NULL);else output Obj.sParamName;if (Obj.sParamLabel ) output QString(NULL);else output Obj.sParamLabel;if (Obj.sParamTip ) output QString(NULL);else output Obj.sParamTip;output Obj.nParamType;if (Obj.sParamDefault ) output QString(NULL);else output Obj.sParamDefault;if (Obj.sParamValueRange ) output QString(NULL);else output Obj.sParamValueRange;if (Obj.sParamValue ) output QString(NULL);else output Obj.sParamValue;if (Obj.sParamRemark ) output QString(NULL);else output Obj.sParamRemark;return output;}friend QDataStream operator (QDataStream input, STBaseParam Obj){input Obj.nParamClassify;input Obj.sParamName;if (Obj.sParamName NULL) Obj.sParamName ;input Obj.sParamLabel;if (Obj.sParamLabel NULL) Obj.sParamLabel ;input Obj.sParamTip;if (Obj.sParamTip NULL) Obj.sParamTip ;input Obj.nParamType;input Obj.sParamDefault;if (Obj.sParamDefault NULL) Obj.sParamDefault ;input Obj.sParamValueRange;if (Obj.sParamValueRange NULL) Obj.sParamValueRange ;input Obj.sParamValue;if (Obj.sParamValue NULL) Obj.sParamValue ;input Obj.sParamRemark;if (Obj.sParamRemark NULL) Obj.sParamRemark ;return input;}int nParamClassify; //参数类别(1过程参数2结果参数3调试参数)QString sParamName; //参数名字QString sParamLabel; //参数在界面显示的中文名字QString sParamTip; //参数在界面的提示的说明文本//参数类型(0int1double2QString3bool4combobox;//5 flag6 point(x, y)7 矩形(row1, col1, row2, col2)//8 旋转矩形(row, col, phi, lenth1, length2)9 size(width, height)//10 按钮11 颜色选择对话框color(r, g, b, a); 12 字体选择对话框font 13 选择文件对话框 14 选择文件夹对话框)int nParamType;QString sParamDefault; //参数默认值QString sParamValueRange; //参数的取值范围(0%%255%%1最小值为0最大值为255每次增加1)QString sParamValue; //参数值QString sParamRemark; //参数的备注 }; 2.在你自己工程的界面中拖入一个QTableView控件将其提升为DBTableParamView.h 3.Test_TableView.h #pragma once#include QtWidgets/QWidget #include ui_Test_TableView.h#include DBHeader.h#pragma execution_character_set(utf-8) class Test_TableView : public QWidget {Q_OBJECTpublic:Test_TableView(QWidget *parent Q_NULLPTR);~Test_TableView();protected:void closeEvent(QCloseEvent* event);private:void InitWidget();void InitConnection();private:void ParamValueChanged(QString sParamName, QString sParamValue);private:QVectorSTBaseParam* Vect_BaseParam;private:Ui::Test_TableViewClass ui; }; 4.Test_TableView.cpp #include Test_TableView.h #include QDebug #include QMessageBoxTest_TableView::Test_TableView(QWidget *parent): QWidget(parent) {ui.setupUi(this);InitWidget();InitConnection(); }Test_TableView::~Test_TableView() {}void Test_TableView::closeEvent(QCloseEvent* event) {//exit(0); }void Test_TableView::InitWidget() {//int型SpinBox控件STBaseParam* pBase1 new STBaseParam;pBase1-nParamClassify 1;pBase1-nParamType 0;pBase1-sParamName Param1;pBase1-sParamLabel 参数1;pBase1-sParamTip 这是参数1;pBase1-sParamDefault 12;pBase1-sParamValueRange 1%%100%1;pBase1-sParamValue 15;pBase1-sParamRemark 最小值是1最大值是100默认值是12;Vect_BaseParam.push_back(pBase1);//double型SpinBox控件STBaseParam* pBase2 new STBaseParam;pBase2-nParamClassify 1;pBase2-nParamType 1;pBase2-sParamName Param2;pBase2-sParamLabel 参数2;pBase2-sParamTip 这是参数2;pBase2-sParamDefault 2.5;pBase2-sParamValueRange 1%%100%%0.5;pBase2-sParamValue 15.6;pBase2-sParamRemark 最小值是1最大值是100默认值是2.5;Vect_BaseParam.push_back(pBase2);//TextEdit型控件STBaseParam* pBase3 new STBaseParam;pBase3-nParamClassify 1;pBase3-nParamType 2;pBase3-sParamName Param3;pBase3-sParamLabel 参数3;pBase3-sParamTip 这是参数3;pBase3-sParamDefault dongbin;pBase3-sParamValueRange ;pBase3-sParamValue dongbin123;pBase3-sParamRemark 请输入名字,默认值是dongbin;Vect_BaseParam.push_back(pBase3);//CheckBox型控件STBaseParam* pBase4 new STBaseParam;pBase4-nParamClassify 1;pBase4-nParamType 3;pBase4-sParamName Param4;pBase4-sParamLabel 参数4;pBase4-sParamTip 这是参数4;pBase4-sParamDefault 1;pBase4-sParamValueRange 是否选择信息;pBase4-sParamValue 0;pBase4-sParamRemark true 运行 false 不运行 默认值:true;Vect_BaseParam.push_back(pBase4);//ComboBox型控件STBaseParam* pBase5 new STBaseParam;pBase5-nParamClassify 1;pBase5-nParamType 4;pBase5-sParamName Param5;pBase5-sParamLabel 参数5;pBase5-sParamTip 这是参数5;pBase5-sParamDefault Name;pBase5-sParamValueRange Name,Age,City,Other;pBase5-sParamValue City;pBase5-sParamRemark 选择相关信息默认值是Name;Vect_BaseParam.push_back(pBase5);//多个CheckBox型控件STBaseParam* pBase6 new STBaseParam;pBase6-nParamClassify 1;pBase6-nParamType 5;pBase6-sParamName Param6;pBase6-sParamLabel 参数6;pBase6-sParamTip 这是参数6;pBase6-sParamDefault 0,0,0,0;pBase6-sParamValueRange Flag1,Flag2,Flag3,Flag4;pBase6-sParamValue 0,1,0,1;pBase6-sParamRemark 设置每个Falg的状态默认值是Flag1falseFlag2falseFlag3falseFlag4false;Vect_BaseParam.push_back(pBase6);//点数据控件STBaseParam* pBase7 new STBaseParam;pBase7-nParamClassify 1;pBase7-nParamType 6;pBase7-sParamName Param7;pBase7-sParamLabel 参数7;pBase7-sParamTip 这是参数7;pBase7-sParamDefault 10,20;pBase7-sParamValueRange ;pBase7-sParamValue 30,40;pBase7-sParamRemark 设置点的坐标(X,Y)默认值是(10,20);Vect_BaseParam.push_back(pBase7);//矩形1数据控件STBaseParam* pBase8 new STBaseParam;pBase8-nParamClassify 1;pBase8-nParamType 7;pBase8-sParamName Param8;pBase8-sParamLabel 参数8;pBase8-sParamTip 这是参数8;pBase8-sParamDefault 10,20,30,40;pBase8-sParamValueRange ;pBase8-sParamValue 50,60,70,80;pBase8-sParamRemark 设置矩形1的坐标(Row1,Col1,Row2,Col2)默认值是(10,20,30,40);Vect_BaseParam.push_back(pBase8);//旋转矩形2数据控件STBaseParam* pBase9 new STBaseParam;pBase9-nParamClassify 1;pBase9-nParamType 8;pBase9-sParamName Param9;pBase9-sParamLabel 参数9;pBase9-sParamTip 这是参数9;pBase9-sParamDefault 10,20,0,30,40;pBase9-sParamValueRange ;pBase9-sParamValue 50,60,1.32007,70,80;pBase9-sParamRemark 设置矩形1的坐标(Row,Col,Phi,Length1,Length2)默认值是(10,20,0,30,40);Vect_BaseParam.push_back(pBase9);//尺寸数据控件STBaseParam* pBase10 new STBaseParam;pBase10-nParamClassify 1;pBase10-nParamType 9;pBase10-sParamName Param10;pBase10-sParamLabel 参数10;pBase10-sParamTip 这是参数10;pBase10-sParamDefault 10,20;pBase10-sParamValueRange ;pBase10-sParamValue 30,40;pBase10-sParamRemark 设置尺寸的大小(Width,Height)默认值是(10,20);Vect_BaseParam.push_back(pBase10);//按钮控件STBaseParam* pBase11 new STBaseParam;pBase11-nParamClassify 1;pBase11-nParamType 10;pBase11-sParamName Param11;pBase11-sParamLabel 参数11;pBase11-sParamTip 这是参数11;pBase11-sParamDefault ;pBase11-sParamValueRange ;pBase11-sParamValue 调试程序;pBase11-sParamRemark 按下按钮开始调试程序;Vect_BaseParam.push_back(pBase11);//选择颜色对话框控件STBaseParam* pBase12 new STBaseParam;pBase12-nParamClassify 1;pBase12-nParamType 11;pBase12-sParamName Param12;pBase12-sParamLabel 参数12;pBase12-sParamTip 这是参数12;pBase12-sParamDefault 200,200,200,100; //r,g,b,apBase12-sParamValueRange ;pBase12-sParamValue 255,255,255,200;pBase12-sParamRemark 选择颜色对话框(R,G,B,A)默认值是rgba(200,200,200,100);Vect_BaseParam.push_back(pBase12);//选择字体对话框控件STBaseParam* pBase13 new STBaseParam;pBase13-nParamClassify 1;pBase13-nParamType 12;pBase13-sParamName Param13;pBase13-sParamLabel 参数13;pBase13-sParamTip 这是参数13;pBase13-sParamDefault 宋体,-1,-1,0;pBase13-sParamValueRange ;pBase13-sParamValue 宋体,12,12,0;pBase13-sParamRemark 选择字体对话框(family,pointSize,weight,italic)默认值是rgba(宋体,-1,-1,0);Vect_BaseParam.push_back(pBase13);//选择文件路径对话框控件STBaseParam* pBase14 new STBaseParam;pBase14-nParamClassify 1;pBase14-nParamType 13;pBase14-sParamName Param14;pBase14-sParamLabel 参数14;pBase14-sParamTip 这是参数14;pBase14-sParamDefault D:\\test.txt;pBase14-sParamValueRange ;pBase14-sParamValue ;pBase14-sParamRemark 选择文件路径对话框(文件路径)默认值是D:\\test.txt;Vect_BaseParam.push_back(pBase14);//选择文件夹路径对话框控件STBaseParam* pBase15 new STBaseParam;pBase15-nParamClassify 1;pBase15-nParamType 14;pBase15-sParamName Param15;pBase15-sParamLabel 参数15;pBase15-sParamTip 这是参数15;pBase15-sParamDefault D:\\test;pBase15-sParamValueRange ;pBase15-sParamValue ;pBase15-sParamRemark 选择文件夹路径对话框(文件夹路径)默认值是D:\\test;Vect_BaseParam.push_back(pBase15);ui.tableView-InitTableParamView(Vect_BaseParam); }void Test_TableView::InitConnection() {ui.tableView-RegisterCallbackParamValueChanged(std::bind(Test_TableView::ParamValueChanged, this, std::placeholders::_1, std::placeholders::_2)); }void Test_TableView::ParamValueChanged(QString sParamName, QString sParamValue) {qDebug() ParamName sParamName ParamValue sParamValue;if (sParamName QString(Param11)){QMessageBox::information(this, QString(提示), QString(按钮按下));} } Chapter4 QT实现一个系统参数管理窗口 原文链接https://blog.csdn.net/zkmrobot/article/details/140962984 为了实现一个管理系统参数的设计我们可以创建一个配置参数类来封装配置的读取和写入操作并使用一个 QWidget 作为用户界面来管理这些参数。以下是如何设计一个这样的系统包括配置参数类和管理界面。 1. 配置参数类 我们创建一个 ConfigManager 类来处理配置的读取和写入。这将使得参数管理与用户界面分离方便维护和扩展。 #include QSettings #include QStringclass ConfigManager { public:ConfigManager(const QString organization, const QString application): settings(organization, application) {}QString getServerAddress() const {return settings.value(serverAddress, ).toString();}void setServerAddress(const QString address) {settings.setValue(serverAddress, address);}QString getPort() const {return settings.value(port, ).toString();}void setPort(const QString port) {settings.setValue(port, port);}bool isLoggingEnabled() const {return settings.value(enableLogging, false).toBool();}void setLoggingEnabled(bool enabled) {settings.setValue(enableLogging, enabled);}private:QSettings settings; };2. 管理界面 QWidget 接下来我们创建一个 ConfigWidget 类来提供用户界面使用 ConfigManager 类来管理和存储配置参数。 #include QWidget #include QPushButton #include QLabel #include QLineEdit #include QCheckBox #include QVBoxLayout #include QHBoxLayout #include QFormLayout #include QMessageBox#include ConfigManager.hclass ConfigWidget : public QWidget {Q_OBJECTpublic:ConfigWidget(ConfigManager *configManager, QWidget *parent nullptr): QWidget(parent), configManager(configManager) {// 创建控件QLabel *label1 new QLabel(Server Address:, this);QLabel *label2 new QLabel(Port:, this);QLabel *label3 new QLabel(Enable Logging:, this);serverAddressEdit new QLineEdit(this);portEdit new QLineEdit(this);enableLoggingCheckBox new QCheckBox(this);QPushButton *saveButton new QPushButton(Save, this);QPushButton *cancelButton new QPushButton(Cancel, this);// 设置布局QFormLayout *formLayout new QFormLayout;formLayout-addRow(label1, serverAddressEdit);formLayout-addRow(label2, portEdit);formLayout-addRow(label3, enableLoggingCheckBox);QHBoxLayout *buttonLayout new QHBoxLayout;buttonLayout-addWidget(saveButton);buttonLayout-addWidget(cancelButton);QVBoxLayout *mainLayout new QVBoxLayout(this);mainLayout-addLayout(formLayout);mainLayout-addLayout(buttonLayout);setLayout(mainLayout);// 连接信号和槽connect(saveButton, QPushButton::clicked, this, ConfigWidget::handleSaveButton);connect(cancelButton, QPushButton::clicked, this, ConfigWidget::handleCancelButton);// 读取设置readSettings();}private slots:void handleSaveButton() {// 保存设置configManager-setServerAddress(serverAddressEdit-text());configManager-setPort(portEdit-text());configManager-setLoggingEnabled(enableLoggingCheckBox-isChecked());QMessageBox::information(this, Configuration Saved, Settings have been saved.);}void handleCancelButton() {// 关闭窗口close();}private:void readSettings() {// 读取设置serverAddressEdit-setText(configManager-getServerAddress());portEdit-setText(configManager-getPort());enableLoggingCheckBox-setChecked(configManager-isLoggingEnabled());}ConfigManager *configManager;QLineEdit *serverAddressEdit;QLineEdit *portEdit;QCheckBox *enableLoggingCheckBox; };3. 主程序 最后我们创建主程序来初始化 ConfigManager 并显示 ConfigWidget。 #include QApplication #include ConfigWidget.h #include ConfigManager.hint main(int argc, char *argv[]) {QApplication app(argc, argv);ConfigManager configManager(MyCompany, MyApp);ConfigWidget configWidget(configManager);configWidget.setWindowTitle(System Configuration);configWidget.resize(300, 200);configWidget.show();return app.exec(); }代码说明 1. ConfigManager 类: 封装了读取和写入配置参数的逻辑。使用 QSettings 来管理配置的持久化。 提供了方法来获取和设置服务器地址、端口和日志记录状态。 2. ConfigWidget 类: 提供了一个用户界面来显示和修改配置参数。 使用 ConfigManager 类来读取和保存设置。 在窗口加载时从 ConfigManager 读取设置并在用户点击保存按钮时将设置写回 ConfigManager。 3. 主程序: 初始化 QApplication 实例和 ConfigManager 实例。 创建 ConfigWidget 实例并将 ConfigManager 传递给它。 显示配置窗口。 Chapter5 Qt平台自动化项目开发基础框架 原文链接https://blog.csdn.net/lg_cool_/article/details/143451103 一、程序框架结构 主函数代码 #include mainwindow.h #include logindialog.h #include QApplication #include QIconint main(int argc, char *argv[]) {QApplication a(argc, argv);logindialog loginDialog;loginDialog.setWindowIcon(QIcon(D:/Project/auto_calibrate_device/haptron.ico)); // 使用资源文件中的图标if (loginDialog.exec() QDialog::Accepted){MainWindow w;w.setWindowIcon(QIcon(D:/Project/auto_calibrate_device/haptron.ico)); // 使用资源文件中的图标w.show();return a.exec();}return 0; }二、GUI界面开发 1登录界面 登录界面代码 #include logindialog.h #include QMessageBox #include ui_logindialog.hlogindialog::logindialog(QWidget *parent):QDialog(parent),ui(new Ui::logindialog) {ui-setupUi(this); } logindialog::~logindialog() {delete ui; } void logindialog::on_m_Login_Btn_clicked() {if (ui - m_UserName_LineEdit-text() admin ui - m_Password_LineEdit-text() admin){this-accept(); // Close the dialog}else{QMessageBox::information(this, 提示, Invalid username or password);} } void logindialog::on_m_Cancel_Btn_clicked() {this-close(); }2主界面 主界面代码 在主界面中创建了主控制线程对象pcontrolThreadnew controlThread;同时在主控制线程中创建了Qwidget对象controlCenterWidget[index]new Widget;以下为大致代码结构 #include mainwindow.h #include ui_mainwindow.h #include widget.h #include message_log.h #include QMessageBox #include QCheckBox #include QVectorMainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow) {ui-setupUi(this);qInstallMessageHandler(recordMessage); //注册日志函数for (int i 0; i 4; i){controlCenterWidget[i] nullptr; //初始化为nullptr}pcontrolThreadnew controlThread;connect(pcontrolThread,SIGNAL(send_signal(QString)),this,SLOT(recv_string(QString))); //处理接收到的信号}MainWindow::~MainWindow() {} //点击启动按钮 void MainWindow::on_startButton_clicked() {QVectorQCheckBox* checkBoxVector; // 使用QVector存储QCheckBox指针checkBoxVector.append(ui-QCheck_calibrate_1);checkBoxVector.append(ui-QCheck_calibrate_2);checkBoxVector.append(ui-QCheck_calibrate_3);checkBoxVector.append(ui-QCheck_calibrate_4);// 读取复选框的状态for(int i0;i4;i){Qt::CheckState state checkBoxVector[i]-checkState();switch (state){case Qt::Unchecked://qDebug() Checkbox is unchecked;break;case Qt::PartiallyChecked://qDebug() Checkbox is partially checked;break;case Qt::Checked:pcontrolThread-runflag[i]stop;pcontrolThread-weightNoLimit_Start[i]comboBoxVector_Start[i]-currentIndex();pcontrolThread-weightNoLimit_End[i]comboBoxVector_End[i]-currentIndex();sta_weigthcomboBoxVector_Start[i]-currentIndex();end_weigthcomboBoxVector_End[i]-currentIndex();crr_weigthsta_weigth;lineEditVector[i]-setText(QString::number(comboBoxVector_Start[i]-currentIndex()*10)N);progressVector[i]-setValue(0); // 设置进度条的当前值为 0break;}}//修改状态显示ui-sys_status_label-setText(运行);ui-sys_status_label-setStyleSheet(QLabel { font-size: 28pt; font-weight: 700; color: #008000; text-align: center; });ui-sys_status_label-setAlignment(Qt::AlignVCenter | Qt::AlignHCenter);// 读取标定砝码的范围pcontrolThread-start(); //启动子线程//间接调用了run()函数//即接收数据 }//点击停止按钮 void MainWindow::on_stopButton_clicked() {pcontrolThread-CloseThread(); //停止线程ui-sys_status_label-setText(停止);ui-sys_status_label-setStyleSheet(QLabel { font-size: 28pt; font-weight: 700; color: #aa0000; text-align: center; });ui-sys_status_label-setAlignment(Qt::AlignVCenter | Qt::AlignHCenter); }//点击控制中心1按钮 void MainWindow::on_ControlCenterButton_1_clicked() {OpenControlCenterWindow(0); }//打开控制中心界面 void MainWindow::OpenControlCenterWindow(int index) {if (!controlCenterWidget[index]){controlCenterWidget[index]new Widget;controlCenterWidget[index]-setWindowTitle(控制中心QString::number(index1));controlCenterWidget[index]-setWindowIcon(QIcon(D:/Project/auto_calibrate_device/haptron.ico));controlCenterWidget[index]-show(); // 显示新窗口}else{controlCenterWidget[index]-close();controlCenterWidget[index]-setWindowIcon(QIcon(D:/Project/auto_calibrate_device/haptron.ico));controlCenterWidget[index]-show(); // 显示新窗口}controlCenterWidget[index]-widget_Idindex; }如何从mainwindow窗口中调用其他窗口中的控件呢 controlCenterWidget是一个Qwidget类指针。 // 使用findChild来查找QTabWidgetQTabWidget *tabWidget controlCenterWidget[index]-findChildQTabWidget*(tabWidget);if (tabWidget){// 如果找到了QTabWidget设置当前标签页为第一个tabWidget-setCurrentIndex(0);}else{// 没有找到QTabWidget可以输出错误信息或者进行其他处理qDebug() QTabWidget not found!;}3手动控制界面Qwidget 手动控制界面代码 手动控制界面有可能被打开多个因此手动控制界面有一个专属的界面id,以区别是被谁打开的。 在mainWindow.cpp中打开Qwidget窗口的部分代码 //打开控制中心界面 void MainWindow::OpenControlCenterWindow(int index) {if (!controlCenterWidget[index]){controlCenterWidget[index]new Widget;controlCenterWidget[index]-show(); // 显示新窗口}else{controlCenterWidget[index]-close();controlCenterWidget[index]-setWindowIcon(QIcon(D:/Project/auto_calibrate_device/haptron.ico));controlCenterWidget[index]-show(); // 显示新窗口}controlCenterWidget[index]-widget_Idindex;//打开窗口后给窗口设定一个唯一的id值 }在widget.cpp中主要完成一些手动控制逻辑直接调用.dll库中的驱动接口。 #include widget.h #include ui_widget.hWidget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui-setupUi(this);sharedData new SharedData; //创建类对象sharedDatamotorControl nullptr; //初始化为nullptrwidget_Id0; } Widget::~Widget() { } void Widget::on_Button_connect_clicked() {qDebug()widget_Id1#点击连接;motorControl new Thread(sharedData,widget_Id); //创建类对象motorControlThreadif (motorControl-connect()true) //打开通道{ui-label_mark-setStyleSheet(QLabel {border: 1px solid black; border-radius: 12px;background-color: green;});qDebug()widget_Id1#控制中心标定台电机连接成功;}else{delete motorControl; // 如果连接失败释放资源motorControl nullptr;} } void Widget::on_Button_home_clicked() {qDebug()widget_Id1#点击回零;if (motorControl){QMessageBox::information(this, 提示, 确认安全后点击“确定”开始回零请等待回零完成!);else{QMessageBox::information(this, 提示, 回零异常请检查后再次尝试回零!);}}else{QMessageBox::information(this, 提示, 请先建立连接!);delete motorControl;motorControl nullptr;} } void Widget::on_Button_run_clicked() {qDebug()widget_Id1#点击运动;if (motorControl){QString loc_strmove1;QMessageBox::information(this, 提示, 确认安全后点击“确定”开始运动中请等待运动到位!);int loc1ui-comboBox_loc1-currentIndex();int loc2ui-comboBox_loc2-currentIndex();}else{QMessageBox::information(this, 提示, 请先建立连接!);delete motorControl;motorControl nullptr;} } void Widget::on_Button_recv_sensor_clicked() {qDebug()widget_Id1#采集数据; }三、主控制线程 主控制线程主要负责调度外设的运行逻辑。 1多线程之间的数据共享 共享数据类代码ShareData.h #ifndef SHAREDDATA_H #define SHAREDDATA_H #include QMutex #include QMutexLocker #include QWaitCondition #include QQueue #include QDebug #include QThread // 共享数据类用于在线程间共享数据和同步 class SharedData { public:SharedData() : dataReady(false) {}QMutex mutex; // 互斥锁用于保护共享数据QWaitCondition condition; // 条件变量用于线程间的通知bool dataReady; // 标志指示数据是否准备好QQueueQString queue; // 用于存储数据的队列QQueueQString queue_1; // 用于存储数据的队列(接收消费者的信息)// 通知消费者线程生产者已经放入数据void wake(){QMutexLocker locker(mutex); // 锁定互斥锁if (!queue.isEmpty()){//qDebug() Data available, waking consumers!;dataReady true; // 标记数据准备好condition.wakeAll(); // 唤醒所有等待的消费者线程}else{//qDebug()queue.isEmpty;return;}}// 等待生产者线程放入数据void wait_data(){QMutexLocker locker(mutex); // 锁定互斥锁while (!dataReady) //如果数据已经准备好则无需等待{//让当前线程等待挂起直到某个条件满足同时释放与之关联的互斥锁QMutex允许其他线程进入临界区并可能改变条件状态condition.wait(mutex); // 如果数据未准备好等待生产者线程的通知由condition.wakeAll()或condition.wakeOne()触发}dataReady false; // 重置数据准备好标志//qDebug()wait Data available!;} }; #endif // SHAREDDATA_H2主控制逻辑 为每个模块创建一个控制流程类负责数据的交互与运行状态的记录 centrial_control.hpp(motorAuto_run类主要负责电机模组模块的运行状态记录以及数据收发) #ifndef CENTRIAL_CONTROL_H #define CENTRIAL_CONTROL_H#include QThread class motorAuto_run; //控制流程类 class controlThread : public QThread //用户自定义的类 {Q_OBJECT public:controlThread(); //构造函数//初始化变量~controlThread(); protected://QThread类的虚函数//就是子线程处理函数void run();//子线程处理函数//不能直接调用该函数//只能通过start间接调用private:bool abb_Enablefalse;SharedData *sharedData[4]; // 创建共享数据指针Thread *motorControlThread[4]; //定义类指针数组SharedData *abbsharedData; signals:void send_calibrateF(const QString data); // 用于传递数据到MainWindow private slots:void recv_motor_canF(const QString data){emit send_calibrateF(data); // 将接收到的数据通过controlThread传递给MainWindow} };//控制流程类 class motorAuto_run { public:motorAuto_run(SharedData *sharedData) :sharedData(sharedData){}int sendstep; //发送字符串步骤标志位int recvstep; //接收字符串步骤标志位int weight_No; //砝码编号1~10void send_data(QString str){{QMutexLocker locker(sharedData-mutex); // 锁定共享数据sharedData-queue.enqueue(str); // 生产数据放入队列}sharedData-wake(); // 通知消费者线程}QString recv_data(){QString str;QMutexLocker locker(sharedData-mutex); //锁定共享数据if (!sharedData-queue_1.isEmpty()){str sharedData-queue_1.dequeue(); // 取出数据}return str;} private:SharedData *sharedData; // 创建共享数据指针 }; #endif // CENTRIAL_CONTROL_Hcentrial_control.cpp #include centrial_control.hpp #include QThread #include QMessageBox #include QWidget controlThread::controlThread() //构造函数//初始化变量 {for(int i0;i4;i){sharedData[i] new SharedData; //创建类对象sharedDatamotorControlThread[i] new Thread(sharedData[i],i); //创建类对象motorControlThreadconnect(motorControlThread[i], Thread::send_motor_canF, this, controlThread::recv_motor_canF); // 连接信号和槽}abbsharedDatanew SharedData;abbnew SocketClient(abbsharedData);for(int i0;i4;i){motorAction[i]new motorAuto_run(sharedData[i]); //创建对象} } controlThread::~controlThread() { for(int i0;i4;i){motorAction[i]-send_data(stop);delete sharedData[i];delete motorControlThread[i];}abbsend_data(stop);delete abbsharedData;delete abb;for(int i0;i4;i){delete motorAction[i];} } void controlThread::run() //controlThread-start 间接调用该函数 {while(!stopped)//死循环//{for(int i0;i4;i){if(runflag[i]running){if(DebugSendstep[i]!motorAction[i]-sendstep){qDebug()i1#motorAction_sendstepmotorAction[i]-sendstep;DebugSendstep[i]motorAction[i]-sendstep;}//step1 查询当前状态 停止 or 运动中if(motorAction[i]-sendstep1 motorAction[i]-recvstep!1){QString task_name status_ QString::number(i1);motorAction[i]-send_data(task_name);motorAction[i]-recvstep1;}//step2 查询当前位置else if(motorAction[i]-sendstep2 motorAction[i]-recvstep!2){QString task_name encoderValue_ QString::number(i1);motorAction[i]-send_data(task_name);motorAction[i]-recvstep2;}}}sleep(1);//接收执行结果for(int i0;i4;i){if(runflag[i]running){if(DebugRecvstep[i]!motorAction[i]-recvstep){qDebug()i1#motorAction_recvstepmotorAction[i]-recvstep;DebugRecvstep[i]motorAction[i]-recvstep;}if(motorAction[i]-recvstep1) //step1 查询当前状态{QString resultmotorAction[i]-recv_data();if(result!){qDebug()i1#result;checkStatus(result,i); //检查当前电机状态并跳转流程步骤}}else if(motorAction[i]-recvstep2) //step2 查询当前位置{QString resultmotorAction[i]-recv_data();if(result!){qDebug()i1#result;checkEncoderValue(result,i,0,0); //检查当前电机位置并跳转流程步骤}}}}} } 四、外设模块线程 外设模块主要的任务是实现与主控制线程的数据传输以及自身的任务执行。 motor_can.hpp:(Thread(SharedData *sharedData,int devind);共享数据在主控制线程中创建new,指向共享数据的指针被传递到外设模块的线程中) #ifndef MOTOR_CAN_HPP #define MOTOR_CAN_HPP #include QThread #include lib/ECanVci.h #include vector #include SharedData.h #include QDateTime #include QDir #include CLibModBus.h #define LibECanVci ECanVci //定义宏LibECanVci class Thread : public QThread //用户自定义的类 {Q_OBJECT public:QString task_name ;Thread(SharedData *sharedData,int devind); //构造函数//初始化变量~Thread(); public:typedef DWORD(__stdcall SetReference)(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,DWORD RefType,PVOID pData);typedef DWORD(__stdcall ReadBoardInfo)(DWORD DeviceType,DWORD DeviceInd,P_BOARD_INFO pInfo);int devtype8; //设备类型号// protected://QThread类的虚函数//就是子线程处理函数void run();//子线程处理函数//不能直接调用该函数//只能通过start间接调用 private:SharedData *sharedData; // 创建共享数据指针CLibModBus *sensor;QString VoltageList;QString AverageList; signals:void send_motor_canF(const QString str); //自定义信号函数用于传递数据到controlThread }; #endif // MOTOR_CAN_HPPmotor_can.cpp采用线程同步的方式接收数据【队列queue】执行任务后返回执行结果【队列queue_1】 #include motor_can.hpp #include QThreadThread::Thread(SharedData *sharedData,int devind) //构造函数//初始化变量:devind(devind),sharedData(sharedData) //连接共享数据指针 {//this-sharedDatasharedData; //连接共享数据指针QLibrary lib(ECanVci64.dll);if(truelib.load()){qDebug()devind1#ECanVci.dll load ok;}else{qDebug()devind1#ECanVci.dll load error;} } void Thread::run() //QThread-start 间接调用该函数 {if (Thread::OpenCANThread(mbaud)true) //打开通道{while(!stopped)//死循环//{sharedData-wait_data(); // 等待生产者线程放入数据//获取共享数据设定锁的范围{QMutexLocker locker(sharedData-mutex); //锁定共享数据if (!sharedData-queue.isEmpty()){task_name sharedData-queue.dequeue(); // 取出数据}}qDebug()devind1#task_nametask_name; //task_name calibrate_4_0N calibrate:标定流程 4:第四个工位 0N:空载标定if(this-task_name stop){CloseCANThread(); //关闭设备stop(); //停止子线程}//执行非标定任务else if (this-task_name ! !this-task_name.contains(calibrate)){QString task_returnexecuteTask(task_name);//返回关节模组执行结果给控制逻辑{QMutexLocker locker(sharedData-mutex); // 锁定共享数据sharedData-queue_1.enqueue(task_return); // 生产数据放入队列}}//执行标定流程else if(this-task_name.trimmed().section(_,0,0) calibrate){//标定数据采集位置定义std::vectorQString task_move {move1_,move3_,move4_,move5_,move6_,move7_,move8_,move9_,move2_,move10_};//标定过程中生成的文件名格式:标定台砝码位置重量电机位置QString file_titletask_name.trimmed().section(_,1,1)C_task_name.trimmed().section(_,2,2);//file_title4C_10N 4:标定台号 C:砝码在标定台中间位置 10N:当前标定砝码重量calibrateProcess(task_move, file_title);}this-task_name;sleep(5);}stopped false;}else{CloseCANThread();stop(); //停止子线程} }五、日志 1)头文件 在recordMessage函数中设置了日志的命名格式代码中可采用qDebug()输出记录信息例如 执行 qDebug()“motor1#load ok”; 语句#号前面的字符串将会生成 ”log_motor1当前日期“ 文件且#号前面的字符串会生成日志信息为 ”load ok“ 。 #ifndef MESSAGE_LOG_H #define MESSAGE_LOG_H#include QApplication #include QtDebug #include QFile #include QTextStream #include QDebug #include QDateTime #include QMutex #include QString #include qapplication.h #include QMessageBox #include QDirvoid recordMessage(QtMsgType type, const QMessageLogContext context, const QString msg) {// 加锁static QMutex mutex;mutex.lock();QString text;switch(type){case QtDebugMsg:text QString(Debug:);break;case QtWarningMsg:text QString(Warning:);break;case QtCriticalMsg:text QString(Critical:);break;case QtFatalMsg:text QString(Fatal:);break;default:break;}// 设置输出信息格式//QString context_info QString(File:(%1) Line:(%2)).arg(QString(context.file)).arg(context.line);QString current_date_time QDateTime::currentDateTime().toString(yyyy-MM-dd hh:mm:ss );QString current_date QString((%1)).arg(current_date_time);//QString message QString(%1 %2 %3 %4).arg(text).arg(context_info).arg(msg).arg(current_date);QString message QString(%1 : %2).arg(current_date).arg(msg);// 提取日志消息中的标识符假设它位于第一个#前的字符串QString LogIdentifier msg.section(#, 0, 0).trimmed();if(LogIdentifier.size()10 || !msg.contains(#)){LogIdentifierundefine;}// 输出信息至文件中读写、追加形式QString logFilePathD:/Project/auto_calibrate_device/log;QDir logDir(logFilePath); //初始化logdir目录if (!logDir.exists()) //如果log文件夹不存在{logDir.mkpath(.); //创建文件夹}QString logFileNamelog_LogIdentifier_QDateTime::currentDateTime().toString(yyyy-MM-dd ).txt;logFilePath /;logFilePath logFileName;QFile file(logFilePath);file.open(QIODevice::WriteOnly | QIODevice::Append);QTextStream text_stream(file);text_stream message \r\n;file.flush();file.close();// 解锁mutex.unlock(); }#endif // MESSAGE_LOG_H2调用方法 调用qInstallMessageHandler(recordMessage); //注册日志函数 #include message_log.hMainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow) {ui-setupUi(this);qInstallMessageHandler(recordMessage); //注册日志函数//输出信息到指定文件文件名为log_mainWindowlog日期日志信息为log load okqDebug()mainWindowlog#log load ok; }
http://www.dnsts.com.cn/news/133759.html

相关文章:

  • 织梦网站后台怎么登陆网上做公司网站怎么做
  • 网站建设存在的具体问题小程序 wordpress api
  • 做网站 网络映射在线医疗 网站建设
  • 网站图片加水印网页模板免费网址
  • 在线网站建设教程北京网页设计公司兴田德润优秀
  • 商城网站建设步骤hoperun企业邮箱
  • 有哪些网站开发公司android开发是做什么的
  • 网站建设的毕业设计网页制作与网站建设技术大全 下载
  • 网站建设拾金手指下拉二十网站域名的作用是什么意思
  • 网站建设网站源码丽江网站开发找千素网
  • 装修网站平台推荐阿里万网域名注册官网
  • 网站建设及政务工作自查做域名交易网站
  • 受欢迎的网站建设案例叶榭做网站
  • 网站建设和网站开发的区别python 做下载网站
  • 电影网站怎么制作网站内容协议
  • 公司禁用网站怎么做景德镇市场建设局网站
  • 网站分析步骤优对 网站开发
  • 网站和网页的关系白石洲附近做网站公司
  • 南京尘帆网站建设管理咨询公司注册要求
  • 网站报名照片怎么做做短裙的视频网站
  • 100m网站空间服务费网站建设服务合同模板
  • 网站模板制作与安装教程jsp网站服务建设是什么
  • 网站建设数据库软件英文网站后角色管理权限怎么设置?
  • 局域网做网站 内网穿透推广网站平台免费
  • 致设计网站官网网站竞价推广哪个好
  • dedecms 网站安全设置专业做网站建设公司有哪些
  • 不用ftp做网站app页面设计软件
  • 焦作 做 网站黄骅贴吧二手房
  • 龙之向导全球贸易优化公司怎么优化网站的
  • 建立站点的作用wordpress 连接池