1. "QApplication::setStyleSheet()"设置样式表:

  1. 创建新的样式表。

  2. 设置新的样式。

  1. void QApplication::setStyleSheet(const QString& styleSheet)
  2. {
  3. QApplicationPrivate::styleSheet = styleSheet;
  4. QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle*>(QApplicationPrivate::app_style);
  5. if (styleSheet.isEmpty()) { // application style sheet removed
  6. if (!proxy)
  7. return; // there was no stylesheet before
  8. setStyle(proxy->base);
  9. } else if (proxy) { // style sheet update, just repolish
  10. proxy->repolish(qApp);
  11. } else { // stylesheet set the first time
  12. QStyleSheetStyle *newProxy = new QStyleSheetStyle(QApplicationPrivate::app_style);
  13. QApplicationPrivate::app_style->setParent(newProxy);
  14. setStyle(newProxy);
  15. }
  16. }

2. "QApplication::setStyle"——设置样式:

  1. void QApplication::setStyle(QStyle *style)
  2. {
  3. if (!style || style == QApplicationPrivate::app_style)
  4. return;
  5.  
  6. QWidgetList all = allWidgets();
  7.  
  8. // clean up the old style
  9. if (QApplicationPrivate::app_style) {
  10. if (QApplicationPrivate::is_app_running && !QApplicationPrivate::is_app_closing) {
  11. for (QWidgetList::ConstIterator it = all.constBegin(), cend = all.constEnd(); it != cend; ++it) {
  12. QWidget *w = *it;
  13. if (!(w->windowType() == Qt::Desktop) && // except desktop
  14. w->testAttribute(Qt::WA_WState_Polished)) { // has been polished
  15. QApplicationPrivate::app_style->unpolish(w);
  16. }
  17. }
  18. }
  19. QApplicationPrivate::app_style->unpolish(qApp);
  20. }
  21.  
  22. QStyle *old = QApplicationPrivate::app_style; // save
  23.  
  24. QApplicationPrivate::overrides_native_style =
  25. nativeStyleClassName() == QByteArray(style->metaObject()->className());
  26.  
  27. #ifndef QT_NO_STYLE_STYLESHEET
  28. if (!QApplicationPrivate::styleSheet.isEmpty() && !qobject_cast<QStyleSheetStyle *>(style)) {
  29. // we have a stylesheet already and a new style is being set
  30. QStyleSheetStyle *newProxy = new QStyleSheetStyle(style);
  31. style->setParent(newProxy);
  32. QApplicationPrivate::app_style = newProxy;
  33. } else
  34. #endif // QT_NO_STYLE_STYLESHEET
  35. QApplicationPrivate::app_style = style;
  36. QApplicationPrivate::app_style->setParent(qApp); // take ownership
  37.  
  38. // take care of possible palette requirements of certain gui
  39. // styles. Do it before polishing the application since the style
  40. // might call QApplication::setPalette() itself
  41. if (QApplicationPrivate::set_pal) {
  42. QApplication::setPalette(*QApplicationPrivate::set_pal);
  43. } else if (QApplicationPrivate::sys_pal) {
  44. clearSystemPalette();
  45. initSystemPalette();
  46. QApplicationPrivate::initializeWidgetPaletteHash();
  47. QApplicationPrivate::initializeWidgetFontHash();
  48. QApplicationPrivate::setPalette_helper(*QApplicationPrivate::sys_pal, /*className=*/, /*clearWidgetPaletteHash=*/false);
  49. } else if (!QApplicationPrivate::sys_pal) {
  50. // Initialize the sys_pal if it hasn't happened yet...
  51. QApplicationPrivate::setSystemPalette(QApplicationPrivate::app_style->standardPalette());
  52. }
  53.  
  54. // initialize the application with the new style
  55. QApplicationPrivate::app_style->polish(qApp);
  56.  
  57. // re-polish existing widgets if necessary
  58. if (QApplicationPrivate::is_app_running && !QApplicationPrivate::is_app_closing) {
  59. for (QWidgetList::ConstIterator it = all.constBegin(), cend = all.constEnd(); it != cend; ++it) {
  60. QWidget *w = *it;
  61. if (w->windowType() != Qt::Desktop && w->testAttribute(Qt::WA_WState_Polished)) {
  62. if (w->style() == QApplicationPrivate::app_style)
  63. QApplicationPrivate::app_style->polish(w); // repolish
  64. #ifndef QT_NO_STYLE_STYLESHEET
  65. else
  66. w->setStyleSheet(w->styleSheet()); // touch
  67. #endif
  68. }
  69. }
  70.  
  71. for (QWidgetList::ConstIterator it = all.constBegin(), cend = all.constEnd(); it != cend; ++it) {
  72. QWidget *w = *it;
  73. if (w->windowType() != Qt::Desktop && !w->testAttribute(Qt::WA_SetStyle)) {
  74. QEvent e(QEvent::StyleChange);
  75. QApplication::sendEvent(w, &e);
  76. w->update();
  77. }
  78. }
  79. }
  80.  
  81. #ifndef QT_NO_STYLE_STYLESHEET
  82. if (QStyleSheetStyle *oldProxy = qobject_cast<QStyleSheetStyle *>(old)) {
  83. oldProxy->deref();
  84. } else
  85. #endif
  86. if (old && old->parent() == qApp) {
  87. delete old;
  88. }
  89.  
  90. if (QApplicationPrivate::focus_widget) {
  91. QFocusEvent in(QEvent::FocusIn, Qt::OtherFocusReason);
  92. QApplication::sendEvent(QApplicationPrivate::focus_widget->style(), &in);
  93. QApplicationPrivate::focus_widget->update();
  94. }
  95. }

  2-1. 获取所有的QWidget列表(在QWidget的构造函数中调用QWidgetPrivate::init函数,将当前QWidget加入到列表)。

  2-2. 移除所有QWidget上旧的样式。

  2-3. 设置所有QWidget新的样式。

  2-4. 更新所有的QWidget。

4. "QStyleSheetStyle::styleRules"——经过一系列调用到这个函数中,获取样式规则:

  1. QVector<QCss::StyleRule> QStyleSheetStyle::styleRules(const QObject *obj) const
  2. {
  3. QHash<const QObject *, QVector<StyleRule> >::const_iterator cacheIt = styleSheetCaches->styleRulesCache.constFind(obj);
  4. if (cacheIt != styleSheetCaches->styleRulesCache.constEnd())
  5. return cacheIt.value();
  6.  
  7. if (!initObject(obj)) {
  8. return QVector<StyleRule>();
  9. }
  10.  
  11. QStyleSheetStyleSelector styleSelector;
  12.  
  13. StyleSheet defaultSs;
  14. QHash<const void *, StyleSheet>::const_iterator defaultCacheIt = styleSheetCaches->styleSheetCache.constFind(baseStyle());
  15. if (defaultCacheIt == styleSheetCaches->styleSheetCache.constEnd()) {
  16. defaultSs = getDefaultStyleSheet();
  17. QStyle *bs = baseStyle();
  18. styleSheetCaches->styleSheetCache.insert(bs, defaultSs);
  19. QObject::connect(bs, SIGNAL(destroyed(QObject*)), styleSheetCaches, SLOT(styleDestroyed(QObject*)), Qt::UniqueConnection);
  20. } else {
  21. defaultSs = defaultCacheIt.value();
  22. }
  23. styleSelector.styleSheets += defaultSs;
  24.  
  25. if (!qApp->styleSheet().isEmpty()) {
  26. StyleSheet appSs;
  27. QHash<const void *, StyleSheet>::const_iterator appCacheIt = styleSheetCaches->styleSheetCache.constFind(qApp);
  28. if (appCacheIt == styleSheetCaches->styleSheetCache.constEnd()) {
  29. QString ss = qApp->styleSheet();
  30. if (ss.startsWith(QLatin1String("file:///")))
  31. ss.remove(0, 8);
  32. parser.init(ss, qApp->styleSheet() != ss);
  33. if (!parser.parse(&appSs))
  34. qWarning("Could not parse application stylesheet");
  35. appSs.origin = StyleSheetOrigin_Inline;
  36. appSs.depth = 1;
  37. styleSheetCaches->styleSheetCache.insert(qApp, appSs);
  38. } else {
  39. appSs = appCacheIt.value();
  40. }
  41. styleSelector.styleSheets += appSs;
  42. }
  43.  
  44. QVector<QCss::StyleSheet> objectSs;
  45. for (const QObject *o = obj; o; o = parentObject(o)) {
  46. QString styleSheet = o->property("styleSheet").toString();
  47. if (styleSheet.isEmpty())
  48. continue;
  49. StyleSheet ss;
  50. QHash<const void *, StyleSheet>::const_iterator objCacheIt = styleSheetCaches->styleSheetCache.constFind(o);
  51. if (objCacheIt == styleSheetCaches->styleSheetCache.constEnd()) {
  52. parser.init(styleSheet);
  53. if (!parser.parse(&ss)) {
  54. parser.init(QLatin1String("* {") + styleSheet + QLatin1Char('}'));
  55. if (!parser.parse(&ss))
  56. qWarning("Could not parse stylesheet of object %p", o);
  57. }
  58. ss.origin = StyleSheetOrigin_Inline;
  59. styleSheetCaches->styleSheetCache.insert(o, ss);
  60. } else {
  61. ss = objCacheIt.value();
  62. }
  63. objectSs.append(ss);
  64. }
  65.  
  66. for (int i = ; i < objectSs.count(); i++)
  67. objectSs[i].depth = objectSs.count() - i + ;
  68.  
  69. styleSelector.styleSheets += objectSs;
  70.  
  71. StyleSelector::NodePtr n;
  72. n.ptr = const_cast<QObject *>(obj);
  73. QVector<QCss::StyleRule> rules = styleSelector.styleRulesForNode(n);
  74. styleSheetCaches->styleRulesCache.insert(obj, rules);
  75. return rules;
  76. }

  4-1. 初始化如果缓存中没有样式,先进行初始化。

  4-2. 获取基本样式到@defaultSs中,并添加到@styleSelector.styleSheets

  4-3. 在缓存中获取全局@qApp样式到@appSs中,并添加到@styleSelector.styleSheets。

    4-3-1. 如果在缓存中没有找到全局@qApp样式,则获取@qApp样式表字符串进行解析生成StyleSheet

  4-4. 不断遍历基类,从缓存中获取基类的样式到@objectSs中,并添加到@styleSelector.styleSheets。

    4-4-1. 如果缓存没有找到样式,则利用字符串重新解析生成StyleSheet

  4-5. 根据样式选着器(QStyleSheetStyleSelector)获取样式规添加到@rules。

  4-6. 最后将对象(QObject)与样式规则(StyleRule)插入到缓存@styleSheetCaches->styleRulesCache中。

5. 将字符串解析生成样式表StyleSheet(主要在qcssparser.cpp文件中):

  在"QStyleSheetStyle::styleRules"主要通过通过两个函数"Parser::init"和"Parser::parse"。

  5-1. 初始化解析器:

  1. void Parser::init(const QString &css, bool isFile)
  2. {
  3. QString styleSheet = css;
  4. if (isFile) {
  5. QFile file(css);
  6. if (file.open(QFile::ReadOnly)) {
  7. sourcePath = QFileInfo(styleSheet).absolutePath() + QLatin1Char('/');
  8. QTextStream stream(&file);
  9. styleSheet = stream.readAll();
  10. } else {
  11. qWarning() << "QCss::Parser - Failed to load file " << css;
  12. styleSheet.clear();
  13. }
  14. } else {
  15. sourcePath.clear();
  16. }
  17.  
  18. hasEscapeSequences = false;
  19. symbols.resize();
  20. symbols.reserve();
  21. Scanner::scan(Scanner::preprocess(styleSheet, &hasEscapeSequences), &symbols);
  22. index = ;
  23. errorIndex = -;
  24. }

    5-1-1. 将字符串进行预处理(这里主要是处理转义字符)。

    5-1-2. 逐个扫描形成一个一个符号(与编译原理中的扫描程序一致,形成符号后,方便后面进一步处理)。

  5-2. 解析样式表:

  1. bool Parser::parse(StyleSheet *styleSheet, Qt::CaseSensitivity nameCaseSensitivity)
  2. {
  3. if (testTokenAndEndsWith(ATKEYWORD_SYM, QLatin1String("charset"))) {
  4. if (!next(STRING)) return false;
  5. if (!next(SEMICOLON)) return false;
  6. }
  7.  
  8. while (test(S) || test(CDO) || test(CDC)) {}
  9.  
  10. while (testImport()) {
  11. ImportRule rule;
  12. if (!parseImport(&rule)) return false;
  13. styleSheet->importRules.append(rule);
  14. while (test(S) || test(CDO) || test(CDC)) {}
  15. }
  16.  
  17. do {
  18. if (testMedia()) {
  19. MediaRule rule;
  20. if (!parseMedia(&rule)) return false;
  21. styleSheet->mediaRules.append(rule);
  22. } else if (testPage()) {
  23. PageRule rule;
  24. if (!parsePage(&rule)) return false;
  25. styleSheet->pageRules.append(rule);
  26. } else if (testRuleset()) {
  27. StyleRule rule;
  28. if (!parseRuleset(&rule)) return false;
  29. styleSheet->styleRules.append(rule);
  30. } else if (test(ATKEYWORD_SYM)) {
  31. if (!until(RBRACE)) return false;
  32. } else if (hasNext()) {
  33. return false;
  34. }
  35. while (test(S) || test(CDO) || test(CDC)) {}
  36. } while (hasNext());
  37. styleSheet->buildIndexes(nameCaseSensitivity);
  38. return true;
  39. }

    5-2-1. 遍历所有符号,根据符号的类型进行相应的处理(这里我们只关注样式规则"parseRuleset(&rule)")。

    5-2-2. 解析样式规则:

  1. bool Parser::parseRuleset(StyleRule *styleRule)
  2. {
  3. Selector sel;
  4. if (!parseSelector(&sel)) return false;
  5. styleRule->selectors.append(sel);
  6.  
  7. while (test(COMMA)) {
  8. skipSpace();
  9. Selector sel;
  10. if (!parseNextSelector(&sel)) return false;
  11. styleRule->selectors.append(sel);
  12. }
  13.  
  14. skipSpace();
  15. if (!next(LBRACE)) return false;
  16. const int declarationStart = index;
  17.  
  18. do {
  19. skipSpace();
  20. Declaration decl;
  21. const int rewind = index;
  22. if (!parseNextDeclaration(&decl)) {
  23. index = rewind;
  24. const bool foundSemicolon = until(SEMICOLON);
  25. const int semicolonIndex = index;
  26.  
  27. index = declarationStart;
  28. const bool foundRBrace = until(RBRACE);
  29.  
  30. if (foundSemicolon && semicolonIndex < index) {
  31. decl = Declaration();
  32. index = semicolonIndex - ;
  33. } else {
  34. skipSpace();
  35. return foundRBrace;
  36. }
  37. }
  38. if (!decl.isEmpty())
  39. styleRule->declarations.append(decl);
  40. } while (test(SEMICOLON));
  41.  
  42. if (!next(RBRACE)) return false;
  43. skipSpace();
  44. return true;
  45. }

    5-2-2-1. 解析选择器(id选着器,class选着器,属性选着器等)。

    5-2-2-2. 解析声明,包括属性名、属性值等。

    5-2-2-3. 将解析的声明添加到样式规则中。

6. (4-5的细化)根据样式选着器(QStyleSheetStyleSelector)得到样式规则"":

  1. QVector<StyleRule> StyleSelector::styleRulesForNode(NodePtr node)
  2. {
  3. QVector<StyleRule> rules;
  4. if (styleSheets.isEmpty())
  5. return rules;
  6.  
  7. QMap<uint, StyleRule> weightedRules; // (spec, rule) that will be sorted below
  8.  
  9. //prune using indexed stylesheet
  10. for (int sheetIdx = ; sheetIdx < styleSheets.count(); ++sheetIdx) {
  11. const StyleSheet &styleSheet = styleSheets.at(sheetIdx);
  12. for (int i = 0; i < styleSheet.styleRules.count(); ++i) {
  13. matchRule(node, styleSheet.styleRules.at(i), styleSheet.origin, styleSheet.depth, &weightedRules);
  14. }
  15.  
  16. if (!styleSheet.idIndex.isEmpty()) {
  17. QStringList ids = nodeIds(node);
  18. for (int i = 0; i < ids.count(); i++) {
  19. const QString &key = ids.at(i);
  20. QMultiHash<QString, StyleRule>::const_iterator it = styleSheet.idIndex.constFind(key);
  21. while (it != styleSheet.idIndex.constEnd() && it.key() == key) {
  22. matchRule(node, it.value(), styleSheet.origin, styleSheet.depth, &weightedRules);
  23. ++it;
  24. }
  25. }
  26. }
  27. if (!styleSheet.nameIndex.isEmpty()) {
  28. QStringList names = nodeNames(node);
  29. for (int i = 0; i < names.count(); i++) {
  30. QString name = names.at(i);
  31. if (nameCaseSensitivity == Qt::CaseInsensitive)
  32. name = name.toLower();
  33. QMultiHash<QString, StyleRule>::const_iterator it = styleSheet.nameIndex.constFind(name);
  34. while (it != styleSheet.nameIndex.constEnd() && it.key() == name) {
  35. matchRule(node, it.value(), styleSheet.origin, styleSheet.depth, &weightedRules);
  36. ++it;
  37. }
  38. }
  39. }
  40. if (!medium.isEmpty()) {
  41. for (int i = ; i < styleSheet.mediaRules.count(); ++i) {
  42. if (styleSheet.mediaRules.at(i).media.contains(medium, Qt::CaseInsensitive)) {
  43. for (int j = ; j < styleSheet.mediaRules.at(i).styleRules.count(); ++j) {
  44. matchRule(node, styleSheet.mediaRules.at(i).styleRules.at(j), styleSheet.origin,
  45. styleSheet.depth, &weightedRules);
  46. }
  47. }
  48. }
  49. }
  50. }
  51.  
  52. rules.reserve(weightedRules.count());
  53. QMap<uint, StyleRule>::const_iterator it = weightedRules.constBegin();
  54. for ( ; it != weightedRules.constEnd() ; ++it)
  55. rules += *it;
  56.  
  57. return rules;
  58. }

  6-1. 遍历已有的样式规则(styleSheet.styleRules),如果匹配规则,将规则添加到@weightedRules中。

  6-2. 遍历id样式(styleSheet.idIndex),获取当前对象的名称(objectName),对象名称相同则匹配规则,将匹配的规则添加到@weightedRules中。

  6-3. 遍历class样式(styleSheet.nameIndex),获取当前对象的类名称(className)和基类的类名称,类名称相同则匹配规则,将规则添加到@weightedRules中。

  6-4. 将@weightedRules中的样式规则添加到@rules,并返回@rules

7. 最后需要渲染规则,将得到的样式规则转换为绘制时需要的对象(字体、颜色、背景画刷、背景图片等等):

  1. QRenderRule::QRenderRule(const QVector<Declaration> &declarations, const QObject *object)
  2. : features(), hasFont(false), pal(), b(), bg(), bd(), ou(), geo(), p(), img(), clipset()
  3. {
  4. QPalette palette = QApplication::palette(); // ###: ideally widget's palette
  5. ValueExtractor v(declarations, palette)zhua
  6. features = v.extractStyleFeatures();
  7.  
  8. int w = -, h = -, minw = -, minh = -, maxw = -, maxh = -;
  9. if (v.extractGeometry(&w, &h, &minw, &minh, &maxw, &maxh))
  10. geo = new QStyleSheetGeometryData(w, h, minw, minh, maxw, maxh);
  11.  
  12. int left = , top = , right = , bottom = ;
  13. Origin origin = Origin_Unknown;
  14. Qt::Alignment position = ;
  15. QCss::PositionMode mode = PositionMode_Unknown;
  16. Qt::Alignment textAlignment = ;
  17. if (v.extractPosition(&left, &top, &right, &bottom, &origin, &position, &mode, &textAlignment))
  18. p = new QStyleSheetPositionData(left, top, right, bottom, origin, position, mode, textAlignment);
  19.  
  20. int margins[], paddings[], spacing = -;
  21. for (int i = ; i < ; i++)
  22. margins[i] = paddings[i] = ;
  23. if (v.extractBox(margins, paddings, &spacing))
  24. b = new QStyleSheetBoxData(margins, paddings, spacing);
  25.  
  26. int borders[];
  27. QBrush colors[];
  28. QCss::BorderStyle styles[];
  29. QSize radii[];
  30. for (int i = ; i < ; i++) {
  31. borders[i] = ;
  32. styles[i] = BorderStyle_None;
  33. }
  34. if (v.extractBorder(borders, colors, styles, radii))
  35. bd = new QStyleSheetBorderData(borders, colors, styles, radii);
  36.  
  37. int offsets[];
  38. for (int i = ; i < ; i++) {
  39. borders[i] = offsets[i] = ;
  40. styles[i] = BorderStyle_None;
  41. }
  42. if (v.extractOutline(borders, colors, styles, radii, offsets))
  43. ou = new QStyleSheetOutlineData(borders, colors, styles, radii, offsets);
  44.  
  45. QBrush brush;
  46. QString uri;
  47. Repeat repeat = Repeat_XY;
  48. Qt::Alignment alignment = Qt::AlignTop | Qt::AlignLeft;
  49. Attachment attachment = Attachment_Scroll;
  50. origin = Origin_Padding;
  51. Origin clip = Origin_Border;
  52. if (v.extractBackground(&brush, &uri, &repeat, &alignment, &origin, &attachment, &clip))
  53. bg = new QStyleSheetBackgroundData(brush, QPixmap(uri), repeat, alignment, origin, attachment, clip);
  54.  
  55. QBrush sfg, fg;
  56. QBrush sbg, abg;
  57. if (v.extractPalette(&fg, &sfg, &sbg, &abg))
  58. pal = new QStyleSheetPaletteData(fg, sfg, sbg, abg);
  59.  
  60. QIcon icon;
  61. alignment = Qt::AlignCenter;
  62. QSize size;
  63. if (v.extractImage(&icon, &alignment, &size))
  64. img = new QStyleSheetImageData(icon, alignment, size);
  65.  
  66. int adj = -;
  67. hasFont = v.extractFont(&font, &adj);
  68.  
  69. #ifndef QT_NO_TOOLTIP
  70. if (object && qstrcmp(object->metaObject()->className(), "QTipLabel") == )
  71. palette = QToolTip::palette();
  72. #endif
  73.  
  74. for (int i = ; i < declarations.count(); i++) {
  75. const Declaration& decl = declarations.at(i);
  76. if (decl.d->propertyId == BorderImage) {
  77. QString uri;
  78. QCss::TileMode horizStretch, vertStretch;
  79. int cuts[];
  80.  
  81. decl.borderImageValue(&uri, cuts, &horizStretch, &vertStretch);
  82. if (uri.isEmpty() || uri == QLatin1String("none")) {
  83. if (bd && bd->bi)
  84. bd->bi->pixmap = QPixmap();
  85. } else {
  86. if (!bd)
  87. bd = new QStyleSheetBorderData;
  88. if (!bd->bi)
  89. bd->bi = new QStyleSheetBorderImageData;
  90.  
  91. QStyleSheetBorderImageData *bi = bd->bi;
  92. bi->pixmap = QPixmap(uri);
  93. for (int i = ; i < ; i++)
  94. bi->cuts[i] = cuts[i];
  95. bi->horizStretch = horizStretch;
  96. bi->vertStretch = vertStretch;
  97. }
  98. } else if (decl.d->propertyId == QtBackgroundRole) {
  99. if (bg && bg->brush.style() != Qt::NoBrush)
  100. continue;
  101. int role = decl.d->values.at().variant.toInt();
  102. if (role >= Value_FirstColorRole && role <= Value_LastColorRole)
  103. defaultBackground = palette.color((QPalette::ColorRole)(role-Value_FirstColorRole));
  104. } else if (decl.d->property.startsWith(QLatin1String("qproperty-"), Qt::CaseInsensitive)) {
  105. // intentionally left blank...
  106. } else if (decl.d->propertyId == UnknownProperty) {
  107. bool knownStyleHint = false;
  108. for (int i = ; i < numKnownStyleHints; i++) {
  109. QLatin1String styleHint(knownStyleHints[i]);
  110. if (decl.d->property.compare(styleHint) == ) {
  111. QString hintName = QString(styleHint);
  112. QVariant hintValue;
  113. if (hintName.endsWith(QLatin1String("alignment"))) {
  114. hintValue = (int) decl.alignmentValue();
  115. } else if (hintName.endsWith(QLatin1String("color"))) {
  116. hintValue = (int) decl.colorValue().rgba();
  117. } else if (hintName.endsWith(QLatin1String("size"))) {
  118. hintValue = decl.sizeValue();
  119. } else if (hintName.endsWith(QLatin1String("icon"))) {
  120. hintValue = decl.iconValue();
  121. } else if (hintName == QLatin1String("button-layout")
  122. && decl.d->values.count() != && decl.d->values.at().type == Value::String) {
  123. hintValue = subControlLayout(decl.d->values.at().variant.toString());
  124. } else {
  125. int integer;
  126. decl.intValue(&integer);
  127. hintValue = integer;
  128. }
  129. styleHints[decl.d->property] = hintValue;
  130. knownStyleHint = true;
  131. break;
  132. }
  133. }
  134. if (!knownStyleHint)
  135. qDebug("Unknown property %s", qPrintable(decl.d->property));
  136. }
  137. }
  138.  
  139. if (const QWidget *widget = qobject_cast<const QWidget *>(object)) {
  140. QStyleSheetStyle *style = const_cast<QStyleSheetStyle *>(globalStyleSheetStyle);
  141. if (!style)
  142. style = qobject_cast<QStyleSheetStyle *>(widget->style());
  143. if (style)
  144. fixupBorder(style->nativeFrameWidth(widget));
  145. }
  146. if (hasBorder() && border()->hasBorderImage())
  147. defaultBackground = QBrush();
  148. }

  从样式规则中得到样式声明,然后根据样式声明去创建不同的绘制对象,为后面的绘制做准备。

  绘制对象包括:位置(Geomeory、Position、Box)、边框(Border、Outline)、背景(BackgroundColor、BackgroundImage等)、字体(FontFamily、FontSize、FontStyle、FontWeight等)等等。

最后如果想查看QSS属性名称和值的列表,可以查看qtbase\src\gui\text\qcssparser.cpp文件:

  1. static const QCssKnownValue properties[NumProperties - ] = {
  2. { "-qt-background-role", QtBackgroundRole },
  3. { "-qt-block-indent", QtBlockIndent },
  4. { "-qt-list-indent", QtListIndent },
  5. { "-qt-list-number-prefix", QtListNumberPrefix },
  6. { "-qt-list-number-suffix", QtListNumberSuffix },
  7. { "-qt-paragraph-type", QtParagraphType },
  8. { "-qt-style-features", QtStyleFeatures },
  9. { "-qt-table-type", QtTableType },
  10. { "-qt-user-state", QtUserState },
  11. { "alternate-background-color", QtAlternateBackground },
  12. { "background", Background },
  13. { "background-attachment", BackgroundAttachment },
  14. { "background-clip", BackgroundClip },
  15. { "background-color", BackgroundColor },
  16. { "background-image", BackgroundImage },
  17. { "background-origin", BackgroundOrigin },
  18. { "background-position", BackgroundPosition },
  19. { "background-repeat", BackgroundRepeat },
  20. { "border", Border },
  21. { "border-bottom", BorderBottom },
  22. { "border-bottom-color", BorderBottomColor },
  23. { "border-bottom-left-radius", BorderBottomLeftRadius },
  24. { "border-bottom-right-radius", BorderBottomRightRadius },
  25. { "border-bottom-style", BorderBottomStyle },
  26. { "border-bottom-width", BorderBottomWidth },
  27. { "border-color", BorderColor },
  28. { "border-image", BorderImage },
  29. { "border-left", BorderLeft },
  30. { "border-left-color", BorderLeftColor },
  31. { "border-left-style", BorderLeftStyle },
  32. { "border-left-width", BorderLeftWidth },
  33. { "border-radius", BorderRadius },
  34. { "border-right", BorderRight },
  35. { "border-right-color", BorderRightColor },
  36. { "border-right-style", BorderRightStyle },
  37. { "border-right-width", BorderRightWidth },
  38. { "border-style", BorderStyles },
  39. { "border-top", BorderTop },
  40. { "border-top-color", BorderTopColor },
  41. { "border-top-left-radius", BorderTopLeftRadius },
  42. { "border-top-right-radius", BorderTopRightRadius },
  43. { "border-top-style", BorderTopStyle },
  44. { "border-top-width", BorderTopWidth },
  45. { "border-width", BorderWidth },
  46. { "bottom", Bottom },
  47. { "color", Color },
  48. { "float", Float },
  49. { "font", Font },
  50. { "font-family", FontFamily },
  51. { "font-size", FontSize },
  52. { "font-style", FontStyle },
  53. { "font-variant", FontVariant },
  54. { "font-weight", FontWeight },
  55. { "height", Height },
  56. { "image", QtImage },
  57. { "image-position", QtImageAlignment },
  58. { "left", Left },
  59. { "line-height", LineHeight },
  60. { "list-style", ListStyle },
  61. { "list-style-type", ListStyleType },
  62. { "margin" , Margin },
  63. { "margin-bottom", MarginBottom },
  64. { "margin-left", MarginLeft },
  65. { "margin-right", MarginRight },
  66. { "margin-top", MarginTop },
  67. { "max-height", MaximumHeight },
  68. { "max-width", MaximumWidth },
  69. { "min-height", MinimumHeight },
  70. { "min-width", MinimumWidth },
  71. { "outline", Outline },
  72. { "outline-bottom-left-radius", OutlineBottomLeftRadius },
  73. { "outline-bottom-right-radius", OutlineBottomRightRadius },
  74. { "outline-color", OutlineColor },
  75. { "outline-offset", OutlineOffset },
  76. { "outline-radius", OutlineRadius },
  77. { "outline-style", OutlineStyle },
  78. { "outline-top-left-radius", OutlineTopLeftRadius },
  79. { "outline-top-right-radius", OutlineTopRightRadius },
  80. { "outline-width", OutlineWidth },
  81. { "padding", Padding },
  82. { "padding-bottom", PaddingBottom },
  83. { "padding-left", PaddingLeft },
  84. { "padding-right", PaddingRight },
  85. { "padding-top", PaddingTop },
  86. { "page-break-after", PageBreakAfter },
  87. { "page-break-before", PageBreakBefore },
  88. { "position", Position },
  89. { "right", Right },
  90. { "selection-background-color", QtSelectionBackground },
  91. { "selection-color", QtSelectionForeground },
  92. { "spacing", QtSpacing },
  93. { "subcontrol-origin", QtOrigin },
  94. { "subcontrol-position", QtPosition },
  95. { "text-align", TextAlignment },
  96. { "text-decoration", TextDecoration },
  97. { "text-indent", TextIndent },
  98. { "text-transform", TextTransform },
  99. { "text-underline-style", TextUnderlineStyle },
  100. { "top", Top },
  101. { "vertical-align", VerticalAlignment },
  102. { "white-space", Whitespace },
  103. { "width", Width }
  104. };
  105.  
  106. static const QCssKnownValue values[NumKnownValues - ] = {
  107. { "active", Value_Active },
  108. { "alternate-base", Value_AlternateBase },
  109. { "always", Value_Always },
  110. { "auto", Value_Auto },
  111. { "base", Value_Base },
  112. { "bold", Value_Bold },
  113. { "bottom", Value_Bottom },
  114. { "bright-text", Value_BrightText },
  115. { "button", Value_Button },
  116. { "button-text", Value_ButtonText },
  117. { "center", Value_Center },
  118. { "circle", Value_Circle },
  119. { "dark", Value_Dark },
  120. { "dashed", Value_Dashed },
  121. { "decimal", Value_Decimal },
  122. { "disabled", Value_Disabled },
  123. { "disc", Value_Disc },
  124. { "dot-dash", Value_DotDash },
  125. { "dot-dot-dash", Value_DotDotDash },
  126. { "dotted", Value_Dotted },
  127. { "double", Value_Double },
  128. { "groove", Value_Groove },
  129. { "highlight", Value_Highlight },
  130. { "highlighted-text", Value_HighlightedText },
  131. { "inset", Value_Inset },
  132. { "italic", Value_Italic },
  133. { "large", Value_Large },
  134. { "left", Value_Left },
  135. { "light", Value_Light },
  136. { "line-through", Value_LineThrough },
  137. { "link", Value_Link },
  138. { "link-visited", Value_LinkVisited },
  139. { "lower-alpha", Value_LowerAlpha },
  140. { "lower-roman", Value_LowerRoman },
  141. { "lowercase", Value_Lowercase },
  142. { "medium", Value_Medium },
  143. { "mid", Value_Mid },
  144. { "middle", Value_Middle },
  145. { "midlight", Value_Midlight },
  146. { "native", Value_Native },
  147. { "none", Value_None },
  148. { "normal", Value_Normal },
  149. { "nowrap", Value_NoWrap },
  150. { "oblique", Value_Oblique },
  151. { "off", Value_Off },
  152. { "on", Value_On },
  153. { "outset", Value_Outset },
  154. { "overline", Value_Overline },
  155. { "pre", Value_Pre },
  156. { "pre-wrap", Value_PreWrap },
  157. { "ridge", Value_Ridge },
  158. { "right", Value_Right },
  159. { "selected", Value_Selected },
  160. { "shadow", Value_Shadow },
  161. { "small" , Value_Small },
  162. { "small-caps", Value_SmallCaps },
  163. { "solid", Value_Solid },
  164. { "square", Value_Square },
  165. { "sub", Value_Sub },
  166. { "super", Value_Super },
  167. { "text", Value_Text },
  168. { "top", Value_Top },
  169. { "transparent", Value_Transparent },
  170. { "underline", Value_Underline },
  171. { "upper-alpha", Value_UpperAlpha },
  172. { "upper-roman", Value_UpperRoman },
  173. { "uppercase", Value_Uppercase },
  174. { "wave", Value_Wave },
  175. { "window", Value_Window },
  176. { "window-text", Value_WindowText },
  177. { "x-large", Value_XLarge },
  178. { "xx-large", Value_XXLarge }
  179. };

QT源码剖析之QSS样式表的更多相关文章

  1. Qt系统对话框中文化及应用程序实现重启及使用QSS样式表文件及使用程序启动界面

    一.应用程序中文化 1).Qt安装目录下有一个目录translations/,在此目录下有qt_zh_CN.ts和 qt_zh_CN.qm把它们拷贝到你的工程目录下. 2).在main函数加入下列代码 ...

  2. 菜鸟nginx源码剖析数据结构篇(七) 哈希表 ngx_hash_t(下)[转]

    菜鸟nginx源码剖析数据结构篇(七) 哈希表 ngx_hash_t(下) Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.c ...

  3. 菜鸟nginx源码剖析数据结构篇(六) 哈希表 ngx_hash_t(上)[转]

    菜鸟nginx源码剖析数据结构篇(六) 哈希表 ngx_hash_t(上) Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.c ...

  4. Qt信号槽源码剖析(一)

    大家好,我是IT文艺男,来自一线大厂的一线程序员 大家在使用Qt开发程序时,都知道怎么使用Qt的信号槽,但是Qt信号槽是怎么工作的? 大部分人仍然不知道:也就是说大家只知道怎么使用,却不知道基于什么原 ...

  5. Qt信号槽源码剖析(二)

    大家好,我是IT文艺男,来自一线大厂的一线程序员 上节视频给大家讲解了Qt信号槽的基本概念.元对象编译器.示例代码以及Qt宏:今天接着深入分析,进入Qt信号槽源码剖析系列的第二节视频. Qt信号槽的宏 ...

  6. (文字版)Qt信号槽源码剖析(三)

    大家好,我是IT文艺男,来自一线大厂的一线程序员 上节视频给大家讲解了Qt信号槽的Qt宏展开推导:今天接着深入分析,进入Qt信号槽源码剖析系列的第三节视频. Qt信号槽宏推导归纳 #define si ...

  7. 基于mybatis-generator-core 1.3.5项目的修订版以及源码剖析

    项目简单说明 mybatis-generator,是根据数据库表.字段反向生成实体类等代码文件.我在国庆时候,没事剖析了mybatis-generator-core源码,写了相当详细的中文注释,可以去 ...

  8. STL"源码"剖析-重点知识总结

    STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点略多 :) 1.STL概述 STL提供六大组件,彼此可以组合 ...

  9. socket_server源码剖析、python作用域、IO多路复用

    本节内容: 课前准备知识: 函数嵌套函数的使用方法: 我们在使用函数嵌套函数的时候,是学习装饰器的时候,出现过,由一个函数返回值是一个函数体情况. 我们在使用函数嵌套函数的时候,最好也这么写. def ...

随机推荐

  1. OleDbCommand cmd.Parameters.AddWithValue 添加参数时需要按照存储过程参数的顺序加入

    在使用存储过程时,参数出入的顺序要一致.

  2. Android开发华为手机无法看log日志解决方法

    Android开发华为手机无法看log日志解决方法 上班的时候,由于开发工具由Eclipse改成Android Studio后,原本的华为手机突然无法查看崩溃日志了,大家都知道,若是无法查看日志要它毛 ...

  3. swift设置textfield边框颜色

    //swift3.0,如果是2.0的话也可以照着这个样子去写,语法有所变动.根据联想出来的就可以了. let tx = UITextField(frame: CGRect(x: 100, y: 100 ...

  4. Js-Html 前端系列--点击非Div区域隐藏Div

    最近做项目要用到三字码下拉,调用一个插件,但是滚动条不能点击. 后来看另一个插件后突发奇想,在点击其他区域的时候隐藏这个Div就可以了. 背景:输入文字,弹出下拉Div,点击或者拉动Div滚动条选择, ...

  5. JavaScript字符和数组一些基本算法题

    1.翻转字符串 例子(要求:先把字符串转化成数组,再借助数组的reverse方法翻转数组顺序,最后把数组转化成字符串) function reverseString(str) { str=str.sp ...

  6. RelativeLayout各个属性

    android:layout_above="@id/xxx"  --将控件置于给定ID控件之上 android:layout_below="@id/xxx"  ...

  7. ToDictionary用法

    ToDictionary其实可以简单化,可以传两个lambada表达式,第一个是Key,第二个就是Value. ToDictionary( key => key.Attribute(" ...

  8. django 学习笔记(一)搭建基础环境

    1.安装django 下载地址 https://github.com/django/django 解压后进入文件夹运行指令 >> python setup.py install 2.创建工 ...

  9. List list = new ArrayList()

    方便以后扩展List是一个接口,而ArrayList 是一个类. ArrayList 继承并实现了List.List list = new ArrayList();这句创建了一个ArrayList的对 ...

  10. Java 基础知识(一)

    Java基础知识篇: 一.关键字解释 1. final:修饰非抽象类,非抽象方法和属性, 以及修饰方法参数,代表“无法改变的”.出于对设计或者效率的考虑使用该关键字. final类无法被继承,fina ...