/QtDynamicThemer

Dynamic CSS Themes for Qt

Primary LanguageC++

QtDynamicThemer - Dynamic CSS Themes for Qt

QtDynamicThemer is a library set that provides the ablity to run-time load CSS "themes" for Qt applications. This allows designers to rapidly test and change CSS for applications without re-compiling or modifying any code, and allows users to create their own themes for an applicatrion to suit their needs.

Requirements

Qt >= 4.8

Usage

You will need to include the source files in your project, follow normal procedure for doing so.

Theme Creation

To create a theme, you will first need to create a directory to store your themes in, by default, this directory is named themes and is found in the application path. You may, however, specify another path (using an absolute path name) via the themePath() method.

Within this directory, create one sub-directory for each theme you wish to support and place the CSS files for each theme in the themes directory, e.g.:

themes/
|
\----- Theme1/
|	|
|	\----- main.css
|	\----- foo.css
\----- Theme2/
	|
	\----- main.css
	\----- foo.css

Naming Theme

By default, the name used for each theme (when calling themes()) is the same as the directory name. However, if you want to use short directory names, and meaningful strings to name the themes, create a file in each directory named theme.ini. Within this ini file, you can specify a display name for the theme, for example: name=My Nice Theme Name

When loading themes from code, you will always use the display name when calling theme(), but that's not a problem because you're going to give the user a nice dialog and let them select from the list dynamically generated by calling themes(), right?

themes/
|
\----- Theme1/
|	|
|	\----- main.css
|	\----- foo.css
|	\----- theme.ini
\----- Theme2/
	|
	\----- main.css
	\----- foo.css
	\----- theme.ini

Disk-Based Resource Files

When including disk-based resource files through the url() directive in your CSS files, such as for images, use only the relative path name starting at the theme directory. The themer will automatically convert these paths to absolute paths as needed. Do NOT use absolute paths in your CSS files.

For example, given the following structure:

themes/
|
\----- Theme1/
	|
	\----- main.css
	\----- foo.css
	\----- theme.ini
	\----- img/
		|
		\----- button.png

We would use the following directive:

border-image: url(themes/Theme1/img/button.png);

OS-Specific Theme Files

QtDynamicThemer supports OS-specific theme files that are loaded in addition to the requested file. To create an OS-specific CSS file, add a suffix to the name of the file, before '.css', for example:

themes/
|
\----- Theme1/
	|
	\----- main.css
	\----- main_win.css
	\----- foo.css
	\----- theme.ini
	\----- img/
		|
		\----- button.png

The following extensions are supported:

  • Windows
    • _win
  • OSX
    • _osx
  • Linux
    • _linux
  • Embedded Linux (Qt 4.x only)
    • _elinux

Coding with QtDynamicThemer

Using Themes in Short-Lived Widgets

For short-lived widgets, such as dialogs, we'll only set the theme at widget construction time, and won't need to do anything special outside of that. To do this, simply call the SingleThemer::getStyleSheet() method with the name of the theme CSS file you want to load:

ErrorDialog::ErrorDialog(QWidget *parent) : QDialog(parent), ui(new Ui::ErrorDialog) {
	ui->setupUi(this);
	setStyleSheet(SingleThemer::getStyleSheet("error"));
}

Using Themes in Long-Lived Widgets

For long-lived widgets, such as your main window, or widgets drawn in your main window, a signal is provided to inform your widget of when the theme changes, and a static re-polish method is provided:

LongLivedWidget(QWidget *parent) : QWidget(parent), ui(new Ui::LongLivedWidget) {
	ui->setupUi(this);
	
		// theming
	Themer* theme = &Singleton::Instance();
	
		// watch for changes to the current theme
	connect(theme, SIGNAL(themeChanged()), this, SLOT(_themeChanged()));
	
		// set style sheet
	setStyleSheet(theme->getThemeCSS("longwidget"));
}

	// our slot that gets called when the theme changes

void LongLivedWidget::_themeChanged() {
    setStyleSheet(SingleThemer::getStyleSheet("longwidget"));
    Themer::rePolish(this);
}

Refresh Theme List

To refresh the theme list, simply call themePath(QString) with the theme path again to refresh the list of themes.

Author, Copyright and License

QtDynamicThemer was developed by C. A. Church as part of the Graffik application and is Copyright © 2011-2013 Dynamic Perception, llc.

This code is shared under the GPL v3 license.

QtDynamicThemer is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

QtDynamicThemer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with QtDynamicThemer. If not, see http://www.gnu.org/licenses/.