Utility.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567
  1. 
  2. #pragma once
  3. #include <QString>
  4. #include <QMessageBox>
  5. #include <QMetaEnum>
  6. #include <QThread>
  7. #include <QTime>
  8. #include <QEventLoop>
  9. #include <QTimer>
  10. #include <QApplication>
  11. #include "DataStructure.h"
  12. // 由于类型转换支持需要,增加此头文件
  13. #include "../Common/CameraBaseClass/IBaseCamCommon.h"
  14. #include "../Common/CameraBaseClass/IBaseCamera.h"
  15. ///////////////////////////////////////////////////////////////
  16. // 工具类
  17. class Utility : public QObject
  18. {
  19. Q_OBJECT
  20. Q_ENUM(VALUE_TYPE)
  21. public:
  22. /// <summary>
  23. /// 判断字符串是否是纯数字(正则,正负整数和0)
  24. /// </summary>
  25. static bool isIntString(QString strInput)
  26. {
  27. QRegExp rx("^-?\\d+$");
  28. return rx.exactMatch(strInput);
  29. }
  30. /// <summary>
  31. /// 判断字符串是否是纯数字(正则,正负浮点数和0)
  32. /// </summary>
  33. /// <param name="strInput"></param>
  34. /// <returns></returns>
  35. static bool isFloatString(QString strInput)
  36. {
  37. QRegExp rx("^(\\-|\\+)?\\d+(\\.\\d+)?$");
  38. return rx.exactMatch(strInput);
  39. }
  40. /// <summary>
  41. /// 弹出Messagebox(Critical)
  42. /// </summary>
  43. /// <param name="strInfo"></param>
  44. #define CRITICAL_MESSAGE(x) Utility::VPCriticalMessageBox(x)
  45. static void VPCriticalMessageBox(const QString& strInfo)
  46. {
  47. qWarning() << strInfo;
  48. //QMessageBox::critical(nullptr, ("Visual Plus"), strInfo);
  49. }
  50. /// <summary>
  51. /// 弹出Messagebox(Information)
  52. /// </summary>
  53. /// <param name="strInfo"></param>
  54. #define INFORMATION_MESSAGE(x) Utility::VPInformationMessageBox(x)
  55. static void VPInformationMessageBox(const QString& strInfo)
  56. {
  57. qInfo() << strInfo;
  58. //QMessageBox::information(nullptr, ("Visual Plus"), strInfo);
  59. }
  60. /// <summary>
  61. /// 弹出MessageBox(question)
  62. /// </summary>
  63. /// <param name="strInfo"></param>
  64. #define QUESTION_MESSAGE(x) Utility::VPQuesitonMessageBox(x)
  65. static QMessageBox::StandardButton VPQuesitonMessageBox(const QString& strInfo)
  66. {
  67. return QMessageBox::question(nullptr, ("Visual Plus"), strInfo,
  68. QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
  69. }
  70. /// <summary>
  71. /// 设置控件为错误状态
  72. /// </summary>
  73. /// <param name="pWidget"></param>
  74. static void setControlError(QWidget* pWidget)
  75. {
  76. QPalette palette;
  77. palette.setColor(QPalette::Base, qRgb(255, 199, 206));
  78. pWidget->setPalette(palette);
  79. }
  80. /// <summary>
  81. /// 设置控件为正常状态
  82. /// </summary>
  83. /// <param name="pWidget"></param>
  84. static void setControlNormal(QWidget* pWidget)
  85. {
  86. QPalette palette;
  87. palette.setColor(QPalette::Base, Qt::white);
  88. pWidget->setPalette(palette);
  89. }
  90. /// <summary>
  91. /// 设置控件为正确状态
  92. /// </summary>
  93. /// <param name="pWidget"></param>
  94. static void setControlOK(QWidget* pWidget)
  95. {
  96. QPalette palette;
  97. palette.setColor(QPalette::Base, qRgb(255, 199, 206));
  98. pWidget->setPalette(palette);
  99. }
  100. /// <summary>
  101. /// 根据Type类型返回对应的类型字符串
  102. /// 此处对应DataStructure.h中的 VALUE_TYPE 顺序,要确保双方顺序同步
  103. /// </summary>
  104. /// <param name="type"></param>
  105. /// <returns></returns>
  106. static QString getTypeString(VALUE_TYPE type)
  107. {
  108. int nIndex = static_cast<int>(type);
  109. // 2022-2-1,处理了Control_Base = 100 导致的序号问题
  110. int nControlBaseIndex = valueString.indexOf("ControlBase");
  111. if (nIndex >= 100)
  112. {
  113. nIndex -= 100;
  114. nIndex += nControlBaseIndex;
  115. }
  116. // 将序号转换为valueStrin
  117. if (nIndex < valueString.size())
  118. {
  119. return valueString.at(nIndex);
  120. }
  121. else
  122. {
  123. return valueString.last();
  124. }
  125. }
  126. /// <summary>
  127. /// 返回字符串对应的Type值
  128. /// </summary>
  129. /// <param name="strTypeString"></param>
  130. /// <returns></returns>
  131. static VALUE_TYPE getTypeByString(const QString& strTypeString )
  132. {
  133. int nIndex = valueString.indexOf(strTypeString);
  134. // 2022-2-1,处理了Control_Base = 100 导致的序号问题
  135. int nControlBaseIndex = valueString.indexOf("ControlBase");
  136. if (nIndex >= nControlBaseIndex)
  137. {
  138. nIndex += 100;
  139. }
  140. if (nIndex >= 0)
  141. {
  142. return static_cast<VALUE_TYPE>(nIndex);
  143. }
  144. else
  145. {
  146. return VALUE_TYPE::Type_Unknown;
  147. }
  148. }
  149. /// <summary>
  150. /// 获取数值对应的字符串
  151. /// </summary>
  152. /// <returns></returns>
  153. static QString getValueString(void** pValuePtr, VALUE_TYPE type)
  154. {
  155. if (type == VALUE_TYPE::Type_Int)
  156. {
  157. return QString::number(*(int*)pValuePtr);
  158. }
  159. else if (type == VALUE_TYPE::Type_String)
  160. {
  161. return *((QString*)pValuePtr);
  162. }
  163. else if (type == VALUE_TYPE::Type_Bool)
  164. {
  165. return (*(bool*)pValuePtr == true) ? "true" : "false";
  166. }
  167. else if (type == VALUE_TYPE::Type_Float)
  168. {
  169. return QString("%1").arg(*(float*)pValuePtr);
  170. }
  171. else if (type == VALUE_TYPE::Type_Double)
  172. {
  173. return QString("%1").arg(*(double*)pValuePtr);
  174. }
  175. else if (type == VALUE_TYPE::Type_StdString)
  176. {
  177. return QString("%1").arg((*(std::string*)pValuePtr).c_str());
  178. }
  179. else if (type == VALUE_TYPE::Type_String)
  180. {
  181. return (*(QString*)pValuePtr);
  182. }
  183. else if (type == VALUE_TYPE::Type_QImage)
  184. {
  185. if ((*(QImage*)pValuePtr).isNull() )
  186. {
  187. return QString("QImage");
  188. }
  189. return QString("size %1 * %2").arg((*(QImage*)pValuePtr).size().width()).arg((*(QImage*)pValuePtr).size().height());
  190. }
  191. else if (type == VALUE_TYPE::Type_HTuple)
  192. {
  193. return QString("HTuple");
  194. }
  195. else if (type == VALUE_TYPE::Type_HObject)
  196. {
  197. return QString("HObject");
  198. }
  199. else if (type == VALUE_TYPE::Type_HImage)
  200. {
  201. return QString("HImage");
  202. }
  203. else if (type == VALUE_TYPE::Type_ST_Pos)
  204. {
  205. return QString("HPose");
  206. }
  207. else if (type == VALUE_TYPE::Type_ST_HomMat2D)
  208. {
  209. return QString("HHomMat2D");
  210. }
  211. else if (type == VALUE_TYPE::Type_pIBaseCamera)
  212. {
  213. if (*pValuePtr == nullptr)
  214. {
  215. return QString("pIBaseCamera");
  216. }
  217. return QString("%1").arg(((IBaseCamera*)*pValuePtr)->serial());
  218. }
  219. else
  220. {
  221. return ("N/A");
  222. }
  223. }
  224. /// <summary>
  225. /// 根据边的方向获取对应Widget的边
  226. /// </summary>
  227. /// <param name="widget"></param>
  228. /// <param name="sideID"></param>
  229. /// <returns></returns>
  230. static QLine getSideLineByID(QWidget* widget, short sideID)
  231. {
  232. QRect rc = widget->geometry();
  233. if (sideID == 0)
  234. {
  235. return QLine(rc.topLeft(), rc.bottomLeft());
  236. }
  237. else if (sideID == 1)
  238. {
  239. return QLine(rc.topLeft(), rc.topRight());
  240. }
  241. else if (sideID == 2)
  242. {
  243. return QLine(rc.topRight(), rc.bottomRight());
  244. }
  245. else if (sideID == 3)
  246. {
  247. return QLine(rc.bottomLeft(), rc.bottomRight());
  248. }
  249. // 错误,不应该执行到这里
  250. else
  251. {
  252. return QLine(-1, -1, -1, -1);
  253. }
  254. }
  255. /// <summary>
  256. /// 辅助函数:判断两条线是否对齐(一条线是否处于另外一条线的延长线中)
  257. /// </summary>
  258. /// <param name="line1"></param>
  259. /// <param name="line2"></param>
  260. /// <returns></returns>
  261. // 用于对齐的精度
  262. #define ALIGN_PRECISION 2
  263. static bool isAligned(const QLine& line1, const QLine& line2)
  264. {
  265. // 2022-9-8 修改了对齐规则,少于2个像素的都认为是对齐了
  266. // 如果4个点的x都相同,则true
  267. if (qAbs(line1.p1().x() - line1.p2().x()) < ALIGN_PRECISION
  268. && qAbs(line2.p1().x() - line2.p2().x()) < ALIGN_PRECISION
  269. && qAbs(line1.p1().x() - line2.p2().x()) < ALIGN_PRECISION
  270. )
  271. {
  272. return true;
  273. }
  274. // 如果4个点的y都相同,则true
  275. if (qAbs(line1.p1().y() - line1.p2().y()) < ALIGN_PRECISION
  276. && qAbs(line2.p1().y() - line2.p2().y()) < ALIGN_PRECISION
  277. && qAbs(line1.p1().y() - line2.p2().y()) < ALIGN_PRECISION
  278. )
  279. {
  280. return true;
  281. }
  282. return false;
  283. }
  284. ///// <summary>
  285. ///// 计算给定Line的长度
  286. ///// </summary>
  287. ///// <returns></returns>
  288. //static int getLineLength(const QLine line)
  289. //{
  290. //
  291. //}
  292. ///// <summary>
  293. ///// 获取数值对应的字符串
  294. ///// </summary>
  295. ///// <returns></returns>
  296. //template<typename T>
  297. //static QString getValueString(T value, VALUE_TYPE type)
  298. //{
  299. // if (type == VALUE_TYPE::Type_Int)
  300. // {
  301. // return QString::number(value);
  302. // }
  303. // else if (type == VALUE_TYPE::Type_String)
  304. // {
  305. // return value;
  306. // }
  307. // else if (type == VALUE_TYPE::Type_Bool)
  308. // {
  309. // return value;
  310. // }
  311. // else if (type == VALUE_TYPE::Type_Float)
  312. // {
  313. // return QString("%1").arg(value);
  314. // }
  315. // else
  316. // {
  317. // return ("");
  318. // }
  319. //}
  320. /// <summary>
  321. /// Sleep ,单位 ms
  322. /// </summary>
  323. /// <param name="ms"></param>
  324. static void qSleep(int ms)
  325. {
  326. if (ms <= 0)
  327. {
  328. return;
  329. }
  330. //#ifdef Q_OS_WIN
  331. // ::Sleep(uint(ms));
  332. //#else
  333. // struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 };
  334. // nanosleep(&ts, NULL);
  335. //#endif
  336. //QTime qTime = QTime::currentTime().addMSecs(ms);
  337. //while (QTime::currentTime() < qTime)
  338. // QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
  339. QThread::msleep(ms);
  340. }
  341. /// <summary>
  342. /// 生成两个范围内的随机数
  343. /// </summary>
  344. /// <param name="start"></param>
  345. /// <param name="end"></param>
  346. static int genRandNumber(int start, int end)
  347. {
  348. qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));
  349. return qrand() % (end - start) + start;
  350. }
  351. /// <summary>
  352. /// 将QColor转换成qss字符串
  353. /// </summary>
  354. /// <param name="color"></param>
  355. /// <param name="type">类型,有"RGBA" "RGB" "HEX" 三种</param>
  356. /// <returns></returns>
  357. static QString qColor2qString(const QColor& color, const QString type = "RGB")
  358. {
  359. if (type == "RGBA")
  360. {
  361. return QString("rgba(%1,%2,%3,%4)")
  362. .arg(color.red())
  363. .arg(color.green())
  364. .arg(color.blue())
  365. .arg(color.alpha());
  366. }
  367. else if (type == "RGB")
  368. {
  369. return QString("rgb(%1,%2,%3)")
  370. .arg(color.red())
  371. .arg(color.green())
  372. .arg(color.blue());
  373. }
  374. else if (type == "HEX")
  375. {
  376. return QString().sprintf("#%1%02X%02X%02X",
  377. color.red(),
  378. color.green(),
  379. color.blue())
  380. .arg(color.alpha() != 255 ? QString().sprintf("%02X", color.alpha()) : QString());
  381. }
  382. return color.name();
  383. }
  384. static QString getHalconErrMessage(int errCode)
  385. {
  386. QString message = ("未定义代码:");
  387. switch (errCode)
  388. {
  389. case H_ERR_WIPV1:
  390. message = ("参数1数据异常");
  391. break;
  392. case H_ERR_WIPV2:
  393. message = ("参数2数据异常");
  394. break;
  395. case H_ERR_WIPV3:
  396. message = ("参数3数据异常");
  397. break;
  398. case H_ERR_WIPV4:
  399. message = ("参数4数据异常");
  400. break;
  401. case H_ERR_WIPV5:
  402. message = ("参数5数据异常");
  403. break;
  404. case H_ERR_WIPV6:
  405. message = ("参数6数据异常");
  406. break;
  407. case H_ERR_WIPV7:
  408. message = ("参数7数据异常");
  409. break;
  410. case H_ERR_WIPV8:
  411. message = ("参数8数据异常");
  412. break;
  413. case H_ERR_WIPV9:
  414. message = ("参数9数据异常");
  415. break;
  416. case H_ERR_WIPV10:
  417. message = ("参数10数据异常");
  418. break;
  419. case H_ERR_WIPV11:
  420. message = ("参数11数据异常");
  421. break;
  422. case H_ERR_WIPV12:
  423. message = ("参数12数据异常");
  424. break;
  425. case H_ERR_WIPV13:
  426. message = ("参数13数据异常");
  427. break;
  428. case H_ERR_WIPV14:
  429. message = ("参数14数据异常");
  430. break;
  431. case H_ERR_WIPV15:
  432. message = ("参数15数据异常");
  433. break;
  434. case H_ERR_WIPV16:
  435. message = ("参数16数据异常");
  436. break;
  437. case H_ERR_WIPV17:
  438. message = ("参数17数据异常");
  439. break;
  440. case H_ERR_WIPV18:
  441. message = ("参数18数据异常");
  442. break;
  443. case H_ERR_WIPV19:
  444. message = ("参数19数据异常");
  445. break;
  446. case H_ERR_WIPV20:
  447. message = ("参数20数据异常");
  448. break;
  449. case H_ERR_JPGLIB_INFORMAT:
  450. message = ("jpg图像格式异常.");
  451. break;
  452. default:
  453. message += QString::number(errCode);
  454. break;
  455. }
  456. return message;
  457. }
  458. private:
  459. };
  460. // 用于在Tool的执行线程中弹出对话框
  461. //class MessageBoxInThread : public QObject
  462. //{
  463. // Q_OBJECT
  464. //private:
  465. // const QString m_title;
  466. // const QString m_message;
  467. //public:
  468. // MessageBoxInThread(const QString& title, const QString& message)
  469. // :m_title(title),
  470. // m_message(message)
  471. // {
  472. //
  473. // }
  474. // static void showInformation(const QString& title, const QString& message)
  475. // {
  476. // QEventLoop eventLoop;
  477. // auto messageBox = new MessageBoxInThread(title, message);
  478. // connect(messageBox, SIGNAL(destroyed()), &eventLoop, SLOT(quit()));
  479. // messageBox->readyShow();
  480. // eventLoop.exec();
  481. // }
  482. //
  483. //private:
  484. //
  485. // void readyShow(void)
  486. // {
  487. // this->moveToThread(qApp->thread());
  488. // QTimer::singleShot(0, this, SLOT(onShow()));
  489. // }
  490. //
  491. //private slots:
  492. //
  493. // void onShow(void)
  494. // {
  495. // QMessageBox::information(NULL, m_title, m_message);
  496. // this->deleteLater();
  497. // }
  498. //};