Files
EJM_Display/PublicFunctions/Basic.cpp

272 lines
9.1 KiB
C++
Raw Permalink Normal View History

2025-08-20 23:06:28 +08:00
#include "Basic.h"
2025-10-16 17:40:00 +08:00
#include <QColor>
2025-10-10 23:10:21 +08:00
2025-08-20 23:06:28 +08:00
/**
* @brief map ,x的值,out_min到out_max的范围内
* @param x
* @param in_min x有可能的最小值
* @param in_max x有可能的最大值
* @param out_min
* @param out_max
* @return
*/
M_d64 map(M_d64 x, M_d64 in_min, M_d64 in_max, M_d64 out_min, M_d64 out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
2025-10-10 23:10:21 +08:00
/**
* @brief Sleep_ms 线
* @param msec
*/
2025-10-10 17:44:10 +08:00
void Sleep_ms(M_u16 msec){
2025-08-20 23:06:28 +08:00
QTime _Timer = QTime::currentTime().addMSecs(msec);
while( QTime::currentTime() < _Timer )
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
}
2025-10-10 23:10:21 +08:00
2025-09-15 22:28:43 +08:00
/**
* @brief 32 N
* @param data 32 uint32_t int32_t
* @param bitIndex 0 = /131 = /32
* @param defaultValue false
* @return bool true = 1false = 0
*/
bool getBitOf32Data(uint32_t data, int bitIndex, bool defaultValue)
{
// 1. 边界检查32位数据的索引范围是 0~31超出则返回默认值
if (bitIndex < 0 || bitIndex > 31) {
qWarning() << "[getBitOf32Data] 位索引越界!当前索引:" << bitIndex
<< "允许范围0~31";
return defaultValue;
}
// 2. 位运算核心逻辑:
// - (1U << bitIndex)生成“指定位为1其他位为0”的掩码1U 确保无符号移位,避免符号位问题)
// - (data & 掩码)按位与操作若结果非0说明指定位为1否则为0
return (static_cast<uint32_t>(data) & (1U << bitIndex)) != 0;
}
2025-10-10 23:10:21 +08:00
2025-09-15 22:28:43 +08:00
/**
* @brief 32 N 1
* @param data 32
* @param bitIndex 0 = 31 =
* @return bool true false data
*/
bool setBitOf32Data(uint32_t &data, int bitIndex)
{
if (bitIndex < 0 || bitIndex > 31) {
qWarning().noquote() << "[setBitOf32Data] 位索引越界!索引:" << bitIndex;
return false;
}
data |= (1U << bitIndex); // 置 1
return true;
}
2025-10-10 23:10:21 +08:00
2025-09-15 22:28:43 +08:00
/**
* @brief 32 N 0
* @param data 32
* @param bitIndex 0 = 31 =
* @return bool true false data
*/
bool clearBitOf32Data(uint32_t &data, int bitIndex)
{
if (bitIndex < 0 || bitIndex > 31) {
qWarning().noquote() << "[clearBitOf32Data] 位索引越界!索引:" << bitIndex;
return false;
}
data &= ~(1U << bitIndex); // 清 0
return true;
}
2025-10-10 23:10:21 +08:00
2025-09-15 22:28:43 +08:00
/**
* @brief 32 N
* @param data 32
* @param bitIndex 0 = 31 =
* @param bitValue true = 1false = 0
* @return bool true false data
*/
bool writeBitOf32Data(uint32_t &data, int bitIndex, bool bitValue)
{
return bitValue ? setBitOf32Data(data, bitIndex)
: clearBitOf32Data(data, bitIndex);
}
2025-10-10 23:10:21 +08:00
2025-09-15 22:28:43 +08:00
/**
* @brief QVariant
* @param variant QVariant
* @param decimalDigits2
* @return
*/
QString variantToFormattedString(const QVariant& variant, int decimalDigits) {
// 1. 安全校验:小数位数不能为负数
if (decimalDigits < 0) {
decimalDigits = 0;
}
// 2. 第一步:先将 QVariant 转为原始字符串(不做任何数值格式化)
QString originalStr = variant.toString();
// 处理空字符串情况
if (originalStr.isEmpty()) {
return "";
}
// 3. 第二步:过滤非数字字符串(仅对数字字符串做小数处理)
// 正则匹配:整数(如 "123"、"-456")或浮点数(如 "123.45"、".67"、"89."
QRegExp numRegExp("^-?\\d+(\\.\\d*)?$");
if (!numRegExp.exactMatch(originalStr)) {
return originalStr;
}
// 4. 第三步:判断字符串是否含小数点,按需格式化
if (originalStr.contains('.')) {
// 有小数点:解析为浮点数,保留指定小数位数(四舍五入)
bool ok = false;
double num = originalStr.toDouble(&ok);
if (ok) {
// 用 'f' 格式确保固定小数位数(如 decimalDigits=3 时123.4→123.400
return QString::number(num, 'f', decimalDigits);
} else {
// 极端情况:匹配正则但无法解析(如 ".abc",实际正则已过滤),返回原字符串
return originalStr;
}
} else {
// 无小数点:直接返回原始整数字符串(不受小数位数影响)
return originalStr;
}
}
2025-10-10 23:10:21 +08:00
/**
* uint32_t的8位部分
* @param data 32
* @param index 0=HH(8), 1=HL(8), 2=LH(8), 3=LL(8)
* @return 8
* @throws std::out_of_range 0-3
*/
uint8_t extractUInt32_8BitPart(uint32_t data, uint8_t index) {
switch(index) {
case 0: // HH - 高8位
return (data >> 24) & 0xFF;
case 1: // HL - 次高8位
return (data >> 16) & 0xFF;
case 2: // LH - 次低8位
return (data >> 8) & 0xFF;
case 3: // LL - 低8位
return data & 0xFF;
default:
return 00;
}
}
/**
* uint32_t的16位部分
* @param data 32
* @param index 0=16, 1=16
* @return 16uint16_t类型
* @throws std::out_of_range 0-1
*/
uint16_t extractUInt32_16BitPart(uint32_t data, int index) {
switch(index) {
case 0: // 高16位
return static_cast<uint16_t>((data >> 16) & 0xFFFF);
case 1: // 低16位
return static_cast<uint16_t>(data & 0xFFFF);
default:
return 00;
}
}
2025-10-16 17:40:00 +08:00
/**
* @brief getNodeValue
* @param nodeId
* @return :QVariant
*/
QVariant getNodeValue(const QString &nodeId){
QString mNodeID = nodeId;
if(!mNodeID.contains("ns=6;s=::AsGlobalPV:"))
mNodeID = "ns=6;s=::AsGlobalPV:"+mNodeID;
return gOPC_NodeValue[mNodeID];
}
/**
* @brief getColorStr
* @param Str
* @return
*/
QString getColorStr(QString str)
{
/*
:
color: rgb(255, 0, 0);
color: #ff0000;
:
color: rgb(255, 0, 0);
color: rgb(255, 0, 0)
rgb(255, 0, 0)
rgb(255, 0, 0);
255, 0, 0
255, 0, 0;
color: #ff0000
color: #ff0000;
#ff0000
#ff0000;
ff0000
ff0000;
*/
str = str.trimmed();
/* 1. 先尝试匹配 rgb(r, g, b) 形式 */
static QRegularExpression reRgb(
R"(^\s*(?:color\s*:\s*)?rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\);?\s*$)",
QRegularExpression::CaseInsensitiveOption);
auto match = reRgb.match(str);
if (match.hasMatch()) {
int r = match.captured(1).toInt();
int g = match.captured(2).toInt();
int b = match.captured(3).toInt();
return QString("color: rgb(%1, %2, %3);").arg(r).arg(g).arg(b);
}
/* 2. 再尝试匹配 #hex 或裸 hex 形式 */
static QRegularExpression reHex(
R"(^\s*(?:color\s*:\s*)?(?:#)?([0-9a-f]{6});?\s*$)",
QRegularExpression::CaseInsensitiveOption);
match = reHex.match(str);
if (match.hasMatch()) {
QString hex = match.captured(1).toLower();
return QString("color: #%1;").arg(hex);
}
/* 3. 都不符合,原样返回(或按需返回空串) */
return str;
}
/**
* @brief getColor
* @param str
* @return QColor QColor
*/
QColor getColor(const QString &str)
{
QString s = str.trimmed();
/* 1. rgb(r, g, b) */
static QRegularExpression reRgb(
R"(^\s*(?:color\s*:\s*)?rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\);?\s*$)",
QRegularExpression::CaseInsensitiveOption);
auto m = reRgb.match(s);
if (m.hasMatch()) {
int r = m.captured(1).toInt();
int g = m.captured(2).toInt();
int b = m.captured(3).toInt();
return QColor(r, g, b);
}
2025-10-10 23:10:21 +08:00
2025-10-16 17:40:00 +08:00
/* 2. #RRGGBB 或 RRGGBB */
static QRegularExpression reHex(
R"(^\s*(?:color\s*:\s*)?(?:#)?([0-9a-fA-F]{6});?\s*$)");
m = reHex.match(s);
if (m.hasMatch())
return QColor('#' + m.captured(1)); // QColor 接受 "#ff0000"
/* 3. 解析失败 */
return QColor(); // 无效颜色
}