前言
迷迷糊糊的去看了关于qstyle的插件,看完后竟一脑浆糊,都不知道是什么东西。
这个qstyle插件主要改了各种部件的样式,从最底部改,比较全面高级。
有空就慢慢自己一步步构建一下简单的demo,仔细看看具体qstyle插件的具体实现流程吧。
框架基于adwaita项目,后续会在上面添加点效果和样式。代码一堆,要理解还真不容易。
当然这是后话,先踏出第一步吧。
qtcreator的cmake工程目录结构
新建一个cmake的工程,里面添加目录,一个style用于开发qtyle的库,另一个demo用于随便整一个简单的app应用并用上开发出来的库测试效果。
先分别在demo和style下建立CMakeLists.txt文件,先是空的,再在上一层的CMakeLists.txt添加add_subdirectory(demo)和add_subdirectory(style),就能在qtcreator工程看见目录结构了!
建立demo目录内容
在demo那里右键添加一个简单的ui类,选择widget:
会生成头文件和ui文件和cpp文件。
再把demo目录的CMakeLists.txt添加刚刚新建的内容:
include_directories(${CMAKE_CURRENT_BINARY_DIR})
set(demo_SRCS
main.cpp
demo.cpp
)
set(demo_UI
demo.ui
)
add_executable(demo ${demo_SRCS})
target_link_libraries(demo Qt5::Core Qt5::Widgets)
先随便拖一个button进去ui文件里吧。
main.cpp文件整一个app即可,应用style先留空:
#include <QApplication>
#include "demo.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QApplication::setStyle("");
demo fact;
fact.show();
return app.exec();
}
建立style目录内容
这里先把必要的内容写下,目录下新建一个贯穿全文的类——QStylePlugin类,当然我们是他的子类styleplugin,头文件写入:
#ifndef STYLEPLUGIN_H
#define STYLEPLUGIN_H
#include <QStylePlugin>
class StylePlugin : public QStylePlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QStyleFactoryInterface" FILE "mystyle.json" )
public:
//* constructor
explicit StylePlugin(QObject *parent = 0):
QStylePlugin(parent)
{}
//* destructor
~StylePlugin();
//* returns list of valid keys
QStringList keys() const;
//* create style
QStyle* create( const QString& );
};
#endif // STYLEPLUGIN_H
网上说这句Q_PLUGIN_METADATA(IID “org.qt-project.Qt.QStyleFactoryInterface” FILE “mystyle.json” )是十分重要的,但我不太理解这是什么东西。查资料说是创建了qt插件的符号,标识了新建的qt插件,emmmm我在暂时理解为起了个名字让以后使用提供名字符号?应该是这样?emmm先不求甚解毕竟有点迷糊。
如我的mystyle.json里面的内容是{ “Keys”: [ “mystyle” ] },意思是我的style插件名字是mystyle这个。app里面setStyle()就可以填入这个名字参数了。
ok,cpp文件写入:
#include "styleplugin.h"
#include "mystyle.h"
#include <QApplication>
QStyle* StylePlugin::create( const QString &key )
{
if( key.toLower() == QStringLiteral( "mystyle" ) )
{
return new MyStyle();
}
return nullptr;
}
StylePlugin::~StylePlugin()
{
}
QStringList StylePlugin::keys() const
{ return QStringList() << QStringLiteral( "mystyle" ); }
这里都是按照格式写一写(chao yi chao),这个MyStyle类就是我们自己改qt部件样式的具体内容类了!
然后是mystyle.h,继承于QCommonStyle:
#ifndef MYSTYLE_H
#define MYSTYLE_H
#include <QCommonStyle>
class MyStyle : public QCommonStyle
{
Q_OBJECT
public:
//* constructor
explicit MyStyle();
//* destructor
virtual ~MyStyle(void);
};
#endif // MYSTYLE_H
先留空,再是mystyle.cpp:
#include "mystyle.h"
MyStyle::MyStyle()
{
}
MyStyle::~MyStyle()
{
}
嘿嘿。。留空留空。
添加style的cmakelists内容:
set(myStyle_SRCS
styleplugin.cpp
mystyle.cpp
)
add_definitions(-DQT_PLUGIN)
include_directories(
${QT_INCLUDES}
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
)
set(LIBRARY_NAME "mystyle-qt${QT_VERSION_NUMBER}")
add_library(${LIBRARY_NAME} MODULE ${myStyle_SRCS})
target_link_libraries(${LIBRARY_NAME} ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTDBUS_LIBRARY})
set_target_properties(${LIBRARY_NAME} PROPERTIES
LINK_FLAGS "-Wl,--no-undefined"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
OUTPUT_NAME "mystyle"
PREFIX "")
install(TARGETS ${LIBRARY_NAME} DESTINATION "${QT_PLUGINS_DIR}/styles")
这边后半部分比较重要,这个目录主要生成的是动态库,使用了一些字段设置了一下这个库,
add_library创建接口库,然后为这个库链接一些库,再设置一下他的属性。
安装目录在默认的/usr/lib64/qt5/plugin/style里。
回到项目根目录的CMakeLists.txt,可以添加一下依赖关系了:
cmake_minimum_required(VERSION 2.8.11)
project(mystyle)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
add_definitions(-std=c++11)
find_package(Qt5Core REQUIRED)
find_package(Qt5Gui REQUIRED)
find_package(Qt5Widgets REQUIRED)
find_package(Qt5DBus REQUIRED)
set(QT_QTGUI_LIBRARY Qt5::Gui Qt5::Widgets)
set(QT_QTCORE_LIBRARY Qt5::Core)
set(QT_QTDBUS_LIBRARY Qt5::DBus)
get_target_property(REAL_QMAKE_EXECUTABLE ${Qt5Core_QMAKE_EXECUTABLE}
IMPORTED_LOCATION)
if (NOT QT_PLUGINS_DIR)
execute_process(COMMAND "${REAL_QMAKE_EXECUTABLE}" -query QT_INSTALL_PLUGINS
OUTPUT_VARIABLE QT_PLUGINS_DIR
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
endif()
add_subdirectory(demo)
add_subdirectory(style)
其中set(CMAKE_AUTOUIC ON)这一句尤为关键。新建ui类时他会包含一个ui_xxx.h头文件,这个要生成的不是自己写的,但我怎么都没有生成,就是没有开这个开关。嗨呀~
基本完成!
额其实也没搞太多哈哈哈,就是先搞好层次嘛。
look at our 层次:
.
├── CMakeLists.txt
├── CMakeLists.txt.user
├── demo
│ ├── CMakeLists.txt
│ ├── demo.cpp
│ ├── demo.h
│ ├── demo.ui
│ └── main.cpp
└── style
├── CMakeLists.txt
├── mystyle.cpp
├── mystyle.h
├── mystyle.json
├── styleplugin.cpp
└── styleplugin.h
稍微编译一下,看到构建目录的demo下有个demo程序,style目录下有个mystyle.so,就大功告成!
甚至可以运行一下那个程序:
也可以在qtcreator中项目设置里设置运行程序,点运行即可运行: