iconhelper.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. #include "iconhelper.h"
  2. IconHelper *IconHelper::iconFontAliBaBa = 0;
  3. IconHelper *IconHelper::iconFontAwesome = 0;
  4. IconHelper *IconHelper::iconFontAwesome6 = 0;
  5. IconHelper *IconHelper::iconFontWeather = 0;
  6. int IconHelper::iconFontIndex = -1;
  7. void IconHelper::initFont()
  8. {
  9. static bool isInit = false;
  10. if (!isInit) {
  11. isInit = true;
  12. if (iconFontAliBaBa == 0) {
  13. iconFontAliBaBa = new IconHelper(":/qrc/ttf/iconfont.ttf", "iconfont");
  14. }
  15. if (iconFontAwesome == 0) {
  16. iconFontAwesome = new IconHelper(":/qrc/ttf/fontawesome-webfont.ttf", "FontAwesome");
  17. }
  18. if (iconFontAwesome6 == 0) {
  19. iconFontAwesome6 = new IconHelper(":/qrc/ttf/fa-regular-400.ttf", "Font Awesome 6 Pro Regular");
  20. }
  21. if (iconFontWeather == 0) {
  22. iconFontWeather = new IconHelper(":/qrc/ttf/pe-icon-set-weather.ttf", "pe-icon-set-weather");
  23. }
  24. }
  25. }
  26. void IconHelper::setIconFontIndex(int index)
  27. {
  28. iconFontIndex = index;
  29. }
  30. QFont IconHelper::getIconFontAliBaBa()
  31. {
  32. initFont();
  33. return iconFontAliBaBa->getIconFont();
  34. }
  35. QFont IconHelper::getIconFontAwesome()
  36. {
  37. initFont();
  38. return iconFontAwesome->getIconFont();
  39. }
  40. QFont IconHelper::getIconFontAwesome6()
  41. {
  42. initFont();
  43. return iconFontAwesome6->getIconFont();
  44. }
  45. QFont IconHelper::getIconFontWeather()
  46. {
  47. initFont();
  48. return iconFontWeather->getIconFont();
  49. }
  50. IconHelper *IconHelper::getIconHelper(int icon)
  51. {
  52. initFont();
  53. //指定了字体索引则取对应索引的字体类
  54. //没指定则自动根据不同的字体的值选择对应的类
  55. //由于部分值范围冲突所以可以指定索引来取
  56. //fontawesome 0xf000-0xf2e0
  57. //fontawesome6 0xe000-0xe33d 0xf000-0xf8ff
  58. //iconfont 0xe501-0xe793 0xe8d5-0xea5d 0xeb00-0xec00
  59. //weather 0xe900-0xe9cf
  60. IconHelper *iconHelper = iconFontAwesome;
  61. if (iconFontIndex < 0) {
  62. if ((icon >= 0xe501 && icon <= 0xe793) || (icon >= 0xe8d5 && icon <= 0xea5d) || (icon >= 0xeb00 && icon <= 0xec00)) {
  63. iconHelper = iconFontAliBaBa;
  64. }
  65. } else if (iconFontIndex == 0) {
  66. iconHelper = iconFontAliBaBa;
  67. } else if (iconFontIndex == 1) {
  68. iconHelper = iconFontAwesome;
  69. } else if (iconFontIndex == 2) {
  70. iconHelper = iconFontAwesome6;
  71. } else if (iconFontIndex == 3) {
  72. iconHelper = iconFontWeather;
  73. }
  74. return iconHelper;
  75. }
  76. void IconHelper::setIcon(QLabel *lab, int icon, quint32 size)
  77. {
  78. getIconHelper(icon)->setIcon1(lab, icon, size);
  79. }
  80. void IconHelper::setIcon(QAbstractButton *btn, int icon, quint32 size)
  81. {
  82. getIconHelper(icon)->setIcon1(btn, icon, size);
  83. }
  84. void IconHelper::setPixmap(QAbstractButton *btn, const QColor &color, int icon, quint32 size,
  85. quint32 width, quint32 height, int flags)
  86. {
  87. getIconHelper(icon)->setPixmap1(btn, color, icon, size, width, height, flags);
  88. }
  89. QPixmap IconHelper::getPixmap(const QColor &color, int icon, quint32 size,
  90. quint32 width, quint32 height, int flags)
  91. {
  92. return getIconHelper(icon)->getPixmap1(color, icon, size, width, height, flags);
  93. }
  94. void IconHelper::setStyle(QWidget *widget, QList<QPushButton *> btns,
  95. QList<int> icons, const IconHelper::StyleColor &styleColor)
  96. {
  97. int icon = icons.first();
  98. getIconHelper(icon)->setStyle1(widget, btns, icons, styleColor);
  99. }
  100. void IconHelper::setStyle(QWidget *widget, QList<QToolButton *> btns,
  101. QList<int> icons, const IconHelper::StyleColor &styleColor)
  102. {
  103. int icon = icons.first();
  104. getIconHelper(icon)->setStyle1(widget, btns, icons, styleColor);
  105. }
  106. void IconHelper::setStyle(QWidget *widget, QList<QAbstractButton *> btns,
  107. QList<int> icons, const IconHelper::StyleColor &styleColor)
  108. {
  109. int icon = icons.first();
  110. getIconHelper(icon)->setStyle1(widget, btns, icons, styleColor);
  111. }
  112. IconHelper::IconHelper(const QString &fontFile, const QString &fontName, QObject *parent) : QObject(parent)
  113. {
  114. //判断图形字体是否存在,不存在则加入
  115. QFontDatabase fontDb;
  116. if (!fontDb.families().contains(fontName) && QFile(fontFile).exists()) {
  117. int fontId = fontDb.addApplicationFont(fontFile);
  118. QStringList listName = fontDb.applicationFontFamilies(fontId);
  119. if (listName.count() == 0) {
  120. qDebug() << QString("load %1 error").arg(fontName);
  121. }
  122. }
  123. //再次判断是否包含字体名称防止加载失败
  124. if (fontDb.families().contains(fontName)) {
  125. iconFont = QFont(fontName);
  126. #if (QT_VERSION >= QT_VERSION_CHECK(4,8,0))
  127. iconFont.setHintingPreference(QFont::PreferNoHinting);
  128. #endif
  129. }
  130. }
  131. bool IconHelper::eventFilter(QObject *watched, QEvent *event)
  132. {
  133. //根据不同的
  134. if (watched->inherits("QAbstractButton")) {
  135. QAbstractButton *btn = (QAbstractButton *)watched;
  136. int index = btns.indexOf(btn);
  137. if (index >= 0) {
  138. //不同的事件设置不同的图标,同时区分选中的和没有选中的
  139. if (btn->isChecked()) {
  140. if (event->type() == QEvent::MouseButtonPress) {
  141. QMouseEvent *mouseEvent = (QMouseEvent *)event;
  142. if (mouseEvent->button() == Qt::LeftButton) {
  143. btn->setIcon(QIcon(pixChecked.at(index)));
  144. }
  145. } else if (event->type() == QEvent::Enter) {
  146. btn->setIcon(QIcon(pixChecked.at(index)));
  147. } else if (event->type() == QEvent::Leave) {
  148. btn->setIcon(QIcon(pixChecked.at(index)));
  149. }
  150. } else {
  151. if (event->type() == QEvent::MouseButtonPress) {
  152. QMouseEvent *mouseEvent = (QMouseEvent *)event;
  153. if (mouseEvent->button() == Qt::LeftButton) {
  154. btn->setIcon(QIcon(pixPressed.at(index)));
  155. }
  156. } else if (event->type() == QEvent::Enter) {
  157. btn->setIcon(QIcon(pixHover.at(index)));
  158. } else if (event->type() == QEvent::Leave) {
  159. btn->setIcon(QIcon(pixNormal.at(index)));
  160. }
  161. }
  162. }
  163. }
  164. return QObject::eventFilter(watched, event);
  165. }
  166. void IconHelper::toggled(bool checked)
  167. {
  168. //选中和不选中设置不同的图标
  169. QAbstractButton *btn = (QAbstractButton *)sender();
  170. int index = btns.indexOf(btn);
  171. if (checked) {
  172. btn->setIcon(QIcon(pixChecked.at(index)));
  173. } else {
  174. btn->setIcon(QIcon(pixNormal.at(index)));
  175. }
  176. }
  177. QFont IconHelper::getIconFont()
  178. {
  179. return this->iconFont;
  180. }
  181. void IconHelper::setIcon1(QLabel *lab, int icon, quint32 size)
  182. {
  183. iconFont.setPixelSize(size);
  184. lab->setFont(iconFont);
  185. lab->setText((QChar)icon);
  186. }
  187. void IconHelper::setIcon1(QAbstractButton *btn, int icon, quint32 size)
  188. {
  189. iconFont.setPixelSize(size);
  190. btn->setFont(iconFont);
  191. btn->setText((QChar)icon);
  192. }
  193. void IconHelper::setPixmap1(QAbstractButton *btn, const QColor &color, int icon, quint32 size,
  194. quint32 width, quint32 height, int flags)
  195. {
  196. btn->setIcon(getPixmap1(color, icon, size, width, height, flags));
  197. }
  198. QPixmap IconHelper::getPixmap1(const QColor &color, int icon, quint32 size,
  199. quint32 width, quint32 height, int flags)
  200. {
  201. //主动绘制图形字体到图片
  202. QPixmap pix(width, height);
  203. pix.fill(Qt::transparent);
  204. QPainter painter;
  205. painter.begin(&pix);
  206. painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
  207. painter.setPen(color);
  208. iconFont.setPixelSize(size);
  209. painter.setFont(iconFont);
  210. painter.drawText(pix.rect(), flags, (QChar)icon);
  211. painter.end();
  212. return pix;
  213. }
  214. void IconHelper::setStyle1(QWidget *widget, QList<QPushButton *> btns, QList<int> icons, const IconHelper::StyleColor &styleColor)
  215. {
  216. QList<QAbstractButton *> list;
  217. foreach (QPushButton *btn, btns) {
  218. list << btn;
  219. }
  220. setStyle(widget, list, icons, styleColor);
  221. }
  222. void IconHelper::setStyle1(QWidget *widget, QList<QToolButton *> btns, QList<int> icons, const IconHelper::StyleColor &styleColor)
  223. {
  224. QList<QAbstractButton *> list;
  225. foreach (QToolButton *btn, btns) {
  226. list << btn;
  227. }
  228. setStyle(widget, list, icons, styleColor);
  229. }
  230. void IconHelper::setStyle1(QWidget *widget, QList<QAbstractButton *> btns, QList<int> icons, const IconHelper::StyleColor &styleColor)
  231. {
  232. int btnCount = btns.count();
  233. int iconCount = icons.count();
  234. if (btnCount <= 0 || iconCount <= 0 || btnCount != iconCount) {
  235. return;
  236. }
  237. QString position = styleColor.position;
  238. quint32 iconSize = styleColor.iconSize;
  239. quint32 iconWidth = styleColor.iconWidth;
  240. quint32 iconHeight = styleColor.iconHeight;
  241. quint32 borderWidth = styleColor.borderWidth;
  242. //根据不同的位置计算边框
  243. QString strBorder;
  244. if (position == "top") {
  245. strBorder = QString("border-width:%1px 0px 0px 0px;padding-top:%1px;padding-bottom:%2px;")
  246. .arg(borderWidth).arg(borderWidth * 2);
  247. } else if (position == "right") {
  248. strBorder = QString("border-width:0px %1px 0px 0px;padding-right:%1px;padding-left:%2px;")
  249. .arg(borderWidth).arg(borderWidth * 2);
  250. } else if (position == "bottom") {
  251. strBorder = QString("border-width:0px 0px %1px 0px;padding-bottom:%1px;padding-top:%2px;")
  252. .arg(borderWidth).arg(borderWidth * 2);
  253. } else if (position == "left") {
  254. strBorder = QString("border-width:0px 0px 0px %1px;padding-left:%1px;padding-right:%2px;")
  255. .arg(borderWidth).arg(borderWidth * 2);
  256. }
  257. //如果图标是左侧显示则需要让没有选中的按钮左侧也有加深的边框,颜色为背景颜色
  258. //如果图标在文字上面而设置的边框是 top bottom 也需要启用加深边框
  259. QStringList qss;
  260. if (styleColor.defaultBorder) {
  261. qss << QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:solid;border-radius:0px;%2border-color:%3;color:%4;background:%5;}")
  262. .arg(position).arg(strBorder).arg(styleColor.normalBgColor).arg(styleColor.normalTextColor).arg(styleColor.normalBgColor);
  263. } else {
  264. qss << QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}")
  265. .arg(position).arg(styleColor.normalTextColor).arg(styleColor.normalBgColor);
  266. }
  267. //悬停+按下+选中
  268. qss << QString("QWidget[flag=\"%1\"] QAbstractButton:hover{border-style:solid;%2border-color:%3;color:%4;background:%5;}")
  269. .arg(position).arg(strBorder).arg(styleColor.borderColor).arg(styleColor.hoverTextColor).arg(styleColor.hoverBgColor);
  270. qss << QString("QWidget[flag=\"%1\"] QAbstractButton:pressed{border-style:solid;%2border-color:%3;color:%4;background:%5;}")
  271. .arg(position).arg(strBorder).arg(styleColor.borderColor).arg(styleColor.pressedTextColor).arg(styleColor.pressedBgColor);
  272. qss << QString("QWidget[flag=\"%1\"] QAbstractButton:checked{border-style:solid;%2border-color:%3;color:%4;background:%5;}")
  273. .arg(position).arg(strBorder).arg(styleColor.borderColor).arg(styleColor.checkedTextColor).arg(styleColor.checkedBgColor);
  274. //窗体背景颜色+按钮背景颜色
  275. qss << QString("QWidget#%1{background:%2;}")
  276. .arg(widget->objectName()).arg(styleColor.normalBgColor);
  277. qss << QString("QWidget>QAbstractButton{border-width:0px;background-color:%1;color:%2;}")
  278. .arg(styleColor.normalBgColor).arg(styleColor.normalTextColor);
  279. qss << QString("QWidget>QAbstractButton:hover{background-color:%1;color:%2;}")
  280. .arg(styleColor.hoverBgColor).arg(styleColor.hoverTextColor);
  281. qss << QString("QWidget>QAbstractButton:pressed{background-color:%1;color:%2;}")
  282. .arg(styleColor.pressedBgColor).arg(styleColor.pressedTextColor);
  283. qss << QString("QWidget>QAbstractButton:checked{background-color:%1;color:%2;}")
  284. .arg(styleColor.checkedBgColor).arg(styleColor.checkedTextColor);
  285. //设置样式表
  286. widget->setStyleSheet(qss.join(""));
  287. //可能会重复调用设置所以先要移除上一次的
  288. for (int i = 0; i < btnCount; ++i) {
  289. for (int j = 0; j < this->btns.count(); j++) {
  290. if (this->btns.at(j) == btns.at(i)) {
  291. disconnect(btns.at(i), SIGNAL(toggled(bool)), this, SLOT(toggled(bool)));
  292. this->btns.at(j)->removeEventFilter(this);
  293. this->btns.removeAt(j);
  294. this->pixNormal.removeAt(j);
  295. this->pixHover.removeAt(j);
  296. this->pixPressed.removeAt(j);
  297. this->pixChecked.removeAt(j);
  298. break;
  299. }
  300. }
  301. }
  302. //存储对应按钮对象,方便鼠标移上去的时候切换图片
  303. int checkedIndex = -1;
  304. for (int i = 0; i < btnCount; ++i) {
  305. int icon = icons.at(i);
  306. QPixmap pixNormal = getPixmap1(styleColor.normalTextColor, icon, iconSize, iconWidth, iconHeight);
  307. QPixmap pixHover = getPixmap1(styleColor.hoverTextColor, icon, iconSize, iconWidth, iconHeight);
  308. QPixmap pixPressed = getPixmap1(styleColor.pressedTextColor, icon, iconSize, iconWidth, iconHeight);
  309. QPixmap pixChecked = getPixmap1(styleColor.checkedTextColor, icon, iconSize, iconWidth, iconHeight);
  310. //记住最后选中的按钮
  311. QAbstractButton *btn = btns.at(i);
  312. if (btn->isChecked()) {
  313. checkedIndex = i;
  314. }
  315. btn->setIcon(QIcon(pixNormal));
  316. btn->setIconSize(QSize(iconWidth, iconHeight));
  317. btn->installEventFilter(this);
  318. connect(btn, SIGNAL(toggled(bool)), this, SLOT(toggled(bool)));
  319. this->btns << btn;
  320. this->pixNormal << pixNormal;
  321. this->pixHover << pixHover;
  322. this->pixPressed << pixPressed;
  323. this->pixChecked << pixChecked;
  324. }
  325. //主动触发一下选中的按钮
  326. if (checkedIndex >= 0) {
  327. QMetaObject::invokeMethod(btns.at(checkedIndex), "toggled", Q_ARG(bool, true));
  328. }
  329. }