《QtCreator快速入门》第2版第8章界面外观(1课时)一个完善的应用程序不仅应该有实用的功能,还要有一个漂亮的外观,这样才能使应用程序更加友善,更加吸引用户。作为一个跨平台的UI开发框架,Qt提供了强大而灵活的界面外观设计机制。这一章将学习在Qt中设计应用程序外观的相关知识,在本章开始会对Qt风格QStyle和调色板QPalette进行简单介绍,然后再对Qt样式表(QtStyleSheets)进行重点讲解,最后还会涉及不规则窗体和透明窗体的实现方法。主要内容8.1Qt风格8.2Qt样式表8.3特殊效果窗体8.4小结8.1Qt风格Qt中的各种风格是一组继承自QStyle的类。QStyle类是一个抽象基类,它封装了一个GUI的外观,Qt的内建(built-in)部件使用它来执行几乎所有的绘制工作,以确保它们看起来可以像各个平台上的本地部件一样。一些风格已经内置在了Qt中,例如Windows风格和Motif风格;而有些风格只在特定的平台上才有效,例如WindowsXP风格、WindowsVista风格和MacOSX风格。使用不同风格预览程序首先进入设计模式,可以先修改界面,然后打开“工具”→“界面编辑器”→“预览于”菜单,这里列出了现在可用的几种风格,比如选择“CDE风格”,预览效果如下图所示。使用不同风格运行程序如果想使用不同的风格来运行程序,那么只需要调用QApplication的setStyle()函数指定要使用的风格即可。例如,在main()函数的“QApplicationa(argc,argv);”一行代码后添加如下一行代码:a.setStyle(newQMotifStyle);这时运行程序,便会使用Motif风格。而如果不想整个应用程序都使用相同的风格,那么可以调用部件的setStyle()函数来指定该部件的风格。调色板调色板QPalette类包含了部件各种状态的颜色组。一个调色板包含三种状态:激活(Active)、失效(Disabled)和非激活(Inactive)。Qt中的所有部件都包含一个调色板,并且使用各自的调色板来绘制它们自身,这样可以使用户界面更容易配置,也更容易保持一致。调色板中的颜色组包括:激活颜色组QPalette::Active,用于获得键盘焦点的窗口;非激活颜色组QPalette::Inactive,用于其他的窗口;失效颜色组QPalette::Disabled,用于因为一些原因而不可用的部件(不是窗口)。要改变一个应用程序的调色板,可以先使用QApplication::palette()函数来获取其调色板,然后对其进行更改,最后再使用QApplication::setPalette()函数来使用该调色板。更改了应用程序的调色板,会影响到该程序的所有窗口部件。如果要改变一个部件的调色板,可以调用该部件的palette()和setPalette()函数,这样只会影响该部件及其子部件。示例://获取pushButton的调色板QPalettepalette1=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);QPalettepalette2=ui-lineEdit-palette();//设置行编辑器不可用时的背景颜色为蓝色palette2.setColor(QPalette::Disabled,QPalette::Base,Qt::blue);ui-lineEdit-setPalette(palette2);设置调色板颜色时可以使用setColor()函数,这个函数需要指定颜色角色(ColorRole)。在QPalette中,颜色角色用来指定该颜色所起的作用,例如是背景颜色或者是文本颜色等,主要的颜色角色如下表所示。8.2Qt样式表Qt样式表是一个可以自定义部件外观的十分强大的机制。Qt样式表的概念、术语和语法都受到了HTML的层叠样式表(CascadingStyleSheets,CSS)的启发,不过与CSS不同的是,Qt样式表应用于部件的世界。Qt样式表概述Qt样式表语法自定义部件外观和换肤Qt样式表概述样式表使用文本描述。可以使用QApplication::setStyleSheet()函数将其设置到整个应用程序上;也可以使用QWidget::setStyleSheet()函数将其设置到一个指定的部件(还有它的子部件)上。如果在不同的级别都设置了样式表,那么Qt会使用所有有效的样式表,这被称为样式表的层叠。使用代码设置样式表例如://设置pushButton的背景为黄色ui-pushButton-setStyleSheet(background:yellow);//设置horizontalSlider的背景为蓝色ui-horizontalSlider-setStyleSheet(background:blue);这样调用指定部件的setStyleSheet()函数只会对这个部件应用该样式表,如果想对所有的相同部件都使用相同的样式表,那么可以在它们的父部件上设置样式表。比如这里两个部件都在MainWindow上,可以为MainWindow设置样式表:setStyleSheet(QPushButton{background:yellow}QSlider{background:blue});这样,以后再往主窗口上添加的所有QPushButton部件和QSlider部件的背景色都会改为这里指定的颜色。在设计模式使用样式表进入设计模式。在界面上点击鼠标右键,在弹出的菜单中选择“改变样式表”,这时会出现编辑样式表对话框,在其中输入如下代码:QPushButton{}注意光标留在第一个大括号后。然后点击上面“添加颜色”选项后面的下拉箭头,在弹出的列表中选择“background-color”一项。这时会弹出选择颜色对话框,大家可以随便选择一个颜色,然后点击“确定按钮”,这时会自动添加代码:QPushButton{background-color:rgb(0,85,255);}根据选择的颜色不同,rgb()中的参数的数值也会不同。可以看到,在这里设置样式表不仅很便捷而且很直观,不仅可以设置颜色,还可以使用图片,使用渐变颜色,或者更改字体。相似的,可以再设置QSlider的背景色。样式表语法样式规则:样式表包含了一系列的样式规则,一个样式规则由一个选择符(selector)和一个声明(declaration)组成。选择符指定了受该规则影响的部件;声明指定了这个部件上要设置的属性。例如:QPushButton{color:red}在这个样式规则中,QPushButton是选择符,{color:red}是声明,而color是属性,red是值。这个规则指定了QPushButton和它的子类应该使用红色作为它们的前景色。Qt样式表中一般不区分大小写,例如color、Color、COLOR和COloR表示相同的属性。只有类名,对象名和Qt属性名是区分大小写的。一些选择符可以指定相同的声明,只需要使用逗号隔开,例如:QPushButton,QLineEdit,QComboBox{color:red}一个样式规则的声明部分是一些属性:值对组成的列表,它们包含在大括号中,使用分号隔开。例如:QPushButton{color:red;background-color:white}选择符类型Qt样式表支持在CSS2中定义的所有选择符。下表列出了最常用的选择符类型。子控件对一些复杂的部件修改样式,可能需要访问它们的子控件,例如QComboBox的下拉按钮,还有QSpinBox的向上和向下的箭头等。选择符可以包含子控件来对部件的特定子控件应用规则,例如:QComboBox::drop-down{image:url(dropdown.png)}这样的规则可以改变所有的QComboBox部件的下拉按钮的样式。伪状态选择符可以包含伪状态来限制规则在部件的指定的状态上应用。伪状态出现在选择符之后,用冒号隔离,例如:QPushButton:hover{color:white}这个规则表明当鼠标悬停在一个QPushButton部件上时才被应用。伪状态可以使用感叹号来表示否定,例如要当鼠标没有悬停在一个QRadioButton上时才应用规则,那么这个规则可以写为:QRadioButton:!hover{color:red}伪状态还可以多个连用,达到逻辑与效果,例如当鼠标悬停在一个被选中的QCheckBox部件上时才应用规则,那么这个规则可以写为:QCheckBox:hover:checked{color:white}如果有需要,也可以使用逗号来表示逻辑或操作,例如:QCheckBox:hover,QCheckBox:checked{color:white}冲突解决当几个样式规则对相同的属性指定了不同的值时就会产生冲突。例如:QPushButton#okButton{color:gray}QPushButton{color:red}这样okButton的color属性便产生了冲突。解决这个冲突的原则是:特殊的选择符优先。在这里,因为QPushButton#okButton一般代表一个单一的对象,而不是一个类所有的实例,所以它比QPushButton更特殊,那么这时便会使用第一个规则,okButton的文本颜色为灰色。相似的,有伪状态比没有伪状态优先。如果两个选择符的特殊性相同,则后面出现的比前面的优先。Qt样式表使用CSS2规范来确定规则的特殊性。层叠样式表可以被设置在QApplication上,或者父部件上,或者子部件上。部件有效的样式表是通过部件祖先的样式表和QApplication上的样式表合并得到的。当发生冲突时,部件自己的样式表优先于任何继承的样式表,同样,父部件的样式表优先于祖先的样式表。自定义部件外观当使用样式表时,每一个部件都被看做是拥有四个同心矩形的盒子,如下图所示。这四个矩形分别是内容(content)、填衬(padding)、边框(border)和边距(margin)。边距、边框宽度和填衬等属性的默认值都是0,这样四个矩形恰好重合。/****************主界面背景*******************/QMainWindow{/*背景图片*/background-image:url(:/image/beijing01.png);}/****************按钮部件*******************/QPushButton{/*背景色*/background-color:rgba(100,225,100,30);/*边框样式*/border-style:outset;/*边框宽度为4像素*/border-width:4px;/*边框圆角半径*/border-radius:10px;/*边框颜色*/border-color:rgba(255,225,255,30);/*字体*/font:bold14px;/*字体颜色*/color:rgba(0,0,0,100);/*填衬*/padding:6px;}/*鼠标悬停在按钮上时*/QPushButton:hover{background-color:rgba(100,255,100,100);border-color:rgba(255,225,255,200);color:rgba(0,0,0,200);}/*按钮被按下时*/QPushBu