0
点赞
收藏
分享

微信扫一扫

Qt换肤之二:基于QSS+XML


一.效果

Qt换肤之二:基于QSS+XML_Qt

二.原理

上篇 ​​Qt换肤之一:基于QSS ​​​中实现了基于QSS换肤,但是QSS文件通常不会暴露出来,这样的话软件发布后,皮肤颜色也就无法修改了。
这里依然用到了QSS文件,但是只用了一份QSS文件,文件里的颜色值通过XML来配置。

三.实现

XML举例,这个XML很简单,实际使用时会复杂很多。

<?xml version="1.0" encoding="UTF-8"?>
<TopicColor>
<ColorItem key="bordercolor" value="rgba(74,184,161)"></ColorItem>
<ColorItem key="backgroundcolor" value="rgba(74,184,161)"></ColorItem>
<ColorItem key="normalcolor" value="rgba(74,184,161)"></ColorItem>
<ColorItem key="hovercolor" value="rgba(74,184,161,200)"></ColorItem>
<ColorItem key="presscolor" value="rgba(74,184,161)"></ColorItem>
<ColorItem key="QSlider::add-page" value="rgba(74,184,161,50)"></ColorItem>
<ColorItem key="QSlider::sub-page" value="rgba(74,184,161)"></ColorItem>
</TopicColor>

XML解析,更复杂XML文件的解析可参考:​​Qt之读(解析)XML文件​​

void testUI::parseXMLFile()
{
QString filePath = QApplication::applicationDirPath() + "/TopicConfig.xml";
QFile file(filePath);
if(!file.open(QIODevice::ReadOnly))
{
qDebug()<<"open topic config file failed";
return;
}
QDomDocument docment;
bool ret = docment.setContent(&file);
if(!ret)
{
qDebug()<<"set content failed";
file.close();
return;
}
file.close();

QDomElement root = docment.documentElement();

QDomNode node = root.firstChild();
while(!node.isNull())
{
if(node.isElement())
{
QDomElement element = node.toElement();
m_colorMap.insert(element.attribute("key"), element.attribute("value"));
}
node = node.nextSibling();
}
}

QSS文件

QWidget#testUI{
border: 1px solid %bordercolor%;
border-radius: 0px;
}

QWidget#titleWidget{
background: %backgroundcolor%;
}

QLabel#iconLabel,QLabel#titleLabel{
border-radius: 0px;
color: rgb(255,255,255);
background-color: transparent;
border-style: none;
}

.QPushButton{
border-style: none;
border: 0px;
color: rgb(255,255,255);
min-height: 20px;
border-radius: 0px;
background: %normalcolor%;
}

.QPushButton:hover{
background: %hovercolor%;
}

.QPushButton:pressed{
background: %presscolor%;
}

QLineEdit {
border: 1px solid %bordercolor%;
border-radius: 5px;
padding: 0 8px;
background: rgb(255,255,255);
selection-background-color: %hovercolor%;
}

QComboBox {
border-radius: 3px;
padding: 1px 10px 1px 5px;
border: 1px solid %bordercolor%;
}

QComboBox::drop-down {
subcontrol-origin: padding;
subcontrol-position: top right;
width: 15px;
border-left-width: 1px;
border-left-style: solid;
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
border-left-color: %bordercolor%;
}

QComboBox::down-arrow {
image: url(:/icons/array_down.png);
}
/*去掉item的虚线框*/
QComboBox QAbstractItemView {
outline: 0px;
}

QListView::item:selected {
color: rgb(255,255,255);
background: %normalcolor%;
}

QListView::item:hover {
color: rgb(255,255,255);
background: %hovercolor%;
}

QListView::item {
padding: 0px;
margin: 0px;
height:30px;
}

QProgressBar {
border-radius: 5px;
text-align: center;
border: 1px solid %bordercolor%;
}

QProgressBar::chunk {
width: 5px;
margin: 0.5px;
background-color: %normalcolor%
}

QSlider::groove:horizontal,QSlider::add-page:horizontal {
background: %QSlider::add-page%;
height: 8px;
border-radius: 3px;
}

QSlider::sub-page:horizontal {
height: 8px;
border-radius: 3px;
background: %QSlider::sub-page%;
}

QSlider::handle:horizontal {
width: 13px;
margin-top: -3px;
margin-bottom: -3px;
border-radius: 6px;
background: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5,stop:0.6 rgb(255,255,255), stop:0.778409 %normalcolor%);
}

QSlider::handle:horizontal:hover {
background: qradialgradient(spread: pad, cx: 0.5, cy: 0.5, radius: 0.5, fx: 0.5, fy: 0.5, stop: 0.6 lightgray,stop:0.778409 %hovercolor%);
}

根据XML替换QSS中的变量

void testUI::updateQssFile()
{
QFile file(":/qss/topic.qss");
file.open(QFile::ReadOnly);
QByteArray ba = file.readAll();
file.close();
if(m_colorMap.count() > 0)
{
QMap<QString,QString>::iterator iter = m_colorMap.begin();
for(; iter != m_colorMap.end(); ++iter)
{
QString name = "%" + iter.key() + "%";
ba.replace(name, iter.value().toStdString().c_str());
}
qApp->setStyleSheet(ba);
}
}

void testUI::on_blackTopicButton_clicked()
{
changeStyle("black");
styleTitleButtons();
}

void testUI::on_orangeTopicButton_clicked()
{
changeStyle("orange");
styleTitleButtons();
}

void testUI::on_cancelTopicButton_clicked()
{
changeStyle("");
restoreTitleButtons();
}

void testUI::on_loadTopicButton_clicked()
{
parseXMLFile();
updateQssFile();
styleTitleButtons();
}

举报

相关推荐

0 条评论