一、语法高亮设置
Qt Creator中默认情况下打开qss文件(*.qss)不会高亮显示,需要手动配置,让其更符合阅读习惯,以更炫丽的方式展示代码片段。
配置流程如下:
A、进入:工具 -> 选项 -> 环境 -> MIME 类型。
B、在【已注册的MIME类型】处输入“text/css”可以快速定位,然后在【详情】中的“模式”处添加 *.qss,即将原来的“模式”改为:*.css;*.CSSL;*.qss。
注意:中间用分号(;)分隔
![图片1.png wKioL1h3MLazus55AAB8TRdrkAs237.png](https://i-blog.csdnimg.cn/blog_migrate/7f040c29b8d44bc82278da6f68a16ad9.png)
效果如下:
![图片2.png wKiom1h3MNejeEi9AABIOKASKwM740.png](https://i-blog.csdnimg.cn/blog_migrate/db88da962954b8346ea5ea144c28e63c.png)
二、动态属性
1、自定义属性
为了用户界面外观的动态变化,属性选择器可以与动态属性组合使用。动态属性在QT4.2中引入,允许为编译时不存在的QObject属性分配属性值。即:如果为QObject设置一个urgent属性为true,该属性将跟随该类,但不会为urgent属性包含一个Q_PROPERTY宏。
创建样式选择器依赖于动态属性,例如:urgent,可以用一个非常动态的方式凸显用户界面。例如:
QLineEdit[urgent=true] {
color: red;
}
使用这种方式有局限性。最主要的是当一个属性值变化时,所引用的样式不会自动更新。相反地,必须手动触发更新才会生效。
unpolish()用于清理之前的样式,而polish()则用于添加新的样式。
lineEdit->setProperty("urgent", true);
lineEdit->style()->unpolish(lineEdit);
lineEdit->style()->polish(lineEdit);
必须在组件的样式中使用,QStyle::polish既接受QWidge也接受QApplication作为参数。
2、实例
自定义标题栏中的最大化/还原按钮为例,进行切换。
![图片3.png wKiom1h3MRHBOysGAAAIRnyXx3k258.png](https://i-blog.csdnimg.cn/blog_migrate/6aaffbd200019b3cad2b01213e6f0d07.png)
![图片4.png wKioL1h3MRKw4DRuAAAIgQP_mmI528.png](https://i-blog.csdnimg.cn/blog_migrate/0ad48e1f12f52a51c96e03837ee8a06c.png)
- void TitleBar::updateMaximize(){ QWidget *pWindow = this->window(); if (pWindow->isTopLevel()) { bool bMaximize = pWindow->isMaximized(); m_pMaximizeButton->setToolTip(bMaximize ? tr("Restore") : tr("Maximize")); m_pMaximizeButton->setProperty("maximizeProperty", bMaximize ? "restore" : "maximize");
QSS:
- QPushButton#maximizeButton[maximizeProperty="maximize"] { border-radius: none; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; background: rgb(50, 50, 50); image: url(:/Images/maximize);}QPushButton#maximizeButton[maximizeProperty="maximize"]:hover { background: rgb(60, 60, 60); image: url(:/Images/maximizeHover);}QPushButton#maximizeButton[maximizeProperty="maximize"]:pressed { background: rgb(55, 55, 55); image: url(:/Images/maximizePressed);}QPushButton#maximizeButton[maximizeProperty="restore"] { border-radius: none; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; background: rgb(50, 50, 50); image: url(:/Images/restore);}QPushButton#maximizeButton[maximizeProperty="restore"]:hover { background: rgb(60, 60, 60); image: url(:/Images/restoreHover);}QPushButton#maximizeButton[maximizeProperty="restore"]:pressed { background: rgb(55, 55, 55); image: url(:/Images/restorePressed);
三、原始属性
任何可被识别的Q_PROPERTY都可以使用qproperty-语法设置。
Q_PROPERTY定义的属性通过QSS按照qproperty-<property name>语法的方式设置。
QLabel的属性如下:
- class Q_WIDGETS_EXPORT QLabel : public QFrame{ ... Q_PROPERTY(QPixmap pixmap READ pixmap WRITE setPixmap) Q_PROPERTY(bool scaledContents READ hasScaledContents WRITE setScaledContents) ...};class Q_WIDGETS_EXPORT QWidget : public QObject, public QPaintDevice{ ... Q_PROPERTY(QSize minimumSize READ minimumSize WRITE setMinimumSize) Q_PROPERTY(QSize maximumSize READ maximumSize WRITE setMaximumSize) ...};
QLabel的属性有minimumSize、maximumSize、pixmap、scaledContents。
QSS文件:
- QLabel#customLabel { qproperty-minimumSize: 100px 100px; qproperty-maximumSize: 100px 100px; qproperty-pixmap: url(:/Images/logo); qproperty-scaledContents: true;} QPushButton#customButton { qproperty-text: "Click Me"; qproperty-icon: url(:/Images/logo); qproperty-iconSize: 20px 20px;} QGroupBox#customGroupBox { qproperty-title: "GroupBox";}
源码:
- Widget::Widget(QWidget *parent) : QWidget(parent){ QLabel *pLabel = new QLabel(this); QPushButton *pButton = new QPushButton(this); QGroupBox *pGroupBox = new QGroupBox(this); pLabel->setObjectName("customLabel"); pButton->setObjectName("customButton"); pGroupBox->setObjectName("customGroupBox"); QVBoxLayout *pLayout = new QVBoxLayout(); pLayout->addStretch(); pLayout->addWidget(pLabel, 0, Qt::AlignCenter); pLayout->addWidget(pButton); pLayout->addStretch(); pLayout->setSpacing(10); pLayout->setContentsMargins(10, 10, 10, 10); pGroupBox->setLayout(pLayout);}
Main.cpp文件:
- #include "Widget.h"#include <QApplication>#include <QFile> class CommonHelper{public: static void setStyle(const QString &style) { QFile qss(style); qss.open(QFile::ReadOnly); qApp->setStyleSheet(qss.readAll()); qss.close(); }}; int main(int argc, char *argv[]){ QApplication a(argc, argv); CommonHelper::setStyle(":/style.qss"); Widget w; w.show(); return a.exec();}
以上的解决方法将界面样式与业务逻辑进行了分离,效果与如下代码相同:
- pLabel->setPixmap(QPixmap(":/Images/logo"));pLabel->setMinimumSize(100, 100);pLabel->setMaximumSize(100, 100);pLabel->setScaledContents(true); pButton->setIcon(QIcon(":/Images/logo"));pButton->setIconSize(QSize(20, 20));pButton->setText("Click Me"); pGroupBox->setTitle("GroupBox");
四、自定义属性
1、自定义属性
QAbstractItemModel、QAbstractItemDelegate均继承自QObject,而QSS只能用于QWidget及其子类,动态获取样式属性值方法如下:
A、创建一个从QWidget继承的专用类StyledWidget。
B、为StyledWidget添加自定义属性,并使用Q_PROPERTY声明
C、自定义QSS,使用自定义属性,语法:qproperty-<property name>
其中,Q_PROPERTY声明有以下要求:
READ getFunction
用于读取属性,使用const限定,返回属性的类型或者类型的指针或引用。
WRITE setFunction
用于设置属性,参数是一个属性的类型,或者属性的const指针或引用,返回
2、应用实例
创建一个从QWidget继承的专用类StyledWidget,为其添加自定义属性,并使用Q_PROPERTY声明。
StyledWidget.h文件:
- #ifndef STYLEDWIDGET_H#define STYLEDWIDGET_H #include <QWidget> class StyledWidget : public QWidget{ Q_OBJECT Q_PROPERTY(QColor normalColor READ normalColor WRITE setNormalColor DESIGNABLE true) ...public: explicit StyledWidget(QWidget *parent = 0); ~StyledWidget(); QColor normalColor() const; void setNormalColor(QColor color); ... private: QColor m_normalColor; ...}; #endif // STYLEDWIDGET_H
StyledWidget.cpp文件:
- ...QColor StyledWidget::normalColor() const{ return m_normalColor;} void StyledWidget::setNormalColor(QColor color){ m_normalColor = color;}...
QSS文件:
- StyledWidget { qproperty-normalColor: white; qproperty-disableColor: gray; qproperty-highlightColor: rgb(0, 160, 230); qproperty-errorColor: red;}
使用:
在需要设置样式的类中声明StyledWidget:
- class TableModel : public QAbstractTableModel{ Q_OBJECTpublic: ... QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; ...private: ... StyledWidget m_styledWidget;};
使用自定义属性设置样式:
- QVariant TableModel::data(const QModelIndex &index, int role) const{ if (!index.isValid()) return QVariant(); switch (role) { case Qt::TextColorRole: { if (index.column() == FILE_NAME_COLUMN) return m_styledWidget.normalColor(); if (index.column() == SIZE_COLUMN) return m_styledWidget.highlightColor(); if (index.column() == STATUS_COLUMN) return m_styledWidget.errorColor(); } ... } return QVariant();}
![图片5.png wKioL1h3MT3QloiuAABCTpvStm8315.png](https://i-blog.csdnimg.cn/blog_migrate/034430fc4a5fbc5d103798ca2a5e6b2e.png)
五、QSS文件加载
QT中对于样式表的使用,为了降低耦合性(与逻辑代码分离),通常会定义一个QSS文件,然后编写各种组件(QLabel、 QLineEdit、QPushButton)的样式,最后使用QApplication进行样式加载,让整个应用程序就共享同一个样式。
1、创建QSS文件
创建一个后缀名为qss的文件,例如:style.qss,将其加入资源文件(qrc)中。
2、编写QSS文件
- QLineEdit{ border: 1px solid rgb(41, 57, 85); border-radius: 3px; background: white; selection-background-color: green; font-size: 14px ;}
3、QSS文件加载
为了便于调用,可以写一个静态加载样式的函数
- #include <QFile>#include <QApplication> class CommonHelper{public: static void setStyle(const QString &style) { QFile qss(style); qss.open(QFile::ReadOnly); qApp->setStyleSheet(qss.readAll()); qss.close(); }};
主函数中加载:
- int main(int argc, char *argv[]){ QApplication a(argc, argv);
4、QSS加载实现原理
qApp是QCoreApplication的一个单例,然后,将其转换为QApplication。
- #if defined(qApp)#undef qApp#endif#define qApp (static_cast<QApplication *>(QCoreApplication::instance()))
QApplication调用setStyleSheet()后所有的组件样式都改变的主要原因是调用了setStyle()。
- void QApplication::setStyle(QStyle *style){ if (!style || style == QApplicationPrivate::app_style) return; QWidgetList all = allWidgets();
主要分为4步:
A、清理旧样式 - unpolish()
B、初始化新样式 - polish()
C、加载新样式 - polish() + sendEvent()、update()
D、删除旧样式 - delete
通过调用QWidgetList all = allWidgets()获取了所有控件的集合,然后利用迭代器QWidgetList::ConstIterator对每一个控件进行处理,通 过QApplication::sendEvent()来发送QEvent::StyleChange事件,达到全局样式更改。
本博文转载自一去丶二三里的博客:http://blog.csdn.net/liang19890820