組合使用QT的資源管理高階功能簡化開發過程
#include "AppHelper.h"
// http://qt-project.org/doc/qt-5/qdir.html#setSearchPaths
// http://qt-project.org/doc/qt-5/resources.html
struct QSettingGroup
{
QSettingGroup( QSettings & config , const QString & group ) : settings( config )
{
settings.beginGroup( group );
}
template< typename T > T Value( const QString & Key , const QVariant & Def = QVariant( ) )
{
return settings.value( Key , Def ).value< T >( );
}
~QSettingGroup( ) { settings.endGroup( ); }
QSettings & settings;
};
struct QSplashArgs
{
explicit QSplashArgs( ) : splashScreen( NULL ){ }
QSplashScreen * splashScreen ;
QString splashImageFile ;
};
static QSplashArgs & splashArgs( )
{
static QSplashArgs splashArgs;
return splashArgs ;
}
QString & dirExpand( QString & path )
{
static QString appDir , binary , config ;
if( appDir.isEmpty( ) || appDir.isNull( ) )
{
binary = QCoreApplication::applicationDirPath( );
appDir = QDir( binary + "/.." ).canonicalPath( );
config = appDir + "/etc" ;
}
path.replace( "$(AppDir)" , appDir );
path.replace( "$(Binary)" , binary );
path.replace( "$(Config)" , config );
return path;
}
QString dirExpand( const char * path ){ return dirExpand( QString( path ) ); }
QStringList & dirExpand( QStringList & pathList )
{
QStringList::iterator itr = pathList.begin( );
for( ; itr != pathList.end( ) ; itr ++ )
{
dirExpand( * itr );
}
return pathList ;
}
static void initResourceSearch( QSettings & settings )
{
QSettingGroup config( settings , "Search" );
QStringList resDirs = settings.childKeys( );
foreach( const QString & resDir , resDirs )
{
QStringList resPaths = config.Value< QStringList >( resDir );
QDir::setSearchPaths( resDir , dirExpand( resPaths ) );
}
}
static void initResourceFiles( QSettings & settings )
{
QSettingGroup config( settings , "Resource" );
QStringList resPaths = settings.childKeys( );
foreach( const QString & resRoot , resPaths )
{
QString resFile = config.Value< QString >( resRoot );
regResource( resFile , resRoot );
}
}
static void initPluginsPaths( QSettings & settings )
{
QSettingGroup config( settings , "Plugins" );
QStringList dirLibraries = config.Value< QStringList >( "Path" );
qApp->setLibraryPaths( dirExpand( dirLibraries ) + qApp->libraryPaths( ) );
}
static void initAppSettings( QSettings & settings )
{
QSettingGroup config( settings , "Application" );
// initialize resource file
QString resFile = QCoreApplication::applicationFilePath( );
resFile.replace( ".exe" , ".rcc" , Qt::CaseInsensitive );
QResource::registerResource( resFile );
// initialize Locale Codec
QByteArray codec = config.Value< QByteArray >( "LocaleCodec" , "GB18030" );
QTextCodec::setCodecForLocale( QTextCodec::codecForName( codec ) );
// install language translator
addTranslator( config.Value< QString >( "Language" , "zh_CN" ) );
// initialize skin styles
setSkinStyles( config.Value< QString >( "Theme" , "Default" ) );
}
static QString getString( QStringList & list , int index , const QString & def = QString( ) )
{
return list.size( ) > index ? list[ index ] : def ;
}
static void initSplashArgs( QSettings & settings )
{
QSettingGroup config( settings , "Splash" );
QSplashArgs & Args = splashArgs( );
Args.splashImageFile = config.Value< QString >( "Image" , "Splash.png" );
}
void initializeApplication( void )
{
QString appFile = QCoreApplication::applicationFilePath( );
appFile.replace( ".exe" , ".ini" , Qt::CaseInsensitive );
QDir::setCurrent( dirExpand( QString( "$(AppDir)" ) ) );
QSettings config( appFile , QSettings::IniFormat );
QDir::setCurrent( dirExpand( "$(AppDir)" ) );
initResourceSearch( config );
initResourceFiles( config );
initPluginsPaths( config );
initAppSettings( config );
initSplashArgs( config );
}
void addTranslator( const QString & Name )
{
QTranslator * translator = new QTranslator( 0 );
translator->load( QString( "lang:" ) + Name + ".lang" );
qApp->installTranslator( translator );
}
void setSkinStyles( const QString & Name )
{
QFile skinFile( QString( "skin:" ) + Name + ".skin" );
skinFile.open( QFile::ReadOnly | QFile::Unbuffered );
qApp->setStyleSheet( skinFile.readAll( ) );
skinFile.close( );
}
void regResource( const QString & Name , const QString & Root )
{
QString name( Name ), root( Root );
if( root[ 0 ] == ':' ){ root[ 0 ] = '/' ; }
if( root[ 0 ] == '$' ){ root[ 0 ] = '/' ; }
if( root[ 0 ] == '@' ){ root[ 0 ] = '/' ; }
if( root[ 0 ] != '/' ){ root.insert( 0 , '/' ); }
QResource::registerResource( dirExpand( name ) , root );
}
struct QSplash : public QSplashScreen
{
void closeEvent( QCloseEvent * event );
explicit QSplash( );
};
void QSplash::closeEvent( QCloseEvent * event )
{
QSplashScreen::closeEvent( event );
splashArgs( ).splashScreen = NULL;
}
QSplash::QSplash( ) : QSplashScreen( QPixmap( splashArgs( ).splashImageFile ) )
{
}
void splashInit( void )
{
if( splashArgs( ).splashScreen != NULL ) return;
if( QSplashScreen * splash = new QSplash( ) )
{
splashArgs( ).splashScreen = splash;
splash->show( );
}
}
void splashShow( const QString & text , const QColor & color )
{
if( QSplashScreen * splash = splashArgs( ).splashScreen )
{
splash->showMessage( text , Qt::AlignCenter , color );
qApp->processEvents( );
}
}
void splashFini( QWidget & mainWidget )
{
if( QSplashScreen * splash = splashArgs( ).splashScreen )
{
splash->finish( & mainWidget );
}
}
void splashHide( void )
{
if( QSplashScreen * splash = splashArgs( ).splashScreen )
{
splashArgs( ).splashScreen = NULL ;
splash->deleteLater( );
splash->close( );
}
}