DialogBase.cpp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. #include "DialogBase.h"
  2. #include <QMouseEvent>
  3. #include <QVBoxLayout>
  4. #include <QLabel>
  5. #include <QPushButton>
  6. #include <QBoxLayout>
  7. #include <QStyle>
  8. #include "OneShadowEffect.h"
  9. DialogBase::DialogBase(QWidget *parent)
  10. : QDialog(parent)
  11. {
  12. m_logger = spdlog::get("ACASetting");
  13. if(m_logger == nullptr)
  14. {
  15. fmt::print("DialogBase: 未发现ACASetting日志记录器,请检查日志记录器是否已初始化。\n");
  16. return;
  17. }
  18. initUI();
  19. initSettings();
  20. /* 设置qss */
  21. connect(&UIStyle, &UIStyleManager::signal_qssChanged, this, &DialogBase::do_setQSS);
  22. /* 设置默认的UI */
  23. setQSS();
  24. }
  25. DialogBase::~DialogBase()
  26. {
  27. }
  28. /* 设置标题 */
  29. void DialogBase::setTitle(const QString &title, QSize size)
  30. {
  31. m_labelTitle->setText(title);
  32. m_labelTitle->setFixedSize(size);
  33. }
  34. /* 获取标题 */
  35. QString DialogBase::getTitle() const
  36. {
  37. return m_labelTitle ? m_labelTitle->text() : QString();
  38. }
  39. /* 设置内容容器 */
  40. bool DialogBase::setContentWidget(QWidget *widget)
  41. {
  42. if(widget == nullptr)
  43. {
  44. SPDLOG_LOGGER_ERROR(m_logger, "设置内容容器失败,widget为nullptr");
  45. return false;
  46. }
  47. if(m_widgetContent != nullptr)
  48. {
  49. m_layoutBackground->removeWidget(m_widgetContent);
  50. delete m_widgetContent;
  51. m_widgetContent = nullptr;
  52. }
  53. QSize size = widget->size();
  54. m_widgetContent = widget;
  55. m_layoutBackground->insertWidget(1, m_widgetContent);
  56. m_widgetContent->resize(size);
  57. return true;
  58. }
  59. /* 设置低栏容器 */
  60. bool DialogBase::setBottomWidget(QWidget *widget)
  61. {
  62. if(widget == nullptr)
  63. {
  64. SPDLOG_LOGGER_ERROR(m_logger, "设置底部容器失败,widget为nullptr");
  65. return false;
  66. }
  67. if(m_widgetBottom != nullptr)
  68. {
  69. m_layoutBackground->removeWidget(m_widgetBottom);
  70. delete m_widgetBottom;
  71. m_widgetBottom = nullptr;
  72. }
  73. m_widgetBottom = widget;
  74. m_layoutBackground->insertWidget(2, m_widgetBottom);
  75. return true;
  76. }
  77. /* 初始化UI */
  78. void DialogBase::initUI()
  79. {
  80. /*--------------------- 设置对话框的属性 -----------------------*/
  81. this->setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog);
  82. this->setAttribute(Qt::WA_TranslucentBackground, true);
  83. // this->setObjectName("DialogBase");
  84. /*--------------------- 初始化背景容器 -----------------------*/
  85. m_widgetBackground = new QWidget(this);
  86. m_widgetBackground->setObjectName("widget_background");
  87. QVBoxLayout* layout = new QVBoxLayout(this);
  88. /* 设置边距,就是阴影的宽度 */
  89. layout->setContentsMargins(20, 20, 20, 20);
  90. layout->setSpacing(0);
  91. this->setLayout(layout);
  92. layout->addWidget(m_widgetBackground);
  93. /* 创建背景容器内部的布局 */
  94. m_layoutBackground = new QVBoxLayout(m_widgetBackground);
  95. m_layoutBackground->setContentsMargins(0, 0, 0, 0);
  96. m_layoutBackground->setSpacing(0);
  97. m_widgetBackground->setLayout(m_layoutBackground);
  98. /*--------------------- 初始顶栏 -----------------------*/
  99. /* 初始化顶部标题栏,高度56,下面分割线高度1 */
  100. m_widgetTop = new QWidget(this);
  101. m_widgetTop->setObjectName("widget_top");
  102. m_widgetTop->setFixedHeight(56);
  103. m_layoutBackground->addWidget(m_widgetTop);
  104. QHBoxLayout* topHBoxLayout = new QHBoxLayout(m_widgetTop);
  105. m_widgetTop->setLayout(topHBoxLayout);
  106. /* 初始化标题栏 */
  107. m_labelTitle = new QLabel(m_widgetTop);
  108. m_labelTitle->setObjectName("label_title");
  109. m_labelTitle->setText("Dialog Title");
  110. m_labelTitle->setFixedSize(120, 18);
  111. m_labelTitle->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
  112. /* 初始化关闭按钮 */
  113. m_pBtn_Close = new QPushButton(m_widgetTop);
  114. m_pBtn_Close->setObjectName("pBtn_Close");
  115. m_pBtn_Close->resize(32, 32);
  116. /* 安装事件过滤器,主要是处理鼠标悬停事件 */
  117. m_pBtn_Close->installEventFilter(this);
  118. /* 重新布局顶栏 */
  119. layoutTop();
  120. /*--------------------- 初始化内容栏 -----------------------*/
  121. // m_widgetContent = new QWidget(this);
  122. // m_layoutBackground->addWidget(m_widgetContent);
  123. /*--------------------- 初始底栏 -----------------------*/
  124. m_widgetBottom = new QWidget(this);
  125. m_widgetBottom->setObjectName("widget_bottom");
  126. m_widgetBottom->setFixedHeight(88);
  127. m_layoutBackground->addWidget(m_widgetBottom);
  128. QHBoxLayout* bottomHBoxLayout = new QHBoxLayout(m_widgetBottom);
  129. m_widgetBottom->setLayout(bottomHBoxLayout);
  130. /* 初始化取消按钮 */
  131. m_pBtn_Cancel = new QPushButton(m_widgetBottom);
  132. m_pBtn_Cancel->setObjectName("pBtn_Cancel");
  133. m_pBtn_Cancel->setText("取消");
  134. m_pBtn_Cancel->setFixedSize(60, 32);
  135. bottomHBoxLayout->addWidget(m_pBtn_Cancel, 0, Qt::AlignRight | Qt::AlignVCenter);
  136. /* 初始化确认按钮 */
  137. m_pBtn_OK = new QPushButton(m_widgetBottom);
  138. m_pBtn_OK->setObjectName("pBtn_OK");
  139. m_pBtn_OK->setText("确定");
  140. m_pBtn_OK->setFixedSize(60, 32);
  141. bottomHBoxLayout->addWidget(m_pBtn_OK, 0, Qt::AlignRight | Qt::AlignVCenter);
  142. /* 添加一个底部横向弹簧 */
  143. bottomHBoxLayout->insertStretch(0, 1);
  144. /* 设置底部按钮的间距 */
  145. bottomHBoxLayout->setContentsMargins(32, 24, 32, 32);
  146. bottomHBoxLayout->setSpacing(16);
  147. /*--------------------- 设置整体背景 -----------------------*/
  148. /* 这个背景需要在初始化所有的widget控件之后再设置 */
  149. // auto screenRect = QGuiApplication::screenAt(QCursor::pos())->geometry();
  150. // this->resize(screenRect.width(), screenRect.height());
  151. // /* 设置设置区域居中显示 */
  152. // m_widgetBackground->move(screenRect.width() / 2 - m_widgetBackground->width() / 2,
  153. // screenRect.height() / 2 - m_widgetBackground->height() / 2);
  154. /*--------------------- 创建阴影 -----------------------*/
  155. auto pShadow = new OneShadowEffect(this);
  156. m_widgetBackground->setGraphicsEffect(pShadow);
  157. }
  158. /* 初始化其他设置 */
  159. void DialogBase::initSettings()
  160. {
  161. /* 初始化变量 */
  162. m_lastPos = QPoint(0, 0);
  163. /* 连接信号和槽 */
  164. connect(m_pBtn_Close, &QPushButton::clicked, this, &DialogBase::do_pBtn_Close_Clicked);
  165. connect(m_pBtn_OK, &QPushButton::clicked, this, &DialogBase::do_pBtn_OK_Clicked);
  166. connect(m_pBtn_Cancel, &QPushButton::clicked, this, &DialogBase::do_pBtnCancel_clicked);
  167. /* 设置样式表 */
  168. // setQSS();
  169. }
  170. /* 加载QSS */
  171. void DialogBase::setQSS()
  172. {
  173. /* 获取样式表路径 */
  174. QString qssPath = UIStyle.getQSSPath() + "/dialogbase.qss";
  175. QFile file(qssPath);
  176. if(file.open(QFile::ReadOnly))
  177. {
  178. QString qss = file.readAll();
  179. file.close();
  180. this->setStyleSheet(qss);
  181. } else
  182. {
  183. SPDLOG_LOGGER_ERROR(m_logger, "打开QSS文件失败: {}", qssPath.toStdString());
  184. SPDLOG_LOGGER_ERROR(m_logger, "错误信息: {}", file.errorString().toStdString());
  185. }
  186. }
  187. /* 设置top栏的位置布局,标题和关闭按钮的高度起始位置不一样,不方便使用布局,所有手动修改坐标
  188. * 标题位置32,18,高度18
  189. * 关闭按钮右对齐16,y12,大小32x32 */
  190. void DialogBase::layoutTop()
  191. {
  192. m_labelTitle->move(32, 18);
  193. int x = m_widgetTop->width() - m_pBtn_Close->width() - 16;
  194. m_pBtn_Close->move(x, 12);
  195. }
  196. /* 确认按钮点击事件 */
  197. void DialogBase::do_pBtn_OK_Clicked()
  198. {
  199. m_isOK = true;
  200. this->accept();
  201. }
  202. /* 设置QSS */
  203. void DialogBase::do_setQSS(EUIStyle style)
  204. {
  205. setQSS();
  206. }
  207. /* 重写鼠标按下事件 */
  208. void DialogBase::mousePressEvent(QMouseEvent *event)
  209. {
  210. m_lastPos = event->globalPos();
  211. event->accept();
  212. }
  213. /* 重写鼠标移动事件 */
  214. void DialogBase::mouseMoveEvent(QMouseEvent *event)
  215. {
  216. auto point = m_widgetTop->mapToGlobal(QPoint(0, 0));
  217. QRect rect(point, m_widgetTop->size());
  218. if(!rect.contains(m_lastPos))
  219. {
  220. event->accept();
  221. return;
  222. }
  223. int dx = event->globalX() - m_lastPos.x();
  224. int dy = event->globalY() - m_lastPos.y();
  225. // m_widgetBackground->move(m_widgetBackground->x() + dx, m_widgetBackground->y() + dy);
  226. move(x() + dx, y() + dy);
  227. m_lastPos = event->globalPos();
  228. event->accept();
  229. }
  230. /* 重写鼠标释放事件 */
  231. void DialogBase::mouseReleaseEvent(QMouseEvent *event)
  232. {
  233. event->accept();
  234. }
  235. /* 显示事件 */
  236. void DialogBase::showEvent(QShowEvent *event)
  237. {
  238. QDialog::showEvent(event);
  239. /* 重新布局顶栏 */
  240. layoutTop();
  241. }
  242. /* 重新设置大小 */
  243. void DialogBase::resizeEvent(QResizeEvent *event)
  244. {
  245. QDialog::resizeEvent(event);
  246. /* 重新布局顶栏 */
  247. layoutTop();
  248. }
  249. /* 事件过滤器 */
  250. bool DialogBase::eventFilter(QObject *watched, QEvent *event)
  251. {
  252. if(watched == m_pBtn_Close && event->type() == QEvent::HoverEnter)
  253. {
  254. m_pBtn_Close->setProperty("Hover", true);
  255. m_pBtn_Close->style()->unpolish(m_pBtn_Close);
  256. m_pBtn_Close->style()->polish(m_pBtn_Close);
  257. m_pBtn_Close->update();
  258. return true;
  259. }
  260. else if(watched == m_pBtn_Close && event->type() == QEvent::HoverLeave)
  261. {
  262. m_pBtn_Close->setProperty("Hover", false);
  263. m_pBtn_Close->style()->unpolish(m_pBtn_Close);
  264. m_pBtn_Close->style()->polish(m_pBtn_Close);
  265. m_pBtn_Close->update();
  266. return true;
  267. }
  268. return QDialog::eventFilter(watched, event);
  269. }