Skip to content

Qt自定义读取qss样式表

Published: at 06:56 AM | 3 min read

在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");