Splash Screen

Moderator: Rathinagiri

Post Reply
User avatar
pctoledo
Posts: 123
Joined: Wed Aug 25, 2010 10:45 am
Location: Araçatuba - SP - Brazil
Contact:

Splash Screen

Post by pctoledo »

Shown splash screen during application startup:

File: globshared.prg

Code: Select all

   CLASS VAR s_cImgSplash              INIT  NIL      SHARED
   CLASS VAR s_nCounterSplash          INIT  0        SHARED
File: hmgapp.prg

Code: Select all

   METHOD SplashScreen                 SETGET

Code: Select all

METHOD SplashScreen( cImg, nCounter ) CLASS HMGAPP

   IF PCOUNT() == 0
      RETURN ::s_cImgSplash
   ELSEIF ::s_lQtStarted == .F. .AND. File( cImg ) 
      ::s_cImgSplash := cImg
      IF hb_IsNumeric( nCounter )
         ::s_nCounterSplash := nCounter
      ELSE
         ::s_nCounterSplash := 5
      ENDIF
   ENDIF

RETURN Self

Code: Select all

METHOD Reset() CLASS HMGAPP

   ::s_oQtApp           := NIL
   ::s_oQtRes           := NIL
   ::s_aResources       := {}
   ::s_cStyle           := NIL
   ::s_oDefaultParent   := NIL
   ::s_nObjectCounter   := 0
   ::s_oMainWindow      := NIL
   ::s_lGridCellFlag    := .F.
   ::s_oMainMenu        := NIL
   ::s_oParentWindow    := NIL
   ::s_cNewPopUpMenuName:= NIL
   ::s_cNewMenuItemName := NIL

   ::s_nCountry         := NIL
   ::s_oCurWindow       := NIL
   ::s_nLanguage        := NIL
   ::s_bOnShutDown      := NIL
   ::s_bOnStartUp       := NIL
   ::s_cPlugInDir       := NIL
   ::s_oQtLocale        := NIL
   ::s_lQtStarted       := .F.
   ::s_oTopParent       := NIL
   ::s_cImgSplash       := NIL
   ::s_nCounterSplash   := 0

RETURN Self

Code: Select all

METHOD Start() CLASS HMGAPP

   LOCAL cPath, cFile, cExt, nX, cResFileName, oImg, oSplash, nSec

   // check if it's already started
   IF ::s_lQtStarted == .T.
      RETURN Self
   ENDIF

   // split program name for two reason
   // 1. to have the current path
   // 2. to have the program name and register default resource with program name
   hb_fNameSplit( hb_ProgName(), @cPath, @cFile, @cExt )

   ::s_lQtStarted := .T.
   ::s_oQtApp     := QApplication()
   ::s_oQtRes     := QResource()

   // Show Splash Screen
   IF VALTYPE( ::s_cImgSplash ) == "C"
      oImg   := QPixmap():new()
      oImg:Load( ::s_cImgSplash )
      oSplash := QSplashScreen():new()
      oSplash:setPixmap( oImg )
      oSplash:Show()
      nSec := seconds()
      DO WHILE .t.
         IF seconds() > nSec + ::s_nCounterSplash
            EXIT
         ENDIF
      ENDDO
   ENDIF

   // localization
   IF VALTYPE( ::s_nLanguage ) == "U"
      ::s_oQtLocale     := QLocale()
      ::s_oQtLocale:setDefault( QLocale() )
   ELSEIF VALTYPE( ::s_nLanguage ) == "N"
      IF VALTYPE( ::s_nCountry ) == "U" ; ::s_nCountry := 0 ; ENDIF     // 0 is like QLocale_AnyCountry
      ::s_oQtLocale     := QLocale( ::s_nLanguage, ::s_nCountry )
      ::s_oQtLocale:setDefault( QLocale( ::s_nLanguage, ::s_nCountry ) )
   ENDIF

   // if ::s_cPlugInDir not evaluated create a default <exePath\Qt\plugins>. If qt.conf exists take that
   IF VALTYPE( ::s_cPlugInDir ) == "U"
      ::s_cPlugInDir := cPath + "Qt" + hb_ps() + "plugins"
   ENDIF
   ::s_oQtApp:addLibraryPath( ::s_cPlugInDir )

   ::s_oDefaultParent   := Self
   ::s_oTopParent       := Self
   ::oQtObject          := ::s_oQtApp:DeskTop()

   // by default register resource file with the same name of program (see harbour)
   Self:RegisterResource( cFile )
   FOR nX := 1 TO LEN( ::s_aResources )
      cResFileName := ::s_aResources[nX]
      IF TYPE( cResFileName ) == "UI"  // to find if exist this function
         ::s_oQtRes:registerResource_1( &cResFileName )
      ENDIF
   NEXT nX

   // Set Widget Style
   IF VALTYPE( ::s_cStyle ) == "C"
      ::s_oQtApp:SetStyle( ::s_cStyle )
   ENDIF

   //    check OnStartUp
   IF hb_IsBlock( ::s_bOnStartUp ) == .T.
      EVAL( ::s_bOnStartUp )
   ENDIF

   // Close Splash Screen
   IF VALTYPE( ::s_cImgSplash ) == "C"
      oSplash:Close()
   ENDIF

RETURN Self
Samples use:

Code: Select all

Function Main

   LOCAL oWindow

   HbQt_ErrorSys()

   HMGAPP():SplashScreen( "hmgsplash.png", 5 )

   WITH OBJECT oWindow := Window():New()
      :Row    := 0
      :Col    := 0
      :Width  := 518
      :Height := 400
      :Title  := 'Splash Screen'
      :Type   := WND_MAIN
      :OnInit := { || oWindow:Center() }

   END WITH

   oWindow:Activate()

   RETURN NIL
Attachments
splash.zip
File demo
(18.63 KiB) Downloaded 195 times
Regards/Saludos,

Toledo

Clipper On Line
mrduck
Posts: 497
Joined: Fri Sep 10, 2010 5:22 pm

Re: Splash Screen

Post by mrduck »

Hi,
thank you for this code.

I'd propose some changes.

1) first open the resource, since I may want to store the splash image in the resource file

2) move the loop down

Code: Select all

      oSplash:Show()
      nSec := seconds()
      DO WHILE .t.
         IF seconds() > nSec + ::s_nCounterSplash
            EXIT
         ENDIF
      ENDDO
With this code you are waiting for the timeout to expire, with a loop that does nothing...

Keep the nSec line where is it now and move the loop after the

Code: Select all

IF hb_IsBlock( ::s_bOnStartUp ) == .T.
      EVAL( ::s_bOnStartUp )
   ENDIF
In this way the splash screen is shown on screen but the program continues to startup....

3) do while .t.
I think that the use of this do while loop is not good in a multitasking environment. Can you please check if there is something similar to inkey(0.2) so that cpu is freed ? Also a timer can be put in use...

4) always on top
from docs:
The splash screen appears in the center of the screen. It may be useful to add the Qt::WindowStaysOnTopHint to the splash widget's window flags if you want to keep it above all the other windows on the desktop.
User avatar
pctoledo
Posts: 123
Joined: Wed Aug 25, 2010 10:45 am
Location: Araçatuba - SP - Brazil
Contact:

Re: Splash Screen

Post by pctoledo »

Hi mrduck, I made some changes:

Code: Select all

METHOD Start() CLASS HMGAPP

   LOCAL cPath, cFile, cExt, nX, cResFileName, oImg, oSplash, nSec

   // check if it's already started
   IF ::s_lQtStarted == .T.
      RETURN Self
   ENDIF

   // split program name for two reason
   // 1. to have the current path
   // 2. to have the program name and register default resource with program name
   hb_fNameSplit( hb_ProgName(), @cPath, @cFile, @cExt )

   ::s_lQtStarted := .T.
   ::s_oQtApp     := QApplication()
   ::s_oQtRes     := QResource()

   // Show Splash Screen
   IF VALTYPE( ::s_cImgSplash ) == "C"
      oImg   := QPixmap():new()
      oImg:Load( ::s_cImgSplash )
      oSplash := QSplashScreen():new()
      oSplash:setPixmap( oImg )
      oSplash:Show()
      nSec := seconds() + ::s_nCounterSplash
   ENDIF

   // localization
   IF VALTYPE( ::s_nLanguage ) == "U"
      ::s_oQtLocale     := QLocale()
      ::s_oQtLocale:setDefault( QLocale() )
   ELSEIF VALTYPE( ::s_nLanguage ) == "N"
      IF VALTYPE( ::s_nCountry ) == "U" ; ::s_nCountry := 0 ; ENDIF     // 0 is like QLocale_AnyCountry
      ::s_oQtLocale     := QLocale( ::s_nLanguage, ::s_nCountry )
      ::s_oQtLocale:setDefault( QLocale( ::s_nLanguage, ::s_nCountry ) )
   ENDIF

   // if ::s_cPlugInDir not evaluated create a default <exePath\Qt\plugins>. If qt.conf exists take that
   IF VALTYPE( ::s_cPlugInDir ) == "U"
      ::s_cPlugInDir := cPath + "Qt" + hb_ps() + "plugins"
   ENDIF
   ::s_oQtApp:addLibraryPath( ::s_cPlugInDir )

   ::s_oDefaultParent   := Self
   ::s_oTopParent       := Self
   ::oQtObject          := ::s_oQtApp:DeskTop()

   // by default register resource file with the same name of program (see harbour)
   Self:RegisterResource( cFile )
   FOR nX := 1 TO LEN( ::s_aResources )
      cResFileName := ::s_aResources[nX]
      IF TYPE( cResFileName ) == "UI"  // to find if exist this function
         ::s_oQtRes:registerResource_1( &cResFileName )
      ENDIF
   NEXT nX

   // Set Widget Style
   IF VALTYPE( ::s_cStyle ) == "C"
      ::s_oQtApp:SetStyle( ::s_cStyle )
   ENDIF

   //    check OnStartUp
   IF hb_IsBlock( ::s_bOnStartUp ) == .T.
      EVAL( ::s_bOnStartUp )
   ENDIF

   // Close Splash Screen
   IF VALTYPE( ::s_cImgSplash ) == "C"
      IF seconds() < nSec
        SecondsSleep(nSec-seconds())
      ENDIF
      oSplash:Close()
   ENDIF

RETURN Self
I decreases the value of ::s_nCounterSplash

Code: Select all

METHOD SplashScreen( cImg, nCounter ) CLASS HMGAPP

   IF PCOUNT() == 0
      RETURN ::s_cImgSplash
   ELSEIF ::s_lQtStarted == .F. .AND. File( cImg ) 
      ::s_cImgSplash := cImg
      IF hb_IsNumeric( nCounter )
         ::s_nCounterSplash := nCounter
      ELSE
         ::s_nCounterSplash := 2
      ENDIF
   ENDIF

RETURN Self
mrduck wrote:1) first open the resource, since I may want to store the splash image in the resource file
Sorry, I do not know how to use image the resource file in the function QPixmap().
Regards/Saludos,

Toledo

Clipper On Line
Post Reply