在Qt中一般情况下我们可以通过qss样式表来配置控件的一些样式,但是一些特殊情况下还是需要使用代码来控制样式,它们的颜色之类的样式属性如果直接写在代码里面会写死掉,后期不容易维护以及为换肤造成麻烦。通常写在ini配置文件里面也是可以的,但是这样要维护qss样式和ini配置两份文件。
下面是将这些配置以css的样式直接写在qss文件中通过代码来解析出我们需要的属性,同时又支持使用属性名来生效样式:
widget->setProperty(“fmlName”,“calendar”);
解析类头文件
class FmlStyle {
public:
static FmlStyle* instance();
void init(const QString &styleFileContent);
const QString& style(const QString &fmlName);
QString attr(const QString &fmlName, const QString &attrName);
private:
FmlStyle();
private:
QMap<QString, QString> m_fmlStyles;
};
解析类源文件
FmlStyle::FmlStyle()
{
}
FmlStyle* FmlStyle::instance()
{
static FmlStyle s_inst;
return &s_inst;
}
void FmlStyle::init(const QString &styleFileContent)
{
int pos = 0;
QRegExp rx("QWidget\\[fmlName=\"\\w+\"\\]"); // 匹配key,如:QWidget[fmlName="calendar"]
while ((pos = rx.indexIn(styleFileContent, pos)) != -1) {
QString head = styleFileContent.mid(pos, rx.matchedLength());
pos += rx.matchedLength();
int start = -1;
int end = -1;
start = styleFileContent.indexOf("{", pos);
if (start >= 0) {
end = styleFileContent.indexOf("}", start);
}
if (end - start > 1) {
QString body = styleFileContent.mid(start + 1, end - start - 1);
pos += body.length();
body = body.trimmed();
if (body.size() > 0) {
m_fmlStyles[head] = body;
}
}
}
}
const QString& FmlStyle::style(const QString &fmlName)
{
QString head = QString("QWidget[fmlName=\"%1\"]").arg(fmlName);
return m_fmlStyles[head];
}
QString FmlStyle::attr(const QString &fmlName, const QString &attrName)
{
const QString &body = style(fmlName);
QStringList attrList = body.split(";");
for (int i = 0, count = attrList.size(); i < count; i++) {
QStringList strList = attrList[i].split(":");
if (strList.size() == 2) {
if (strList[0].trimmed() == attrName) {
return strList[1].trimmed();
}
}
}
return "";
}
如下样式在qss文件的任意位置:
QWidget[fmlName="calendar11"] {
background: #111111;
border: none;
color:#FFFFFF;
font-size:12px;
height:30px;
}
初始化以及读取样式:
QFile file(":/style.qss");
if (!file.exists()) {
qDebug() << "no skin file!!!";
}
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QString str = file.readAll();
FmlStyle::instance()->init(str);
qApp->setStyleSheet(str);
file.close();
}
QString xx = FmlStyle::instance()->style("calendar");
QString xxx = FmlStyle::instance()->attr("calendar", "font-size");
QString xxxx = FmlStyle::instance()->attr("calendar", "background");