Qt界面渲染
Qt中界面的渲染,吸收了html的css的渲染风格,渲染风格很类似。
Qt界面风格
Qt能够显示不同的平台的界面风格,Qt中的各种风格是一组继承自QStyle的类。
QStyle类是一个抽象基类,封装了一个GUI的外观,Qt的内建(built-in)部件使用它来执行几乎所有的绘制工作,以确保它们看起来可以像各个平台上的本地部件一样。
QStyle对象可以通过QStyleFactory类创建,首先通过keys()函数获取可用的风格,然后使用create()函数创建一个QStyle对象。
一般windows风格和fusion风格是默认可用的,而有些风格只在特定的平台上才有效,例如windowsxp风格、windowsvista风格、gtk风格和macintosh风格。
Qt界面风格设置
整体使用:
如果想使用不同的风格来运行程序,那么只需要在main中调用QApplication的setStyle()函数指定要使用的风格即可。
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.setStyle(QStyleFactory::create("Windows"));
w.show();
return a.exec();
}
局部使用:
而如果不想整个应用程序都使用相同的风格,那么可以调用部件的setStyle()函数来指定该部件的风格。
Qt调色板
调色板QPalette类包含了部件各种状态的颜色组。
颜色组:颜色角色(可以看作为指定颜色的对象)的集合,
一个调色板包含三种状态:激活(Active)、失效(Disabled)和非激活(Inactive)。
Qt中的所有部件都包含一个调色板,并且使用各自的调色板来绘制它们自身,这样可以使用户界面更容易配置,也更容易保持一致。
调色板中的颜色组包括:
1.激活颜色组QPalette::Active,用于获得键盘焦点的窗口;
2.非激活颜色组QPalette::Inactive,用于其他的窗口;
3.失效颜色组QPalette::Disabled,用于因为一些原因而不可用的部件(不是窗口)。
如果要改变一个应用程序的调色板,可以先使用QApplication::palette()函数来获取其调色板;然后对其进行更改,最后再使用QApplication::setPalette()函数来使用该调色板。更改了应用程序的调色板,会影响到该程序的所有窗口部件。
如果要改变一个部件的调色板,可以调用该部件的palette()和setPalette()函数,这样只会影响该部件及其子部件。
设置调色板颜色时可以使用setColor()函数,这个函数需要指定颜色角色(Color Role)。
在QPalette中,颜色角色用来指定该颜色所起的作用范围,例如是背景颜色或者是文本颜色等,主要的颜色角色如表所示:
使用举例:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.setStyle(QStyleFactory::create("Windows"));
QPalette palette1 = w.palette(); //1.获取调色板
palette1.setColor(QPalette::ButtonText, Qt::red); //2.设置调色板
palette1.setColor(QPalette::Disabled,QPalette::ButtonText, Qt::black);
w.setPalette(palette1); //部件绑定调色板
w.show();
return a.exec();
}
Qt样式表
Qt样式表是一个可以自定义部件外观的十分强大的机制。
Qt样式表的概念、术语和语法都受到了HTML的层叠样式表(Cascading Style Sheets,CSS)的启发,不过与CSS不同的是,Qt样式表应用于部件的世界。
样式表与调色板区别:
Qt的样式/颜色机制主要有两个体系:一个是用调色板(QPalette) 另一个是样式表Style Sheets。在Qt4之前 Qt的图形化组件的各种颜色(前景色、背景色、文本色、选中色、非选中色等)有不同的函数,例如setBackgroundColor函数。但在Qt4之后这些函数不在使用,而是由QPalette调色板管理,当然样式表(Style Sheets)也是可以的,在Qt4.5以后Qt样式表已经完美支持Mac系统了,所有也是个不错的选择,特别是对有CSS使用经验的人来说。—详解Qt样式/颜色机制:调色板(QPalette)与样式表(Style Sheets)
样式表介绍
1.可以使用QApplication::setStyleSheet()函数将其设置到整个应用程序上;
2.也可以使用QWidget::setStyleSheet()函数将其设置到一个指定的部件(还有它的子部件)上。
3.如果在不同的级别都设置了样式表,那么Qt会使用所有有效的样式表,这被称为样式表的层叠。
样式表语法
样式表包含了一系列的样式规则,一个样式规则由一个选择器(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部件的下拉按钮的样式。
伪状态:
选择器可以包含伪状态来限制规则在部件的指定的状态上应用。
qt QSS文件伪状态列表
伪状态 | 描述 |
---|---|
checked | button部件被选中 |
disabled | 部件被禁用 |
enabled | 部件被启用 |
ocus | 部件获得焦点 |
:hover | 鼠标位于部件上 |
indeterminate | checkbox或radiobutton被部分选中 |
off | 部件可以切换,且处于off状态 |
on | 部件可以切换,且处于on状态 |
pressed | 部件被鼠标按下 |
unchecked | button部件未被选中 |
伪状态出现在选择器之后,用冒号隔离:
例如:
QPushButton:hover{color:white}
这个规则表明当鼠标悬停在一个QPushButton部件上时才被应用。
伪状态可以使用感叹号来表示否定:
例如:
要当鼠标没有悬停在一个QRadioButton上时才应用规则,那么这个规则可以写为:
QRadioButton:!hover{color:red}
使用冒号,多个伪状态连用,达到逻辑与效果:
例如当鼠标悬停在一个被选中的QCheckBox部件上时才应用规则,那么这个规则可以写为:
QCheckBox:hover:checked{color:white}
使用逗号来表示逻辑或操作:
例如:
QCheckBox:hover,QCheckBox:checked{color:white}
多层次样式冲突
当几个样式规则对相同的属性指定了不同的值时就会产生冲突。
解决这个冲突的原则是:
特殊的选择器优先,有伪状态比没有伪状态优先;
两个选择器的特殊性相同,则后面出现的比前面的优先;
部件自己的样式表优先于任何继承的样式表,同样,父部件的样式表优先于祖先的样式表;
Qt样式表使用CSS2规范来确定规则的特殊性;
注意:
样式表可以被设置在QApplication上,或者父部件上,或者子部件上。
部件有效的样式表是通过部件祖先的样式表和QApplication上的样式表合并得到的。
样式表使用
样式表来切换图片
注意:使用setStyleSheet进行显示,目前不能拉伸铺满。
具体策略:QT实现背景图片多种填充方式:居中、平铺、缩放、拉伸
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QPushButton>
#include <QLabel>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
public slots:
void on_switch_btn_clicked();
private:
QPushButton * switch_btn;
QLabel * picture_brow;
};
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
#include <QPalette>
#include <QVBoxLayout>
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
QPalette palette = this->palette();
palette.setColor(QPalette::Background,Qt::black);
setPalette(palette); //设置主窗口背景
QVBoxLayout *layout = new QVBoxLayout(this);
switch_btn = new QPushButton();
picture_brow = new QLabel(this);
switch_btn->setText("图片切换");
picture_brow->setText("hello world");
picture_brow->setStyleSheet("color:rgba(100,255,100,100)");
picture_brow->setAlignment(Qt::AlignCenter);
//picture_brow->setGeometry(0,0,200,300);//布局管理器控制了子部件,setGeometry失效。
picture_brow->setFixedSize(QSize(400,300)); //固定picture_brow大小。
picture_brow->show();
layout->addWidget(picture_brow);
layout->addWidget(switch_btn);
setLayout(layout);
connect(switch_btn,SIGNAL(clicked()),this,SLOT(on_switch_btn_clicked()));
}
void Widget::on_switch_btn_clicked()
{
qDebug() << "on_switch_btn_clicked" ;
static bool flag = false;
if((flag = !flag))
{
picture_brow->setStyleSheet("border-image:url(E:/QTWorkspace/lession/build-QstyleSheet-Desktop_Qt_5_9_9_MinGW_32bit-Debug/bmp/155771589037954032.jpg);\
background-repeat: no-repeat;background-position: center;background-attachment:fixed;");
// picture_brow->setStyleSheet("background-image:url(E:/QTWorkspace/lession/build-QstyleSheet-Desktop_Qt_5_9_9_MinGW_32bit-Debug/bmp/155771589037954032.jpg);\
background-repeat: no-repeat;background-position: center;background-attachment:fixed;");
}
else
{
picture_brow->setStyleSheet("border-image:url(./bmp/155771589064749921.jpg)");
}
}
Widget::~Widget()
{
}
效果图:
部件外观框架
当使用样式表时,每一个部件都被看做是拥有四个同心矩形的盒子,如下图所示。
这四个矩形分别是:内容(content)、填衬(padding)、边框(border)和边距(margin)。边距、边框宽度和填衬等属性的默认值都是0,这样四个矩形恰好重合。
外观框架如下所示:
例如:QPushBottom样式:
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: bold 14px;
/*字体颜色*/
color:rgba(0, 0, 0, 100);
/*填衬*/
padding: 6px;
}
注意:
Qt样式表可以存放在一个以.qss为后缀的文件中,这样我们就可以在程序中调用不同的.qss文件来实现换肤的功能。
样式表嵌套:
设置所有时:
style("{background:transparent;font-size:16px;color:red} ")不正常
style("background:transparent;font-size:16px;color:red ")正常
含有多个选择器
style(“QWidget{background:transparent;font-size:16px;color:red}
QProgressBar {border:none;background-color:gray;color:white;text-align: center;}”)正常
style(“background:transparent;font-size:16px;color:red
QProgressBar {border:none;background-color:gray;color:white;text-align: center;}”)不正常