QT源码剖析之QSS样式表
1. "QApplication::setStyleSheet()"设置样式表:
1. 创建新的样式表。
2. 设置新的样式。
- void QApplication::setStyleSheet(const QString& styleSheet)
- {
- QApplicationPrivate::styleSheet = styleSheet;
- QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle*>(QApplicationPrivate::app_style);
- if (styleSheet.isEmpty()) { // application style sheet removed
- if (!proxy)
- return; // there was no stylesheet before
- setStyle(proxy->base);
- } else if (proxy) { // style sheet update, just repolish
- proxy->repolish(qApp);
- } else { // stylesheet set the first time
- QStyleSheetStyle *newProxy = new QStyleSheetStyle(QApplicationPrivate::app_style);
- QApplicationPrivate::app_style->setParent(newProxy);
- setStyle(newProxy);
- }
- }
2. "QApplication::setStyle"——设置样式:
- void QApplication::setStyle(QStyle *style)
- {
- if (!style || style == QApplicationPrivate::app_style)
- return;
- QWidgetList all = allWidgets();
- // clean up the old style
- if (QApplicationPrivate::app_style) {
- if (QApplicationPrivate::is_app_running && !QApplicationPrivate::is_app_closing) {
- for (QWidgetList::ConstIterator it = all.constBegin(), cend = all.constEnd(); it != cend; ++it) {
- QWidget *w = *it;
- if (!(w->windowType() == Qt::Desktop) && // except desktop
- w->testAttribute(Qt::WA_WState_Polished)) { // has been polished
- QApplicationPrivate::app_style->unpolish(w);
- }
- }
- }
- QApplicationPrivate::app_style->unpolish(qApp);
- }
- QStyle *old = QApplicationPrivate::app_style; // save
- QApplicationPrivate::overrides_native_style =
- nativeStyleClassName() == QByteArray(style->metaObject()->className());
- #ifndef QT_NO_STYLE_STYLESHEET
- if (!QApplicationPrivate::styleSheet.isEmpty() && !qobject_cast<QStyleSheetStyle *>(style)) {
- // we have a stylesheet already and a new style is being set
- QStyleSheetStyle *newProxy = new QStyleSheetStyle(style);
- style->setParent(newProxy);
- QApplicationPrivate::app_style = newProxy;
- } else
- #endif // QT_NO_STYLE_STYLESHEET
- QApplicationPrivate::app_style = style;
- QApplicationPrivate::app_style->setParent(qApp); // take ownership
- // take care of possible palette requirements of certain gui
- // styles. Do it before polishing the application since the style
- // might call QApplication::setPalette() itself
- if (QApplicationPrivate::set_pal) {
- QApplication::setPalette(*QApplicationPrivate::set_pal);
- } else if (QApplicationPrivate::sys_pal) {
- clearSystemPalette();
- initSystemPalette();
- QApplicationPrivate::initializeWidgetPaletteHash();
- QApplicationPrivate::initializeWidgetFontHash();
- QApplicationPrivate::setPalette_helper(*QApplicationPrivate::sys_pal, /*className=*/, /*clearWidgetPaletteHash=*/false);
- } else if (!QApplicationPrivate::sys_pal) {
- // Initialize the sys_pal if it hasn't happened yet...
- QApplicationPrivate::setSystemPalette(QApplicationPrivate::app_style->standardPalette());
- }
- // initialize the application with the new style
- QApplicationPrivate::app_style->polish(qApp);
- // re-polish existing widgets if necessary
- if (QApplicationPrivate::is_app_running && !QApplicationPrivate::is_app_closing) {
- for (QWidgetList::ConstIterator it = all.constBegin(), cend = all.constEnd(); it != cend; ++it) {
- QWidget *w = *it;
- if (w->windowType() != Qt::Desktop && w->testAttribute(Qt::WA_WState_Polished)) {
- if (w->style() == QApplicationPrivate::app_style)
- QApplicationPrivate::app_style->polish(w); // repolish
- #ifndef QT_NO_STYLE_STYLESHEET
- else
- w->setStyleSheet(w->styleSheet()); // touch
- #endif
- }
- }
- for (QWidgetList::ConstIterator it = all.constBegin(), cend = all.constEnd(); it != cend; ++it) {
- QWidget *w = *it;
- if (w->windowType() != Qt::Desktop && !w->testAttribute(Qt::WA_SetStyle)) {
- QEvent e(QEvent::StyleChange);
- QApplication::sendEvent(w, &e);
- w->update();
- }
- }
- }
- #ifndef QT_NO_STYLE_STYLESHEET
- if (QStyleSheetStyle *oldProxy = qobject_cast<QStyleSheetStyle *>(old)) {
- oldProxy->deref();
- } else
- #endif
- if (old && old->parent() == qApp) {
- delete old;
- }
- if (QApplicationPrivate::focus_widget) {
- QFocusEvent in(QEvent::FocusIn, Qt::OtherFocusReason);
- QApplication::sendEvent(QApplicationPrivate::focus_widget->style(), &in);
- QApplicationPrivate::focus_widget->update();
- }
- }
2-1. 获取所有的QWidget列表(在QWidget的构造函数中调用QWidgetPrivate::init函数,将当前QWidget加入到列表)。
2-2. 移除所有QWidget上旧的样式。
2-3. 设置所有QWidget新的样式。
2-4. 更新所有的QWidget。
4. "QStyleSheetStyle::styleRules"——经过一系列调用到这个函数中,获取样式规则:
- QVector<QCss::StyleRule> QStyleSheetStyle::styleRules(const QObject *obj) const
- {
- QHash<const QObject *, QVector<StyleRule> >::const_iterator cacheIt = styleSheetCaches->styleRulesCache.constFind(obj);
- if (cacheIt != styleSheetCaches->styleRulesCache.constEnd())
- return cacheIt.value();
- if (!initObject(obj)) {
- return QVector<StyleRule>();
- }
- QStyleSheetStyleSelector styleSelector;
- StyleSheet defaultSs;
- QHash<const void *, StyleSheet>::const_iterator defaultCacheIt = styleSheetCaches->styleSheetCache.constFind(baseStyle());
- if (defaultCacheIt == styleSheetCaches->styleSheetCache.constEnd()) {
- defaultSs = getDefaultStyleSheet();
- QStyle *bs = baseStyle();
- styleSheetCaches->styleSheetCache.insert(bs, defaultSs);
- QObject::connect(bs, SIGNAL(destroyed(QObject*)), styleSheetCaches, SLOT(styleDestroyed(QObject*)), Qt::UniqueConnection);
- } else {
- defaultSs = defaultCacheIt.value();
- }
- styleSelector.styleSheets += defaultSs;
- if (!qApp->styleSheet().isEmpty()) {
- StyleSheet appSs;
- QHash<const void *, StyleSheet>::const_iterator appCacheIt = styleSheetCaches->styleSheetCache.constFind(qApp);
- if (appCacheIt == styleSheetCaches->styleSheetCache.constEnd()) {
- QString ss = qApp->styleSheet();
- if (ss.startsWith(QLatin1String("file:///")))
- ss.remove(0, 8);
- parser.init(ss, qApp->styleSheet() != ss);
- if (!parser.parse(&appSs))
- qWarning("Could not parse application stylesheet");
- appSs.origin = StyleSheetOrigin_Inline;
- appSs.depth = 1;
- styleSheetCaches->styleSheetCache.insert(qApp, appSs);
- } else {
- appSs = appCacheIt.value();
- }
- styleSelector.styleSheets += appSs;
- }
- QVector<QCss::StyleSheet> objectSs;
- for (const QObject *o = obj; o; o = parentObject(o)) {
- QString styleSheet = o->property("styleSheet").toString();
- if (styleSheet.isEmpty())
- continue;
- StyleSheet ss;
- QHash<const void *, StyleSheet>::const_iterator objCacheIt = styleSheetCaches->styleSheetCache.constFind(o);
- if (objCacheIt == styleSheetCaches->styleSheetCache.constEnd()) {
- parser.init(styleSheet);
- if (!parser.parse(&ss)) {
- parser.init(QLatin1String("* {") + styleSheet + QLatin1Char('}'));
- if (!parser.parse(&ss))
- qWarning("Could not parse stylesheet of object %p", o);
- }
- ss.origin = StyleSheetOrigin_Inline;
- styleSheetCaches->styleSheetCache.insert(o, ss);
- } else {
- ss = objCacheIt.value();
- }
- objectSs.append(ss);
- }
- for (int i = ; i < objectSs.count(); i++)
- objectSs[i].depth = objectSs.count() - i + ;
- styleSelector.styleSheets += objectSs;
- StyleSelector::NodePtr n;
- n.ptr = const_cast<QObject *>(obj);
- QVector<QCss::StyleRule> rules = styleSelector.styleRulesForNode(n);
- styleSheetCaches->styleRulesCache.insert(obj, rules);
- return rules;
- }
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. 初始化解析器:
- void Parser::init(const QString &css, bool isFile)
- {
- QString styleSheet = css;
- if (isFile) {
- QFile file(css);
- if (file.open(QFile::ReadOnly)) {
- sourcePath = QFileInfo(styleSheet).absolutePath() + QLatin1Char('/');
- QTextStream stream(&file);
- styleSheet = stream.readAll();
- } else {
- qWarning() << "QCss::Parser - Failed to load file " << css;
- styleSheet.clear();
- }
- } else {
- sourcePath.clear();
- }
- hasEscapeSequences = false;
- symbols.resize();
- symbols.reserve();
- Scanner::scan(Scanner::preprocess(styleSheet, &hasEscapeSequences), &symbols);
- index = ;
- errorIndex = -;
- }
5-1-1. 将字符串进行预处理(这里主要是处理转义字符)。
5-1-2. 逐个扫描形成一个一个符号(与编译原理中的扫描程序一致,形成符号后,方便后面进一步处理)。
5-2. 解析样式表:
- bool Parser::parse(StyleSheet *styleSheet, Qt::CaseSensitivity nameCaseSensitivity)
- {
- if (testTokenAndEndsWith(ATKEYWORD_SYM, QLatin1String("charset"))) {
- if (!next(STRING)) return false;
- if (!next(SEMICOLON)) return false;
- }
- while (test(S) || test(CDO) || test(CDC)) {}
- while (testImport()) {
- ImportRule rule;
- if (!parseImport(&rule)) return false;
- styleSheet->importRules.append(rule);
- while (test(S) || test(CDO) || test(CDC)) {}
- }
- do {
- if (testMedia()) {
- MediaRule rule;
- if (!parseMedia(&rule)) return false;
- styleSheet->mediaRules.append(rule);
- } else if (testPage()) {
- PageRule rule;
- if (!parsePage(&rule)) return false;
- styleSheet->pageRules.append(rule);
- } else if (testRuleset()) {
- StyleRule rule;
- if (!parseRuleset(&rule)) return false;
- styleSheet->styleRules.append(rule);
- } else if (test(ATKEYWORD_SYM)) {
- if (!until(RBRACE)) return false;
- } else if (hasNext()) {
- return false;
- }
- while (test(S) || test(CDO) || test(CDC)) {}
- } while (hasNext());
- styleSheet->buildIndexes(nameCaseSensitivity);
- return true;
- }
5-2-1. 遍历所有符号,根据符号的类型进行相应的处理(这里我们只关注样式规则"parseRuleset(&rule)")。
5-2-2. 解析样式规则:
- bool Parser::parseRuleset(StyleRule *styleRule)
- {
- Selector sel;
- if (!parseSelector(&sel)) return false;
- styleRule->selectors.append(sel);
- while (test(COMMA)) {
- skipSpace();
- Selector sel;
- if (!parseNextSelector(&sel)) return false;
- styleRule->selectors.append(sel);
- }
- skipSpace();
- if (!next(LBRACE)) return false;
- const int declarationStart = index;
- do {
- skipSpace();
- Declaration decl;
- const int rewind = index;
- if (!parseNextDeclaration(&decl)) {
- index = rewind;
- const bool foundSemicolon = until(SEMICOLON);
- const int semicolonIndex = index;
- index = declarationStart;
- const bool foundRBrace = until(RBRACE);
- if (foundSemicolon && semicolonIndex < index) {
- decl = Declaration();
- index = semicolonIndex - ;
- } else {
- skipSpace();
- return foundRBrace;
- }
- }
- if (!decl.isEmpty())
- styleRule->declarations.append(decl);
- } while (test(SEMICOLON));
- if (!next(RBRACE)) return false;
- skipSpace();
- return true;
- }
5-2-2-1. 解析选择器(id选着器,class选着器,属性选着器等)。
5-2-2-2. 解析声明,包括属性名、属性值等。
5-2-2-3. 将解析的声明添加到样式规则中。
6. (4-5的细化)根据样式选着器(QStyleSheetStyleSelector)得到样式规则"":
- QVector<StyleRule> StyleSelector::styleRulesForNode(NodePtr node)
- {
- QVector<StyleRule> rules;
- if (styleSheets.isEmpty())
- return rules;
- QMap<uint, StyleRule> weightedRules; // (spec, rule) that will be sorted below
- //prune using indexed stylesheet
- for (int sheetIdx = ; sheetIdx < styleSheets.count(); ++sheetIdx) {
- const StyleSheet &styleSheet = styleSheets.at(sheetIdx);
- for (int i = 0; i < styleSheet.styleRules.count(); ++i) {
- matchRule(node, styleSheet.styleRules.at(i), styleSheet.origin, styleSheet.depth, &weightedRules);
- }
- if (!styleSheet.idIndex.isEmpty()) {
- QStringList ids = nodeIds(node);
- for (int i = 0; i < ids.count(); i++) {
- const QString &key = ids.at(i);
- QMultiHash<QString, StyleRule>::const_iterator it = styleSheet.idIndex.constFind(key);
- while (it != styleSheet.idIndex.constEnd() && it.key() == key) {
- matchRule(node, it.value(), styleSheet.origin, styleSheet.depth, &weightedRules);
- ++it;
- }
- }
- }
- if (!styleSheet.nameIndex.isEmpty()) {
- QStringList names = nodeNames(node);
- for (int i = 0; i < names.count(); i++) {
- QString name = names.at(i);
- if (nameCaseSensitivity == Qt::CaseInsensitive)
- name = name.toLower();
- QMultiHash<QString, StyleRule>::const_iterator it = styleSheet.nameIndex.constFind(name);
- while (it != styleSheet.nameIndex.constEnd() && it.key() == name) {
- matchRule(node, it.value(), styleSheet.origin, styleSheet.depth, &weightedRules);
- ++it;
- }
- }
- }
- if (!medium.isEmpty()) {
- for (int i = ; i < styleSheet.mediaRules.count(); ++i) {
- if (styleSheet.mediaRules.at(i).media.contains(medium, Qt::CaseInsensitive)) {
- for (int j = ; j < styleSheet.mediaRules.at(i).styleRules.count(); ++j) {
- matchRule(node, styleSheet.mediaRules.at(i).styleRules.at(j), styleSheet.origin,
- styleSheet.depth, &weightedRules);
- }
- }
- }
- }
- }
- rules.reserve(weightedRules.count());
- QMap<uint, StyleRule>::const_iterator it = weightedRules.constBegin();
- for ( ; it != weightedRules.constEnd() ; ++it)
- rules += *it;
- return rules;
- }
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. 最后需要渲染规则,将得到的样式规则转换为绘制时需要的对象(字体、颜色、背景画刷、背景图片等等):
- QRenderRule::QRenderRule(const QVector<Declaration> &declarations, const QObject *object)
- : features(), hasFont(false), pal(), b(), bg(), bd(), ou(), geo(), p(), img(), clipset()
- {
- QPalette palette = QApplication::palette(); // ###: ideally widget's palette
- ValueExtractor v(declarations, palette)zhua
- features = v.extractStyleFeatures();
- int w = -, h = -, minw = -, minh = -, maxw = -, maxh = -;
- if (v.extractGeometry(&w, &h, &minw, &minh, &maxw, &maxh))
- geo = new QStyleSheetGeometryData(w, h, minw, minh, maxw, maxh);
- int left = , top = , right = , bottom = ;
- Origin origin = Origin_Unknown;
- Qt::Alignment position = ;
- QCss::PositionMode mode = PositionMode_Unknown;
- Qt::Alignment textAlignment = ;
- if (v.extractPosition(&left, &top, &right, &bottom, &origin, &position, &mode, &textAlignment))
- p = new QStyleSheetPositionData(left, top, right, bottom, origin, position, mode, textAlignment);
- int margins[], paddings[], spacing = -;
- for (int i = ; i < ; i++)
- margins[i] = paddings[i] = ;
- if (v.extractBox(margins, paddings, &spacing))
- b = new QStyleSheetBoxData(margins, paddings, spacing);
- int borders[];
- QBrush colors[];
- QCss::BorderStyle styles[];
- QSize radii[];
- for (int i = ; i < ; i++) {
- borders[i] = ;
- styles[i] = BorderStyle_None;
- }
- if (v.extractBorder(borders, colors, styles, radii))
- bd = new QStyleSheetBorderData(borders, colors, styles, radii);
- int offsets[];
- for (int i = ; i < ; i++) {
- borders[i] = offsets[i] = ;
- styles[i] = BorderStyle_None;
- }
- if (v.extractOutline(borders, colors, styles, radii, offsets))
- ou = new QStyleSheetOutlineData(borders, colors, styles, radii, offsets);
- QBrush brush;
- QString uri;
- Repeat repeat = Repeat_XY;
- Qt::Alignment alignment = Qt::AlignTop | Qt::AlignLeft;
- Attachment attachment = Attachment_Scroll;
- origin = Origin_Padding;
- Origin clip = Origin_Border;
- if (v.extractBackground(&brush, &uri, &repeat, &alignment, &origin, &attachment, &clip))
- bg = new QStyleSheetBackgroundData(brush, QPixmap(uri), repeat, alignment, origin, attachment, clip);
- QBrush sfg, fg;
- QBrush sbg, abg;
- if (v.extractPalette(&fg, &sfg, &sbg, &abg))
- pal = new QStyleSheetPaletteData(fg, sfg, sbg, abg);
- QIcon icon;
- alignment = Qt::AlignCenter;
- QSize size;
- if (v.extractImage(&icon, &alignment, &size))
- img = new QStyleSheetImageData(icon, alignment, size);
- int adj = -;
- hasFont = v.extractFont(&font, &adj);
- #ifndef QT_NO_TOOLTIP
- if (object && qstrcmp(object->metaObject()->className(), "QTipLabel") == )
- palette = QToolTip::palette();
- #endif
- for (int i = ; i < declarations.count(); i++) {
- const Declaration& decl = declarations.at(i);
- if (decl.d->propertyId == BorderImage) {
- QString uri;
- QCss::TileMode horizStretch, vertStretch;
- int cuts[];
- decl.borderImageValue(&uri, cuts, &horizStretch, &vertStretch);
- if (uri.isEmpty() || uri == QLatin1String("none")) {
- if (bd && bd->bi)
- bd->bi->pixmap = QPixmap();
- } else {
- if (!bd)
- bd = new QStyleSheetBorderData;
- if (!bd->bi)
- bd->bi = new QStyleSheetBorderImageData;
- QStyleSheetBorderImageData *bi = bd->bi;
- bi->pixmap = QPixmap(uri);
- for (int i = ; i < ; i++)
- bi->cuts[i] = cuts[i];
- bi->horizStretch = horizStretch;
- bi->vertStretch = vertStretch;
- }
- } else if (decl.d->propertyId == QtBackgroundRole) {
- if (bg && bg->brush.style() != Qt::NoBrush)
- continue;
- int role = decl.d->values.at().variant.toInt();
- if (role >= Value_FirstColorRole && role <= Value_LastColorRole)
- defaultBackground = palette.color((QPalette::ColorRole)(role-Value_FirstColorRole));
- } else if (decl.d->property.startsWith(QLatin1String("qproperty-"), Qt::CaseInsensitive)) {
- // intentionally left blank...
- } else if (decl.d->propertyId == UnknownProperty) {
- bool knownStyleHint = false;
- for (int i = ; i < numKnownStyleHints; i++) {
- QLatin1String styleHint(knownStyleHints[i]);
- if (decl.d->property.compare(styleHint) == ) {
- QString hintName = QString(styleHint);
- QVariant hintValue;
- if (hintName.endsWith(QLatin1String("alignment"))) {
- hintValue = (int) decl.alignmentValue();
- } else if (hintName.endsWith(QLatin1String("color"))) {
- hintValue = (int) decl.colorValue().rgba();
- } else if (hintName.endsWith(QLatin1String("size"))) {
- hintValue = decl.sizeValue();
- } else if (hintName.endsWith(QLatin1String("icon"))) {
- hintValue = decl.iconValue();
- } else if (hintName == QLatin1String("button-layout")
- && decl.d->values.count() != && decl.d->values.at().type == Value::String) {
- hintValue = subControlLayout(decl.d->values.at().variant.toString());
- } else {
- int integer;
- decl.intValue(&integer);
- hintValue = integer;
- }
- styleHints[decl.d->property] = hintValue;
- knownStyleHint = true;
- break;
- }
- }
- if (!knownStyleHint)
- qDebug("Unknown property %s", qPrintable(decl.d->property));
- }
- }
- if (const QWidget *widget = qobject_cast<const QWidget *>(object)) {
- QStyleSheetStyle *style = const_cast<QStyleSheetStyle *>(globalStyleSheetStyle);
- if (!style)
- style = qobject_cast<QStyleSheetStyle *>(widget->style());
- if (style)
- fixupBorder(style->nativeFrameWidth(widget));
- }
- if (hasBorder() && border()->hasBorderImage())
- defaultBackground = QBrush();
- }
从样式规则中得到样式声明,然后根据样式声明去创建不同的绘制对象,为后面的绘制做准备。
绘制对象包括:位置(Geomeory、Position、Box)、边框(Border、Outline)、背景(BackgroundColor、BackgroundImage等)、字体(FontFamily、FontSize、FontStyle、FontWeight等)等等。
最后如果想查看QSS属性名称和值的列表,可以查看qtbase\src\gui\text\qcssparser.cpp文件:
- static const QCssKnownValue properties[NumProperties - ] = {
- { "-qt-background-role", QtBackgroundRole },
- { "-qt-block-indent", QtBlockIndent },
- { "-qt-list-indent", QtListIndent },
- { "-qt-list-number-prefix", QtListNumberPrefix },
- { "-qt-list-number-suffix", QtListNumberSuffix },
- { "-qt-paragraph-type", QtParagraphType },
- { "-qt-style-features", QtStyleFeatures },
- { "-qt-table-type", QtTableType },
- { "-qt-user-state", QtUserState },
- { "alternate-background-color", QtAlternateBackground },
- { "background", Background },
- { "background-attachment", BackgroundAttachment },
- { "background-clip", BackgroundClip },
- { "background-color", BackgroundColor },
- { "background-image", BackgroundImage },
- { "background-origin", BackgroundOrigin },
- { "background-position", BackgroundPosition },
- { "background-repeat", BackgroundRepeat },
- { "border", Border },
- { "border-bottom", BorderBottom },
- { "border-bottom-color", BorderBottomColor },
- { "border-bottom-left-radius", BorderBottomLeftRadius },
- { "border-bottom-right-radius", BorderBottomRightRadius },
- { "border-bottom-style", BorderBottomStyle },
- { "border-bottom-width", BorderBottomWidth },
- { "border-color", BorderColor },
- { "border-image", BorderImage },
- { "border-left", BorderLeft },
- { "border-left-color", BorderLeftColor },
- { "border-left-style", BorderLeftStyle },
- { "border-left-width", BorderLeftWidth },
- { "border-radius", BorderRadius },
- { "border-right", BorderRight },
- { "border-right-color", BorderRightColor },
- { "border-right-style", BorderRightStyle },
- { "border-right-width", BorderRightWidth },
- { "border-style", BorderStyles },
- { "border-top", BorderTop },
- { "border-top-color", BorderTopColor },
- { "border-top-left-radius", BorderTopLeftRadius },
- { "border-top-right-radius", BorderTopRightRadius },
- { "border-top-style", BorderTopStyle },
- { "border-top-width", BorderTopWidth },
- { "border-width", BorderWidth },
- { "bottom", Bottom },
- { "color", Color },
- { "float", Float },
- { "font", Font },
- { "font-family", FontFamily },
- { "font-size", FontSize },
- { "font-style", FontStyle },
- { "font-variant", FontVariant },
- { "font-weight", FontWeight },
- { "height", Height },
- { "image", QtImage },
- { "image-position", QtImageAlignment },
- { "left", Left },
- { "line-height", LineHeight },
- { "list-style", ListStyle },
- { "list-style-type", ListStyleType },
- { "margin" , Margin },
- { "margin-bottom", MarginBottom },
- { "margin-left", MarginLeft },
- { "margin-right", MarginRight },
- { "margin-top", MarginTop },
- { "max-height", MaximumHeight },
- { "max-width", MaximumWidth },
- { "min-height", MinimumHeight },
- { "min-width", MinimumWidth },
- { "outline", Outline },
- { "outline-bottom-left-radius", OutlineBottomLeftRadius },
- { "outline-bottom-right-radius", OutlineBottomRightRadius },
- { "outline-color", OutlineColor },
- { "outline-offset", OutlineOffset },
- { "outline-radius", OutlineRadius },
- { "outline-style", OutlineStyle },
- { "outline-top-left-radius", OutlineTopLeftRadius },
- { "outline-top-right-radius", OutlineTopRightRadius },
- { "outline-width", OutlineWidth },
- { "padding", Padding },
- { "padding-bottom", PaddingBottom },
- { "padding-left", PaddingLeft },
- { "padding-right", PaddingRight },
- { "padding-top", PaddingTop },
- { "page-break-after", PageBreakAfter },
- { "page-break-before", PageBreakBefore },
- { "position", Position },
- { "right", Right },
- { "selection-background-color", QtSelectionBackground },
- { "selection-color", QtSelectionForeground },
- { "spacing", QtSpacing },
- { "subcontrol-origin", QtOrigin },
- { "subcontrol-position", QtPosition },
- { "text-align", TextAlignment },
- { "text-decoration", TextDecoration },
- { "text-indent", TextIndent },
- { "text-transform", TextTransform },
- { "text-underline-style", TextUnderlineStyle },
- { "top", Top },
- { "vertical-align", VerticalAlignment },
- { "white-space", Whitespace },
- { "width", Width }
- };
- static const QCssKnownValue values[NumKnownValues - ] = {
- { "active", Value_Active },
- { "alternate-base", Value_AlternateBase },
- { "always", Value_Always },
- { "auto", Value_Auto },
- { "base", Value_Base },
- { "bold", Value_Bold },
- { "bottom", Value_Bottom },
- { "bright-text", Value_BrightText },
- { "button", Value_Button },
- { "button-text", Value_ButtonText },
- { "center", Value_Center },
- { "circle", Value_Circle },
- { "dark", Value_Dark },
- { "dashed", Value_Dashed },
- { "decimal", Value_Decimal },
- { "disabled", Value_Disabled },
- { "disc", Value_Disc },
- { "dot-dash", Value_DotDash },
- { "dot-dot-dash", Value_DotDotDash },
- { "dotted", Value_Dotted },
- { "double", Value_Double },
- { "groove", Value_Groove },
- { "highlight", Value_Highlight },
- { "highlighted-text", Value_HighlightedText },
- { "inset", Value_Inset },
- { "italic", Value_Italic },
- { "large", Value_Large },
- { "left", Value_Left },
- { "light", Value_Light },
- { "line-through", Value_LineThrough },
- { "link", Value_Link },
- { "link-visited", Value_LinkVisited },
- { "lower-alpha", Value_LowerAlpha },
- { "lower-roman", Value_LowerRoman },
- { "lowercase", Value_Lowercase },
- { "medium", Value_Medium },
- { "mid", Value_Mid },
- { "middle", Value_Middle },
- { "midlight", Value_Midlight },
- { "native", Value_Native },
- { "none", Value_None },
- { "normal", Value_Normal },
- { "nowrap", Value_NoWrap },
- { "oblique", Value_Oblique },
- { "off", Value_Off },
- { "on", Value_On },
- { "outset", Value_Outset },
- { "overline", Value_Overline },
- { "pre", Value_Pre },
- { "pre-wrap", Value_PreWrap },
- { "ridge", Value_Ridge },
- { "right", Value_Right },
- { "selected", Value_Selected },
- { "shadow", Value_Shadow },
- { "small" , Value_Small },
- { "small-caps", Value_SmallCaps },
- { "solid", Value_Solid },
- { "square", Value_Square },
- { "sub", Value_Sub },
- { "super", Value_Super },
- { "text", Value_Text },
- { "top", Value_Top },
- { "transparent", Value_Transparent },
- { "underline", Value_Underline },
- { "upper-alpha", Value_UpperAlpha },
- { "upper-roman", Value_UpperRoman },
- { "uppercase", Value_Uppercase },
- { "wave", Value_Wave },
- { "window", Value_Window },
- { "window-text", Value_WindowText },
- { "x-large", Value_XLarge },
- { "xx-large", Value_XXLarge }
- };
QT源码剖析之QSS样式表的更多相关文章
- Qt系统对话框中文化及应用程序实现重启及使用QSS样式表文件及使用程序启动界面
一.应用程序中文化 1).Qt安装目录下有一个目录translations/,在此目录下有qt_zh_CN.ts和 qt_zh_CN.qm把它们拷贝到你的工程目录下. 2).在main函数加入下列代码 ...
- 菜鸟nginx源码剖析数据结构篇(七) 哈希表 ngx_hash_t(下)[转]
菜鸟nginx源码剖析数据结构篇(七) 哈希表 ngx_hash_t(下) Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.c ...
- 菜鸟nginx源码剖析数据结构篇(六) 哈希表 ngx_hash_t(上)[转]
菜鸟nginx源码剖析数据结构篇(六) 哈希表 ngx_hash_t(上) Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.c ...
- Qt信号槽源码剖析(一)
大家好,我是IT文艺男,来自一线大厂的一线程序员 大家在使用Qt开发程序时,都知道怎么使用Qt的信号槽,但是Qt信号槽是怎么工作的? 大部分人仍然不知道:也就是说大家只知道怎么使用,却不知道基于什么原 ...
- Qt信号槽源码剖析(二)
大家好,我是IT文艺男,来自一线大厂的一线程序员 上节视频给大家讲解了Qt信号槽的基本概念.元对象编译器.示例代码以及Qt宏:今天接着深入分析,进入Qt信号槽源码剖析系列的第二节视频. Qt信号槽的宏 ...
- (文字版)Qt信号槽源码剖析(三)
大家好,我是IT文艺男,来自一线大厂的一线程序员 上节视频给大家讲解了Qt信号槽的Qt宏展开推导:今天接着深入分析,进入Qt信号槽源码剖析系列的第三节视频. Qt信号槽宏推导归纳 #define si ...
- 基于mybatis-generator-core 1.3.5项目的修订版以及源码剖析
项目简单说明 mybatis-generator,是根据数据库表.字段反向生成实体类等代码文件.我在国庆时候,没事剖析了mybatis-generator-core源码,写了相当详细的中文注释,可以去 ...
- STL"源码"剖析-重点知识总结
STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点略多 :) 1.STL概述 STL提供六大组件,彼此可以组合 ...
- socket_server源码剖析、python作用域、IO多路复用
本节内容: 课前准备知识: 函数嵌套函数的使用方法: 我们在使用函数嵌套函数的时候,是学习装饰器的时候,出现过,由一个函数返回值是一个函数体情况. 我们在使用函数嵌套函数的时候,最好也这么写. def ...
随机推荐
- OleDbCommand cmd.Parameters.AddWithValue 添加参数时需要按照存储过程参数的顺序加入
在使用存储过程时,参数出入的顺序要一致.
- Android开发华为手机无法看log日志解决方法
Android开发华为手机无法看log日志解决方法 上班的时候,由于开发工具由Eclipse改成Android Studio后,原本的华为手机突然无法查看崩溃日志了,大家都知道,若是无法查看日志要它毛 ...
- swift设置textfield边框颜色
//swift3.0,如果是2.0的话也可以照着这个样子去写,语法有所变动.根据联想出来的就可以了. let tx = UITextField(frame: CGRect(x: 100, y: 100 ...
- Js-Html 前端系列--点击非Div区域隐藏Div
最近做项目要用到三字码下拉,调用一个插件,但是滚动条不能点击. 后来看另一个插件后突发奇想,在点击其他区域的时候隐藏这个Div就可以了. 背景:输入文字,弹出下拉Div,点击或者拉动Div滚动条选择, ...
- JavaScript字符和数组一些基本算法题
1.翻转字符串 例子(要求:先把字符串转化成数组,再借助数组的reverse方法翻转数组顺序,最后把数组转化成字符串) function reverseString(str) { str=str.sp ...
- RelativeLayout各个属性
android:layout_above="@id/xxx" --将控件置于给定ID控件之上 android:layout_below="@id/xxx" ...
- ToDictionary用法
ToDictionary其实可以简单化,可以传两个lambada表达式,第一个是Key,第二个就是Value. ToDictionary( key => key.Attribute(" ...
- django 学习笔记(一)搭建基础环境
1.安装django 下载地址 https://github.com/django/django 解压后进入文件夹运行指令 >> python setup.py install 2.创建工 ...
- List list = new ArrayList()
方便以后扩展List是一个接口,而ArrayList 是一个类. ArrayList 继承并实现了List.List list = new ArrayList();这句创建了一个ArrayList的对 ...
- Java 基础知识(一)
Java基础知识篇: 一.关键字解释 1. final:修饰非抽象类,非抽象方法和属性, 以及修饰方法参数,代表“无法改变的”.出于对设计或者效率的考虑使用该关键字. final类无法被继承,fina ...