一、概述
今天是组件化的第三篇文章了,前两篇文章主要是以功能为主,分别讲解了 高仿富途牛牛-组件化(一)-支持页签拖拽、增删、小工具和高仿富途牛牛-组件化(二)-磁力吸附,其中也不乏有一些小的bug,不过这些都不是问题。
效果美化是参照富途牛牛做的,虽然不是一模一样,但是确实比之前的效果好了一些,喜欢的同学可以参考下。
文章最后会把描述显示效果的qss文件贴上,希望可以帮到大家
欢迎大家提出问题,交互、配色都可以
三、工具箱
工具箱是一个很重要的功能。我们的每一个独立组件模板都拥有一个工具箱。
工具箱自身支持移动组件模板移动时 会联动工具箱移动(工具箱和组件模板的相对位置不变)下面我们来分析下工具箱是怎么做的
这里我们为了实现这个功能,重写了QWidget的三个接口,实现内容都比较简单,这里就不做说明了,有兴趣的自行百度,网上一大堆。
对于工具箱来说,我们也可以通过点击组件模板工具栏上的按钮进行关闭
工具箱的客户端我们这里是只有一个QTabWidget类,而通用和港股页签就是QTabWidget下的两个页签。
每个页签里边都是一个QListWidget,我给QListWidget设置了图表展示模式,让他有了一个钟按钮的显示风格。
2、功能详解
上边我们主要分析了工具箱的一个组成部分,接下来我将会从更为详细的代码层面说明工具箱的实现过程,其中可能会包含一些qss样式表,全部的样式表将会在文章最后贴出
上边已经提供到两个页签里边的工具按钮都是包含在QListWidget控件中的,下面我直接贴出页签初始化的关键代码
void ToolBoxDialog::InitializeTools(int start, int end, const QString normalWidget-setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); normalWidget-setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); connect(normalWidget, normalWidget-setDragEnabled(false); normalWidget-setViewMode(QListView::IconMode); normalWidget-setResizeMode(QListView::Adjust); normalWidget-setSpacing(3); for (int i = start; i end; i) { normalWidget-addItem(createItem(toolNames[i], toolTypes[i])); } m_pTabWidget-addTab(normalWidget, title);}
从上边代码可以看出,我们的列表使用了图标(QListView::IconMode)显示模式,并且设置了图标项不可以拖拽。
最后我们使用一个循环构造了很多item,插入到了QListWidget控件中
样式美化代码如下,不了解Qss语法的可以参考qt qss这篇文章,我以前写的,比较详细。
QDialog#ToolBoxDialog QTabWidget::pane { border-top: 1px solid #2B3236; }QDialog#ToolBoxDialog QTabWidget::tab-bar { top:1px;}QDialog#ToolBoxDialog QTabBar::tab { background:#1D2224;border-bottom: 1 solid #2B3236; min-width: 20ex; padding: 4px; color:#919AA3; }QDialog#ToolBoxDialog QTabBar::tab:selected { border-bottom: 1 solid #FF9900; }QDialog#ToolBoxDialog QTabBar::tab:hover { border-bottom: 1 solid #FFB700; }QDialog#ToolBoxDialog QTabBar::tab:!selected:!hover { border-bottom: 1 solid #2B3236; }QDialog#ToolBoxDialog QListView{border:0px solid blue;margin-top:12px;margin-left:12px;outline:none;}QDialog#ToolBoxDialog QListView::item{padding-top:10px;border:1 solid transparent;}QDialog#ToolBoxDialog QListView::item:hover{color:#FF9900;background:#6B7276;}
最后也是最重要的一点,item我们是怎么构造的
四、组件模板工具栏
关于工具栏的实现,我们可以参考高仿富途牛牛-组件化(一)-支持页签拖拽、增删、小工具这篇文章,今天这篇文章我们只讲解怎么美化,虽然美化效果没有很明显,我们还是凑合着看吧。
这里同样也是使用了Qt的动态属性功能,这真是Qt的一个很强大的能力,有了动态属性,我们可以很容易的做出一些交互上比较复杂的效果。
鼠标hover时的文字颜色就是使用了动态属性来实现。仔细看如下qss样式表,当QLabel的Hovered属性为true时(实际上QLabel并没有达到hover,这里我们是模拟了hover行为),我们启用了一种新的文字颜色。
TabButton#tab_Button:hover{border-bottom:1 solid #FFB700;}TabButton#tab_Button[Selected=true]{border-bottom:1 solid #FF9900;color:#FF9900;}TabButton#tab_Button QLabel[Hovered=true]{color:#FF9900;}TabButton#tab_Button QLabel[SelectedColor=true]{color:#FF9900;}TabButton#tab_Button QToolButton{border:0px;border-image:url(./image/common/titlebar_normal.png) 0 0 0 78;}TabButton#tab_Button QToolButton:hover{border:0px;border-image:url(./image/common/titlebar_hover.png) 0 0 0 78;}
再看实现代码,当我们的鼠标移入自定义的标签页按钮时,给子控件(文本控件)设置了动态属性,并刷新了界面。
void TabButton::enterEvent(QEvent * event){ m_pTitle-setProperty(Hovered, true); m_pTitle-style()-unpolish(m_pTitle); m_pTitle-style()-polish(m_pTitle); __super::enterEvent(event);}
自定义的页签按钮,本身是一个QWidget,他内部包含了QLabel文本和QToolButton关闭按钮,为了让QLabel还没有hover的时候,我们给他制造一种hover假象,我们使用了动态属性。
这个组件化demo中使用动态属性的地方其实比较多,这里就不一一例举出来了,说明一个,大家知道有这么会事,自己也学会使用即可
五、其他界面美化
讲完工具箱和组件模板工具栏美化之后,其他界面的美化就比较简单了。
剩下的就是subPanel和小窗口的美化,这里我重点说下小窗口的美化,有一个边框颜色的改变这个地方。
当小窗口获取焦点时,边框是黄色的,失去焦点时边框是灰色的
实现方式如下,这里我重写了窗口获取焦点和失去焦点的接口,并且进行设置了Qt内置的动态属性,然后在qss中对属性进行了样式配置
代码如下
//获取焦点时void SmallWidget::focusInEvent(QFocusEvent * event){ setProperty(SelectedWidget, true); style()-unpolish(this); style()-polish(this); __super::focusInEvent(event);}//失去焦点时void SmallWidget::focusOutEvent(QFocusEvent * event){ setProperty(SelectedWidget, false); style()-unpolish(this); style()-polish(this); __super::focusOutEvent(event);}
qss样式如下
QWidget#small_widget_title{ border-bottom:1 solid #2B5470;background:#292F33;}QWidget#SmallWidget{ border:1 solid #474F57;background:#1D2224;}QWidget#SmallWidget[SelectedWidget=true]{ border:2 solid #FFE100;}
是不是很简单,哈哈哈哈。
最后我贴出完整的qss样式表,为了显示更多内容,这里我把多余的换行符都去掉了。
QDialog{ border:1px solid #7b8187}QWidget{ background:#28323f;color:#DDDDDD;}QWidget#small_widget_title{ border-bottom:1 solid #2B5470;background:#292F33;}QWidget#SmallWidget{ border:1 solid #474F57;background:#1D2224;}QWidget#SmallWidget[SelectedWidget=true]{ border:2 solid #FFE100;}QWidget#DragToolBar{ background:#1D2224;border-bottom:1 solid #2B3236;}QWidget#ToolBoxTitle{ border-bottom:1 solid #2B5470;background:#292F33;}QWidget#ToolBoxDialog{ background:#28323F;border:1 solid #474F57;}TabButton#tab_Button:hover{border-bottom:1 solid #FFB700;}TabButton#tab_Button[Selected=true]{border-bottom:1 solid #FF9900;color:#FF9900;}TabButton#tab_Button QLabel[Hovered=true]{color:#FF9900;}TabButton#tab_Button QLabel[SelectedColor=true]{color:#FF9900;}TabButton#tab_Button QToolButton{border:0px;border-image:url(./image/common/titlebar_normal.png) 0 0 0 78;}TabButton#tab_Button QToolButton:hover{border:0px;border-image:url(./image/common/titlebar_hover.png) 0 0 0 78;}QDialog#ToolBoxDialog QTabWidget::pane { border-top: 1px solid #2B3236; }QDialog#ToolBoxDialog QTabWidget::tab-bar { top:1px;}QDialog#ToolBoxDialog QTabBar::tab { background:#1D2224;border-bottom: 1 solid #2B3236; min-width: 20ex; padding: 4px; color:#919AA3; }QDialog#ToolBoxDialog QTabBar::tab:selected { border-bottom: 1 solid #FF9900; }QDialog#ToolBoxDialog QTabBar::tab:hover { border-bottom: 1 solid #FFB700; }QDialog#ToolBoxDialog QTabBar::tab:!selected:!hover { border-bottom: 1 solid #2B3236; }QDialog#ToolBoxDialog QListView{border:0px solid blue;margin-top:12px;margin-left:12px;outline:none;}QDialog#ToolBoxDialog QListView::item{padding-top:10px;border:1 solid transparent;}QDialog#ToolBoxDialog QListView::item:hover{color:#FF9900;background:#6B7276;}
六、使用qss文件
设置外部qss文件的流程如下:
找到qss文件加载qss文件通过QApplication::setStyleSheet设置样式表这样是一种比较冷通的设置方式,一旦qss文件比较大,会出现这句代码卡顿的情况。如果想要更好的性能,qss建议还是分开来写,至于怎么合理的拆分qss文件,可以根据自己的需求来拆分
这里提供我之前使用过的两种方式
控件级别,每个控件对应一个qss文件功能级别,一个功能模块一个qss文件拆分的好处我就不多说了,谁用谁知道!
话不多说,直接上代码了。
SetCurrentDirectory(a.applicationDirPath().toStdWString().c_str());QString qssFile = a.applicationDirPath() \\TemplateLayout.qss;QFile qss(qssFile);qss.open(QFile::ReadOnly);if (qss.isOpen()){ QString btnstylesheet = QObject::tr(qss.readAll()); a.setStyleSheet(btnstylesheet); qss.close();}