Qt中的各种风格是一组继承自QStyle的类。QStyle类是一个抽象基类,封装了 一个GUI的外观,Qt的内建(built-in)部件使用它来执行几乎所有的绘制工作,以确保它们看起来可以像各个平台上的本地部件一样。
Qt提供的风格类如下表所列:
类名 介绍
QCDEStyle CDE(Common Desktop Environment)风格
QCleanlooksStyle 类似于GNOME中的Clearlook风格
QGtkStyle GTK +风格
QMotifStyle Motif风格
QMacStyle Mac OS X风格
QPlastiqueStylc 类似于KDE中的Plastik风格
QWindowsStyle 微软Windows风格
QWindowsVistaStyle 微软Windows Vista风格
QWinclowsXPStyle 微软Windows XP风格
选择“工具→From Editor→Preview in”菜单项,这里列出了现在可用的几种风格。
调用setStyle()函数指定要使用的风格即可。(不仅可以应用到整个应用程序在,还可以应用到某个特定部件中)
在main()函数的“QApplication a(argc,argv);”一行代码后添加如下一行代码:
a.setStyle(new QMotifStyle); //整个应用程序使用了Motify风格
ui->progressBar->setStyle(new QWindowsXPStyle); //进度条部件使用了Windows XP的风格。
注:可以使用QStyleFactory::keys()函数来获取当前系统所支持的风格。
调色板QPalette类包含了部件各种状态的颜色组。一个调色板包含3种状态:激活(Active)、失效(Disabled)和非激活(Inactive)。
调色板中的颜色组包括:
要改变一个应用程序或部件的调色板,先使用palette()函数来获取其调色板,然后对其进行更改,最后再使用SetPalette()函数来使用该调色板。
例如:
//获取 pushButton 的调色板
QPalette palette1 = ui->pushButton->palette();
//设置按钮文本颜色为红色
palette1.setColor(QPalette::ButtonText,Qt::red);
//设置按钮背景色为绿色
palette1.setColor(QPalette::Button,Qt::green);
//pushButton 使用修改后的调色板
ui->pushButton->setPalette(palette1);
//设置 lineEdit 不可用
ui->lineEdit->setDisabled(true);
QPalette palette2 = ui->lineEdit->palette();
//设置行编辑器不可用时的背景颜色为蓝色
palette2.setColor(QPalette::Disabled,QPalette::Base,Qt::blue);
ui->lineEdit->setPalette(palette2);
设置调色板颜色时可以使用setColor()函数,这个函数需要指定颜色角色(Color Role)。
在QPalette中,颜色角色用来指定该颜色所起的作用,例如是背景颜色或者是文本颜色等,主要的颜色角色如下表所列:
常量 描述
QPalette::Window 一个一般的背景颜色
QPalette::WindowText 一个一般的前景颜色
QPalette::Base 主要作为输人部件(如QLineEdit)的背贵色,也可用作QComboBox的下拉列表的背景色
QPalette::AlternateBase 在交种行颜色的视图中作为交替背景色
QPalette::ToolTipBase 作为QToolTip和QWhatsThis的背景色
QPalette::ToolTipText 作为QToolTip和QWhatsThis的前景色
QPalette::Text 和Base—起使用,作为前景色
QPalette::Button 按钮部件背景色
QPalette::ButtonText 按钮部件前景色
Qt样式表的概念、术语和语法都受到了HTML的层叠样式表(Cascading Style Sheets, CSS)的启发,不过与CSS不同的是,Qt样式表应用于部件的世界。
样式表使用文本描述,可以使用 QApplication:: setStyleSheet() 函数将其设置到整个应用程序上,也可以使用 QWidget::setStyleSheet() 函数将其设置到一个指定的部件(还有它的子部件)上。
如果在不同的级别都设置了样式表,那么Qt会使用所有有效的样式表,这被称为样式表的层叠。
如:
//设置pushButton的背景颜色为黄色
ui->pushButton->setStyleSheet("background:yellow");
//设置horizontalSlider的背贵为蓝色
ui->horizontalSlider->setStyleSheet("background:blue");
这样调用指定部件的setStyleSheet()函数只会对这个部件应用该样式表,如果想对所有的相同部件都使用相同的样式表,那么可以在它们的父部件上设置样式表。
即,this->setStyleSheet(“background:blue”);
这样,以后再往主窗口上添加的所有QPushButton部件和QSlider部件的背景色都会改为这里指定的颜色。
进入设计模式,在界面上右击,在弹出的菜单中选择“改变样式表”,这时会出现编辑样式表对话框,然后进行编辑或从工具栏中选择相应的添加。
也可以按照这种方法在指定的部件上添加样式表。
使用Style Sheets时,所有的部件都被视为有四个同心矩形的盒子(box):边缘矩形(margin rectangle),边框矩形(border rectangle),填充矩形(padding rectangle)和内容矩形(content rectangle)。
盒子模型对四个矩形有详细的描述,
边缘,边框宽度和填充属性默认为0。这样四个矩形(margin, border, padding和content)重合。
注:使用background-image属性,你可以为部件指定背景图片。默认地,背景图片只画在边框以内。背景图片不随部件大小改变而改变。
提供一个随部件大小改变而改变的背景或皮肤,必须使用border-image。因为border-image属性提供了一个备选背景,所以并不需要再为部件指定一个背景图片。在两者都指定的情况下,border-image将画于background-image之上。
①样式规则
一个样式规则由一个选择器和声明组成,选择器指定哪些部件由规则影响,声明指定哪些属性应该在部件上进行设置。
例如:
QPushButton { color: red }
QPushButton是选择器,{ color: red }是声明,该规则指定QPushButton及其子类(例如:MyPushButton)应使用红色作为前景色。
几个选择器可以指定相同的声明,使用逗号(,)来分隔选择器。
例如:
QPushButton, QLineEdit, QComboBox { color: red }
声明部分的规则是一个属性值对(property: value)列表,包含在花括号中,以分号分隔。
例如:
QPushButton { color: red; background-color: white }
注:QSS通常不区分大小写(即:color、Color、COLOR、cOloR指同一属性),唯一例外就是类名(class names)、 对象名(object names)、属性名(property names)区分大小写。
②选择器类型
选择器 示例 说明
通用选择器 * 匹配所有部件
类型选择器 QPushButton 匹配QPushButton及其子类的实例
属性选择器 QPushButton[flat=”false”] 匹配QPushButton中flat属性为false的实例。
类选择器 .QPushButton 匹配QPushButton的实例,但不包含子类。相当于*[class~=”QPushButton”]。
ID选择器 QPushButton#okButton 匹配所有objectName为okButton的QPushButton实例。
后代选择器 QDialog QPushButton 匹配属于QDialog后代(孩子,孙子等)的QPushButton所有实例。
子选择器 QDialog > QPushButton 匹配属于QDialog直接子类的QPushButton所有实例。
③子控件
对于样式复杂的部件,需要访问子控件,
例如:QComboBox的下拉按钮或QSpinBox的上下箭头:
QComboBox::drop-down { image: url(dropdown.png) }
//上述规则指定了QComboBoxe下拉按钮样式。
width和height属性可用于控制子控件的大小,注意:设置一个图片会隐式地设置子控件的大小。
相对定位(position : relative):可以改变子控件相对初始位置的偏移量。
绝对定位(position : absolute):允许子控件改变位置和的大小而不受参考元素限制。
④伪选择器
⑤解决冲突
示例一
当样式中指定相同的属性具有不同的值时,就会出现冲突。例如:
QPushButton#okButton { color: blue }
QPushButton { color: red }
要解决这个冲突,必须考虑到的选择器的特殊性。
上面的例子,QPushButton#okButton 被认为比 QPushButton 更具体,因为它通常是指单个对象,而不是一类的所有实例。
所以 okButton 这个按钮文本颜色会设置为blue,而其它按钮文本仍然设置为red。
示例二
同样的,利用伪状态比不指定伪状态那些选择器更具体。因此,下面的样式指定一个QPushButton应该有鼠标悬停文本颜色为白色,否则文本颜色为红色。
QPushButton:hover { color: white }
QPushButton { color: red }
示例三
QPushButton:hover { color: white }
QPushButton:enabled { color: red }
这里,两个选择器有相同的特殊性,但后一条规则优先,即QPushButton:enabled { color: red }优先级更高,所以按钮默认 enabled 的情况下,无论鼠标是否悬停在按钮上,文本颜色始终为红色。
想要鼠标是否悬停在按钮上文本颜色为白色,根据后面规则优先级更高的原则,则使颜色为white的规则在后面即可,如下所示:
QPushButton:enabled { color: red }
QPushButton:hover { color: white }
或者,可以使文本颜色为白色的规则更加具体:
QPushButton:hover:enabled { color: white }
QPushButton:enabled { color: red }
示例四
类似的问题出现在类型选择器一起使用。例如:
QPushButton { color: red }
QAbstractButton { color: blue }
两个规则应用于 QPushButton 实例(因为 QPushButton 继承自 QAbstractButton)并有color属性的冲突。
因为 QPushButton 继承 QAbstractButton,所以 QPushButton 比 QAbstractButton 更具体,本应该按钮文本颜色为红色。
然而,对于QSS的计算,所有的类型选择具有相同的特殊性,最后出现的规则优先,所以实际上按钮文本颜色为蓝色。
如果需要设置QPushButtons为红色文字,需要重新排序规则。
总结
为了确定一个规则的特殊性,QSS遵循CSS2规范,一个选择器的特殊性的计算方法如下:
⑥级联效应
QSS可以在QApplication、父部件、子部件中设置。冲突发生时,不论冲突规则的特殊性,部件自身的样式表总优先于任何继承样式表。
⑦继承性
在经典的CSS中,当字体和颜色没有明确设置时,它就会自动从父继承。当使用QSS时,部件不会自动从父继承字体和颜色。
例如,一个QGroupBox中包含QPushButton:
qApp->setStyleSheet("QGroupBox { color: red; } ");
QPushButton不会继承其父QGroupBox的颜色,而是显示系统的颜色。
①CSS文字属性
CSS文字属性及示例 说明
color:#999999; 文字颜色
font-family:Microsoft Yahei,sans-serif; 字体家族
font-size:16pt; 字体大小
font-style:itelic;(normal、oblique) 字体样式
letter-spacing:1pt; 字间距离
line-height:200%; 设置行高
font-weight:bold;(lighter、normal、数值900) 字体粗细
text-decoration:underline;(line-through、overline、none) 字体修饰
text-align:left;(right、center、justify) 文字左对齐
vertical-align:top;(bottom、middle、text-top、text-bottom) 垂直对齐方式
text-transform:uppercase;(lowercase、capitalize) 英文大写
font-variant: small-caps;(normal) 小型大写字母
②CSS背景样式
CSS背景样式及示例 说明
background:black; 背景颜色为黑色
background-color:#F5E2EC; 背景颜色
background-image:url(/image/bg.gif); 背景图片
background:transparent; 透视背景
background-repeat : repeat; 重复排列-网页默认
background-position : center; 指定背景位置-居中对齐
③CSS边框空白
CSS边框空白及示例 说明
padding:5px 10px 5px 10px; 所有边框留空白
padding-top:10px; 上边框留空白
padding-right:10px; 右边框留空白
padding-bottom:10px; 下边框留空白
padding-left:10px; 左边框留空白
④CSS框线
CSS框线建议书写方式 说明
border:1px solid red; 所有边框线
border-top:1px solid #6699cc; 上框线
border-bottom:1px solid #6699cc; 下框线
border-left:1px solid #6699cc; 左框线
border-right:1px solid #6699cc; 右框线
border-radius:8px; 边框圆角半径
以上是建议书写方式,但也可以使用常规书写方式,如下表所示:
CSS框线常规书写方式 说明
border-top-color:#369; 设置上框线颜色
border-top-width:1px; 设置上框线宽度
border-top-style:solid 设置上框线样式
其他框线样式如下:
solid - 实线
dotted - 虚线
double - 双线
inset - 凹框
outset - 凸框
groove - 立体内凸框
ridge - 立体浮雕框
⑤CSS边界样式
CSS边界样式及示例 说明
margin-top:10px; 上边界值
margin-right:10px; 右边界值
margin-bottom:10px; 下边界值
margin-left:10px; 左边界值
注:px:相对长度单位,像素(Pixel)。pt:绝对长度单位,点(Point)。
按钮的三态,指的是普通态、鼠标的悬停态、按下态。Qt中如果使用的是默认按钮,三态的效果是有的,鼠标放上去会变色,点击的时候有凹陷的效果。
但是如果自定义按钮实现三态效果有三种方法,一种是设置背景图,主要是需要自己设计按钮的效果图,另一种是通过样式控制不同状态下按钮的显示效果,还有一种是通过qss文件实现。
样式表设置背景图可以使用setStyleSheet函数,在程序里设置按钮的样式表,具体程序如下所示:
ui->pbut_boardimg_reset->setStyleSheet("QPushButton{border-image: url(:/new/prefix1/image/showmodeimag/ok.png);}"
"QPushButton:hover{border-image: url(:/new/prefix1/image/showmodeimag/ok.png);}"
"QPushButton:pressed{border-image: url(:/new/prefix1/image/showmodeimag/ok1.png);}");
也可以在 QtDesigner 上,即ui文件上的按钮处编辑样式表
样式表如下:
QPushButton{border-image: url(:/new/prefix1/image/showmodeimag/ok.png)}
QPushButton:hover{border-image: url(:/new/prefix1/image/showmodeimag/ok.png)}
QPushButton:pressed{border-image: url(:/new/prefix1/image/showmodeimag/ok1.png)}
注:三个 .png 图片是背景图。
/*按钮普通态*/
QPushButton
{
/*字体为微软雅黑*/
font-family:Microsoft Yahei;
/*字体大小为20点*/
font-size:20pt;
/*字体颜色为白色*/
color:white;
/*背景颜色*/
background-color:rgb(14 , 150 , 254);
/*边框圆角半径为8像素*/
border-radius:8px;
}
/*按钮停留态*/
QPushButton:hover
{
/*背景颜色*/
background-color:rgb(44 , 137 , 255);
}
/*按钮按下态*/
QPushButton:pressed
{
/*背景颜色*/
background-color:rgb(14 , 135 , 228);
/*左内边距为3像素,让按下时字向右移动3像素*/
padding-left:3px;
/*上内边距为3像素,让按下时字向下移动3像素*/
padding-top:3px;
}
注:注释只能使用/* */,#和//均无效。
①新建qss文件
新建一个txt文本文档,并修改后缀名为.qss,文件名任取,例如:myStyleSheet.qss,在这个qss文件写入qss语句。内容如下:
/*按钮普通态*/
QPushButton
{
/*字体为微软雅黑*/
font-family:Microsoft Yahei;
/*字体大小为20点*/
font-size:20pt;
/*字体颜色为白色*/
color:white;
/*背景颜色*/
background-color:rgb(14 , 150 , 254);
/*边框圆角半径为8像素*/
border-radius:8px;
}
/*按钮停留态*/
QPushButton:hover
{
/*背景颜色*/
background-color:rgb(44 , 137 , 255);
}
/*按钮按下态*/
QPushButton:pressed
{
/*背景颜色*/
background-color:rgb(14 , 135 , 228);
/*左内边距为3像素,让按下时字向右移动3像素*/
padding-left:3px;
/*上内边距为3像素,让按下时字向下移动3像素*/
padding-top:3px;
}
②引用qss文件
引用qss文件有两种方式,一是引用qss文件的外部路径,二是引用qss文件的资源路径。
③ 程序设置样式表
//这是在Qt的资源下的文件,可以不用在资源下
QFile file(":/qss/myStyleSheet.qss");
//只读方式打开文件
file.open(QFile::ReadOnly);
//读取文件的所有内容,并转换成QString类型
QString styleSheet = tr(file.readAll());
//当前窗口设置样式表
//this->setStyleSheet(styleSheet);
//指定按钮设置样式表
ui->pushButton->setStyleSheet(styleSheet);
ui->pushButton_2->setStyleSheet(styleSheet);
如果想设置单个的指定按钮样式,则通过UI指向按钮进行修改样式表就可以了。
补充:QT样式表属性大全
(1)Box样式
●width:宽度
●height:高度
●max-width:最大宽度
●max-height:最大高度
●min-width:最小宽度
●min-height:最小高度
●margin:边距尺寸
●margin-top
●margin-right
●margin-bottom
●margin-left
●padding:填充尺寸
●padding-top
●padding-right
●padding-bottom
●padding-left
(2)位置样式
●position:定位属性,如果position是relative(默认值),则将子控件移动一定的偏移量;如果position是absolute,则指定子控件相对于父控件位置
●top
●right
●bottom
●left
(3)字体样式
●font:字体样式
●font-family:字体类型
●font-size:字体大小
●font-style:字体风格
●font-weight:字体粗细
●color:字体颜色
(4)文本样式
●text-decoration:文本修饰
●text-align:水平对齐
(5)背景样式
●background:背影样式
●background-color:背景颜色
●background-image:背景图片
●background-repeat:背景重复
●background-position:背景定位
●background-attachment:背景固定
●background-clip:设置元素的背景(背景图片或颜色)是否延伸到边框下面。
●background-origin:指定背景图片background-image 属性的原点位置的背景相对区域
(6)边框样式
●border:边框样式
●border-top
●border-top-color
●border-top-style
●border-top-width
●border-right
●border-right-color
●border-right-style
●border-right-width
●border-bottom
●border-bottom-color
●border-bottom-style
●border-bottom-width
●border-left
●border-left-color
●border-left-style
●border-left-width
●border-color:边框颜色
●border-style:边框风格
●border-width:边框宽度
●border-image:边框图片
●border-radius:元素的外边框圆角
●border-top-left-radius
●border-top-right-radius
●border-bottom-right-radius
●border-bottom-left-radius
(7)颜色样式
●alternate-background-color:交替行颜色
●gridline-color:QTableView中网格线的颜色
●selection-color:所选文本或项目的前景色
●selection-background-color:所选文本或项目的背景色
(8)轮廓样式
●outline:轮廓属性
●outline-color:设置一个元素轮廓的颜色
●outline-offset:设置 outline 与元素边缘或边框之间的间隙
●outline-style:设置元素轮廓的样式
●outline-radius:设置元素的轮廓圆角
●outline-bottom-left-radius
●outline-bottom-right-radius
●outline-top-left-radius
●outline-top-right-radius
(9)其他样式
●opacity:控件的不透明度
●icon-size:控件中图标的宽度和高度。
●image:在子控件的内容矩形中绘制的图像
●image-position:在Qt 4.3及更高版本中,可以使用相对或绝对位置指定图像图像位置的对齐
●spacing:控件中的内部间距
●subcontrol-origin:父元素中子控件的原始矩形。
●subcontrol-position:subcontrol-origin指定的原始矩形内子控件的对齐方式。
●button-layout:QDialogButtonBox或QMessageBox中按钮的布局
●messagebox-text-interaction-flags:消息框中文本的交互行为
●dialogbuttonbox-buttons-have-icons:QDialogButtonBox中的按钮是否显示图标
●titlebar-show-tooltips-on-buttons:是否在窗口标题栏按钮上显示工具提示。
●widget-animation-duration:动画应该持续多少(以毫秒为单位)。值等于零意味着将禁用动画
●lineedit-password-character:该QLineEdit的密码字符作为Unicode数字。
●lineedit-password-mask-delay:在将lineedit-password-character应用于可见字符之前,QLineEdit密码掩码延迟(以毫秒为单位)
●paint-alternating-row-colors-for-empty-area:QTreeView是否为空白区域(即没有项目的区域)绘制交替的行颜色
●show-decoration-selected:控制QListView中的选择是覆盖整个行还是仅覆盖文本的范围。
使用部件遮罩 (mask)来实现不规则窗体。
如果想实现窗体内容部件的透明效果,只需在设置其背景色时指定alpha值即可。
QPushButton{background-color:rgba(255, 255, 255, 100)}
其中rgba()中的a就是指alpha,取值为0〜255,取值为0时完全透明,取值为255时完全不透明。
①方式一:
setWindowOpacity(0.5); // 设置窗口的不透明度为0.5
使用setWindowOpacity()函数就可以实现窗口的透明效果,参数取值范围为0.0〜1.0,当取值为0.0时完全透明,取值为1.0时完全不透明。
②方式二:
//添加如下两行代码:
setWindowFlags(Qt::FramelessWindowHint);
setAttribute(Qt::WA_TranslucentBackground);
这里使用了setAttribute()函数指定窗口的Qt::WA_TranslucentBackground属性,它可以使窗体背景透明,而其中的部件不受影响。
不过在Windows下,还要使用setWindowFlags()函数指定Qt::FramelessWindowHint标志,这样才能实现透明效果。
这种方法窗口没有了标题栏,并且实现的效果是背景完全透明的,要是还想实现半透明效果,可以使用重绘事件:
//先在widget.h文件中声明paintEvent()函数:
protected:
void paintEvent(QPaintEvent *);
//然后到widget.cpp文件中添加头文件#include ,再进行paintEvent()函数的定义:
void Widget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.fillRect(rect(), QColor(255,255,255,100));
}
这里先使用rect()函数获取窗口的内部矩形,它不包含任何边框。然后使用半透明的白色对这个矩形进行填充。
对于fillRect()函数,可以指定任意的一个区域,所以可以实现窗体的部分区域全部透明,部分区域半透明或者不透明的效果。
注:使用方式一会使整个应用程序都成为半透明效果;而使用方式二,可以实现只是顶层窗口的背景透明,不过,它没有了标题栏和边框,需要手动为其添加一个标题栏。