一、qss的实现
在QT中,除了基础的拖放ui控件来改变外观之外,QT还提供了一个类似于CSS的改变外观的方法,即qss。要在QT中使用qss,或者说改变widget中控件的外观,有以下方式实现:
1.直接在QtDesigner中,点击某一个控件,右击,选择改变样式表,设置自己所需要的样式。如图:
2.使用setStyleSheet加载qss文件。
2.1widget调用setStyleSheet方法,作用域于widget及子元素。
2.2QApplication调用setStyleSheet方法,作用于整个程序里面的widget。
例:
//控件已经在QtDesigner中进行拖放
ui->groupBox->setStyleSheet("border:1px solid black;");
//该样式将作用于当前的groupBo以及当前groupBox中的子元素
二、外部加载qss文件
一般在一个项目工程中,为了方便更改程序的外观,都会选择加载外部的qss文件来更改程序窗口的外观。加载外部qss文件的基本步骤如下:
//首先,确定qss文件所在的目录
//这里放在运行程序所在的目录下
QString qss = qApp->applicationDirPath() + "/QSS/left.qss";
//打开文件
QFile file(qss);
//判断文化是否存在
if(!file.open(QIODevice::ReadOnly))
{
qDebug() << "Open Fail";
return;
}
//如果存在 就将该文件中的内容全部读出来
QString content = file.readAll() + "/n";
//最后加载qss
qApp()->setStyleSheet(content);
但是,为了方便在程序运行的时候能实时看到修改后样式的效果,通常会考虑将加载文件的操作赋值一个快捷键,同时,将加载的方法写成一个单例的模式。
三、单例模式
单例模式是一种创建型的设计模式,保证了只有一个实例化对象的存在,具有延迟初始化,简单易用的特点,缺点就是在多线程的情况下,可能存在资源管理问题,要特别注意保证其安全性。
单例模式在QT中有以下的实现方法,只提供两种,具体的可以看一下这篇博文:QT中的单例模式
3.1 静态成员变量
在私有静态成员变量中保存单例对象的指针,并提供一个静态方法来获取该对象。这样就保证了只有一个实例化对象的实现。
//Person.h
class Person
{
private:
static Person* instance;
//保证线程的安全性
static QMutex mutex;
Person();
public:
static Person *getInstance();
}
//Person.cpp
Person* Person::instance = nullptr;
QMutex Person::mutex;
static Person *getInstance()
{
QMutexLocker locker(&mutex);
if(instance == nullptr)
{
instance = new Person();
}
return instance;
}
3.2 Q_GLOBAL_STATIC
QT提供了Q_GLOBAL_STATIC宏,可以方便地定义全局的单例对象。这个宏使用了线程安全的延迟初始化机制,并提供了方便地访问方式.
//使用Q_GLOBAL_STATIC宏
//Person.h
#ifndef PERSON_H
#define PERSON_H
class Person
{
//声明一个静态方法
public:
static Person* Instance();
}
#endif // PERSON_H
//Person.cpp
#include "Person.h"
Q_GLOBAL_STATIC(Person,person);
Person *Person::Instance()
{
return person();
}
四、加载qss
介绍完单例模式,下面就利用单例模式来完整实现在程序运行时加载qss文件。
4.1 首先,实现一个单例模式类,主要用于遍历存放qss文件的文件夹
QStringList G::getQssFiles()
{
// QStringList qssList;
QStringList qssList("*.qss");
QString fileName = qApp->applicationDirPath() + "/QSS";
//遍历循环存放qss文件的目录
//使用QDir的方法
QDir dir(fileName);
//判断目录是否存在
if(!dir.exists())
{
qDebug() <<"The File Path Not Exist" ;
}
//设置过滤器 遍历所有文件 过滤掉. ..
dir.setFilter(QDir::AllEntries | QDir::NoDotAndDotDot);
//QDir::setNameFilters方法用于设置文件过滤器
dir.setNameFilters(qssList);
//筛选出后缀名为qss的文件 存放在QStringList中
QStringList fList = dir.entryList();
QStringList aList;
if(fList.count() > 0)
{
foreach(QString fileNames,fList)
{
qDebug() << fileNames << " ";
aList.append(fileName+"/"+fileNames);
}
}
return aList;
}
4.2 实例化单例对象,获取qss文件,最后读取所有的qss文件加载
void UiUtil::loadQss()
{
QStringList flist = G::Instance()->getQssFiles();
//需要把所有文件中的QSS合并在一起
QString qss;
foreach(QString name,flist)
{
qDebug() << QString("=> 加载QSS文件 %1").arg(name);
QFile file(name);
if(!file.open(QIODevice::ReadOnly))
{
qDebug() << QString("打开QSS文件%1失败").arg(name);
continue;
}
qss.append(file.readAll()).append("\n");
}
if(!qss.isEmpty())
{
qApp->setStyleSheet(qss);
}
}
4.3 main()中实现快捷键操作,直接加载qss
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
QShortcut *shortCut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_L),&w);
QObject::connect(shortCut,&QShortcut::activated,[]{
UiUtil::loadQss();
});
w.show();
//
QString qss = "QMainWindow{border-radius:50%;}"
"QFrame{ backgroud:#AAA;border:2px dashed gray;} QPushButton {font-size:20px;padding:5px 20px;color:black;border:4px solid gray;background-color:rgb(230,250,250);}";
a.setStyleSheet(qss);
return a.exec();
}
五 结束