问题描述
在Qt中,很多时候我们都需要使用样式表来设置控件样式,如颜色、边框、字体等。然而,有时候设置的样式却没有生效,或者设置多个样式却只展现出一个。
案例
我自定义了一个继承于QLabel
的类MyLabel
,并希望创建其对象时,控件就默认显示绿色背景及红色文字。代码如下:
- MyLabel.h
#ifndef MYLABEL_H
#define MYLABEL_H
#include <QLabel>
class MyLabel : public QLabel
{
Q_OBJECT
public:
explicit MyLabel(QWidget *parent = nullptr);
private:
void setBgColor();
void setFontColor();
};
#endif // MYLABEL_H
- MyLabel.cpp
#include "mylabel.h"
MyLabel::MyLabel(QWidget *parent) : QLabel(parent)
{
setBgColor();
setFontColor();
}
void MyLabel::setBgColor()
{
setStyleSheet("background-color: green;");
}
void MyLabel::setFontColor()
{
setStyleSheet("color: red");
}
- main.cpp
#include "mylabel.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MyLabel *label = new MyLabel;
label->setText("Hello, CS");
label->resize(200, 200);
label->show();
return a.exec();
}
结果分析
运行效果如下:
发现***仅文字显示为了红色,但背景没有变化!***
我尝试调换了设置样式的两行语句的顺序,修改代码如下:
- MyLabel.cpp
MyLabel::MyLabel(QWidget *parent) : QLabel(parent)
{
setFontColor();
setBgColor();
}
运行效果如下:
观察发现,每次设置样式后,均只显示了最后一次设置的样式,其他的被屏蔽!
经思考,应该是setStyleSheet()每次设置样式都会覆盖之前的样式表,导致只有最后设置的样式生效。为确认此推断,我调用styleSheet()
方法获取最终的样式表:
#include "mylabel.h"
#include <QApplication>
#include <QDebug>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MyLabel *label = new MyLabel;
label->setText("Hello, CS");
label->resize(200, 200);
qDebug() << label->styleSheet();
label->show();
return a.exec();
}
打印信息如下:
"background-color: green;"
证实了猜想。
对策
那么该如何同时让两种样式均生效呢?可使用字符串拼接的方式。
Example
- MyLabel.h
#ifndef MYLABEL_H
#define MYLABEL_H
#include <QLabel>
class MyLabel : public QLabel
{
Q_OBJECT
public:
explicit MyLabel(QWidget *parent = nullptr);
private:
void setBgColor();
void setFontColor();
private:
QString _styleSheet;
QString _bgColor;
QString _fontColor;
};
#endif // MYLABEL_H
- MyLabel.cpp
#include "mylabel.h"
MyLabel::MyLabel(QWidget *parent) : QLabel(parent)
{
setFontColor();
setBgColor();
}
void MyLabel::setBgColor()
{
_bgColor = "green";
_styleSheet = "background-color: %1; color: %2;";
_styleSheet = _styleSheet.arg(_bgColor).arg(_fontColor);
setStyleSheet(_styleSheet);
}
void MyLabel::setFontColor()
{
_fontColor = "red";
_styleSheet = "background-color: %1; color: %2;";
_styleSheet = _styleSheet.arg(_bgColor).arg(_fontColor);
setStyleSheet(_styleSheet);
}
- main.cpp
#include "mylabel.h"
#include <QApplication>
#include <QDebug>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MyLabel *label = new MyLabel;
label->setText("Hello, CS");
label->resize(200, 200);
qDebug() << label->styleSheet();
label->show();
return a.exec();
}
主要就是改变了样式表字符串的设置方式,让它预留不同样式的位置,设置时依次填充即可。
运行效果如下:
"background-color: green; color: red;"
总结
Qt的setStyleSheet()实际就是设置样式表的字符串,会覆盖,其语法与css类似。
样式表字符串只能有一个,但其中所包含的样式种类可以有很多。要同时显示多种样式,只需要让一个样式表字符串包含多种样式即可。