Customizing Qt Widgets Using Style Sheets
使用样式表时,每个小部件都被视为一个具有四个同心矩形的框:边距矩形、边框矩形、填充矩形和内容矩形。盒子模型对此进行了更详细的描述。
盒子模型
四个同心矩形在概念上如下所示:
- 边距在边框外。
- 在边距和填充之间绘制边框。
- 填充位于边框内部,介于边框和实际内容之间。
- 内容是删除边距、边框和填充后,原始小部件或子控件中剩下的内容。
margin、border-width和padding属性都默认为零。在这种情况下,所有四个矩形(边距、边框、填充和内容)完全重合。
您可以使用 background-image 属性为小部件指定背景。默认情况下,仅为边框内的区域绘制背景图像。这可以使用background-clip属性进行更改。可以使用“background-repeat”和“background-origin”来控制背景图像的重复和原点。
background-image 不随小部件的大小而缩放。要提供随小部件大小缩放的“皮肤”或背景,必须使用border-image。由于border-image属性提供备用背景,因此在指定border-image时不需要指定背景图像。在这种情况下,当两者都被指定时,边框图像将绘制在背景图像上。
另外,图像属性可用于在边框图像上绘制图像。指定的图像不平铺或拉伸,当其大小与小部件的大小不匹配时,将使用“image-position”属性指定其对齐方式。与背景图像和边框图像不同,可以在image属性中指定SVG,在这种情况下,图像会根据小部件大小自动缩放。
呈现规则的步骤如下:
- 为整个渲染操作设置剪辑(border-radius 边界半径)
- 绘制背景(background-image 背景图像)
- 绘制边框(border-image 边框图像,border 边框)
- 绘制覆盖图像(image 图像)
子控件
小部件被认为是一个层次结构(树)的子控件绘制在彼此的顶部。例如,QComboBox绘制下拉子控件,后跟向下箭头子控件。QComboBox呈现如下:
- 渲染QComboBox {}规则
- 渲染QComboBox::drop-down {}规则
- 渲染QComboBox::down-arrow {}规则
子控件们共享父子关系。 对于QComboBox,down-arrow的父代是下拉列表,而drop-down的父代就是小部件本身。 子控件们使用subcontrol-position和subcontrol-origin属性放置在其父级中。
一旦定位后,可以使用盒子模型为子控件设置样式。
注意:对于复杂的窗口小部件(例如QComboBox和QScrollBar),如果自定义一个属性或子控件,则所有其他属性或子控件也必须被自定义。
演示代码
main.cpp
#include <QtWidgets>
#define WidgetType QLabel
void loadQssFile(){
QFile file("StyleSheet.qss");
file.open (QFile::ReadWrite | QIODevice::Text );
qApp->setStyleSheet (file.readAll ());
file.close ();
}
int main(int argc, char *argv[])
{
QApplication app(argc,argv);
app.setApplicationName ("QSS");
QDialog w;
w.setWindowFlag (Qt::WindowContextHelpButtonHint,false);
auto mainLayout = new QGridLayout(&w);
mainLayout->addWidget (new WidgetType("QLabel 1"),0,0);
mainLayout->addWidget (new WidgetType("QLabel 2"),0,1);
WidgetType * widget = qobject_cast<WidgetType *>( mainLayout->itemAt (0)->widget ());
widget->setObjectName ("test");
loadQssFile ();
w.resize (300,200);
w.show ();
app.exec();
return 0;
}
StyleSheet.qss
/* 1.jpg == https://t7.baidu.com/it/u=825057118,3516313570&fm=193&f=GIF */
QDialog {
background-image:url(1.jpg);
}
QLabel#test {
border-image:url(1.jpg);
}
QLabel:hover {
color: red;
}
演示代码2
main.cpp
#include <QtWidgets>
#define WidgetType QLabel
void loadQssFile(){
QFile file("StyleSheet.qss");
file.open (QFile::ReadWrite | QIODevice::Text );
qApp->setStyleSheet (file.readAll ());
file.close ();
}
int main(int argc, char *argv[])
{
QApplication app(argc,argv);
QCoreApplication::setAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles, true);
app.setApplicationName ("QSS");
QDialog w;
w.setWindowFlag (Qt::WindowContextHelpButtonHint,false);
auto mainLayout = new QGridLayout(&w);
mainLayout->addWidget (new WidgetType("QLabel 1"),0,0);
mainLayout->addWidget (new WidgetType("QLabel 2"),0,1);
mainLayout->addWidget (new WidgetType("QLabel 3"),0,2);
QString str = "<h2>Lorem Ipsum Dolor</h2>\n"
"<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, "
"sed diam nonummy nibh euismod tincidunt ut laoreet dolore "
"magna aliquam erat volutpat.</p>";
for (int i = 0; i < mainLayout->count (); ++i) {
WidgetType *w = qobject_cast<WidgetType *>(mainLayout->itemAt (i)->widget ());
// w->setAlignment (Qt::AlignCenter);
w->setText (str);
w->setWordWrap (true);
w->setObjectName (QString("test%1").arg (i));
// qDebug()<<w->objectName ();
}
loadQssFile ();
w.resize (600,300);
w.show ();
app.exec();
return 0;
}
StyleSheet.qss
QLabel#test0 {
margin: 10px;
border: 10px dotted black;
padding:35px;
background: red;
}
QLabel#test1 {
margin: 10px;
border: 10px dotted black;
padding:35px;
background: green;
background-clip: padding;
}
QLabel#test2 {
margin: 10px;
border: 10px dotted black;
padding:35px;
background: yellow;
background-clip: content;
}
QLabel:hover {
color: red;
}