Animierter Splashscreen hängt während laden

Plattformunabhängige GUIs mit wxWidgets.
Antworten
Hand
User
Beiträge: 65
Registriert: Sonntag 28. Januar 2007, 14:28

Hallo, ich schon wieder... :wink:

Ich möchte meiner Applikation gerne einen animierten Splashscreen hinzufügen das insbesondere das wx.HtmlWindow auf älteren Rechner ziemlich lang zu laden braucht...

Klar geht es mit wx.SplashScreen, aber damit können leider keine Animationen dargestellt werden.

Mein Ansatz:

Ich habe einen Dialog erstellt von dem aus der Hauptframe nach einer Sekunde geladen wird (zum testen). Nach dieser Sekunde stockt die Animation jedoch.

Code: Alles auswählen

#------------------------------------------------------------------------------
# class mySplash
#------------------------------------------------------------------------------
class mySplash(wx.Dialog):
    def __init__(self):
        screen = wx.GetDisplaySize()
        wx.Dialog.__init__(self, None, wx.ID_ANY, '', wx.DefaultPosition,
                           (210,150), wx.STAY_ON_TOP | wx.FRAME_NO_TASKBAR |
                           wx.RAISED_BORDER)

        self.SetBackgroundColour(wx.WHITE)
        image = wx.Bitmap('../img/splash.jpg', wx.BITMAP_TYPE_JPEG)
        wx.StaticBitmap(self, -1, image, (1,0))
        gif = wx.animate.Animation('tiptip.gif')
        wx.animate.AnimationCtrl(self, -1, gif, (10,45)).Play()
        wx.StaticText(self, -1, 'Data Connector', (105,70))
        wx.StaticText(self, -1, 'build " + sVersion', (105,85))
        wx.StaticText(self, -1, '(c)2007', (105,105))
        wx.StaticText(self, -1, 'Loading...', (105,125))
        self.CentreOnScreen()
        thread.start_new_thread(self.test,())
        self.Show()

    def test(self):
        time.sleep(1)
        wx.CallAfter(self.OK)

    def OK(self):
        self.frame = myMainFrame.myFrame(self)
        self.frame.Show()

#------------------------------------------------------------------------------
# class myApp
#------------------------------------------------------------------------------
class myApp(wx.App):
    def OnInit(self):
        self.splash = mySplash()
        return True

    def test2(self, evt):
        self.frame = myMainFrame.myFrame(self)
        self.frame.Show()
        self.SetTopWindow(self.frame)

Ich befürchte es geht nur mit einem zweitem Python programm oder?

Programm Splash.py -> startet Main.py
Main.py -> killt nach Start Splash.py

Eigentlich bräuchte man sowas wie eine zweite Mainloop die den Splash unabhängig aktualisiert.

Vielleicht hat noch jemand eine tolle Idee? :roll:
Hand
User
Beiträge: 65
Registriert: Sonntag 28. Januar 2007, 14:28

Hat denn keiner ne Idee?

ich werds dann mal mit 2 Programmen angehen

1. Programm zeigt Splash, sobald Lockfile vorhanden ist Programmende


2. Programm startet und erstellt Lockfile, löscht dieses bei Programmende wieder
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Hoi "Hand",
Hand hat geschrieben:Hat denn keiner ne Idee?
Scheinbar nicht: Versuche es doch mal auf der wxPython-Mailingliste. Hier gibt es zwar oft großartige Hilfe, aber manchmal eben weiß hier niemand weiter.

Dennoch eine allgemeine Idee hierzu:
Hand hat geschrieben: 1. Programm zeigt Splash, sobald Lockfile vorhanden ist Programmende
2. Programm startet und erstellt Lockfile, löscht dieses bei Programmende wieder
Das hatten wir hier im Forum schon in ähnlichen Threads besprochen. Die Gefahr ist, daß Dein Programm abstürzt und das Lockfile nicht entfernt wird. Worauf es ein Nutzer in diesen Fällen per Hand löschen muß.
Außerdem hast Du dann keinen Splashscreen mehr, sondern eben zwei Programme, die hintereinander laufen: Das macht Dir beim Testen Deines Programmes und Deinen Nutzern beim Gebrauch sicher keinen Spaß (denn es dauert irgendwann einfach zu lange).
Aber das ist nur eine Meinung, um Hilfe vielleicht wirklich am besten bei der Mailingliste bitten.

Gruß,
Christian
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Hand hat geschrieben:Hat denn keiner ne Idee?
Hi Hand!

Es gibt für mich kaum etwas unwichtigeres als ein Splashscreen, deshalb verschwende ich auch keine Zeit darin, mich in dieses Thema einzudenken.

Vielleicht kannst du damit etwas anfangen:
http://xoomer.alice.it/infinity77/eng/A ... plash.html

mfg
Gerold
:-)
Zuletzt geändert von gerold am Montag 5. März 2007, 19:11, insgesamt 1-mal geändert.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Jadawin
User
Beiträge: 12
Registriert: Samstag 17. Februar 2007, 18:34

CM hat geschrieben: Das hatten wir hier im Forum schon in ähnlichen Threads besprochen. Die Gefahr ist, daß Dein Programm abstürzt und das Lockfile nicht entfernt wird. Worauf es ein Nutzer in diesen Fällen per Hand löschen muß.
Na das lässt sich aber ganz billig lösen, indem das Splashscreenprogramm bei seinem Start das Lockfile auf jeden Fall schonmal weglöscht. So kann das Lockfile, auf das das Programm später testet, ja nur vom gerade gestarteten Hauptprogramm kommen.


Aber mal zum Thema:
Ich bin selbst noch Python-Anfänger und habe mich noch nicht zu Threads vorgearbeitet, aber:
Ich glaube, Du musst gleich zu Beginn des Hauptprogramms einen Thread starten, der den Splashscreen anzeigt und animiert und dann aber mit dem laden des Hauptprogramms weiter machen. Wenn das Hauptprogramm bereit ist, "sagst" Du dem Thread, er soll sich beenden.
So, wie Dein Code aussieht, machst Du es im Moment genau andersherum. Der Splashscreen startet einen Thread, der das Hauptprogramm lädt. Ich weiss nicht, ob es da nicht irgendwelche Abhängigkeiten zwischen dem Thread und seinem Erzeuger-Thread gibt.
Coding rule 1: A Computer will only do what you told him to do, not what you want him to do.
Therefore: Very often the problem sits right in front of the keyboard.
Hand
User
Beiträge: 65
Registriert: Sonntag 28. Januar 2007, 14:28

Das Problem ist dass wxPython nur einen eigenen Thread zulässt, also eine mainloop()

In andere threads können zwar Programmfunktionen ausgeführt werden aber alles was wxPython Grafikausgaben betrifft muss in der mainloop passieren.
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Hand hat geschrieben:Das Problem ist dass wxPython nur einen eigenen Thread zulässt, also eine mainloop()

In andere threads können zwar Programmfunktionen ausgeführt werden aber alles was wxPython Grafikausgaben betrifft muss in der mainloop passieren.
Ah ich glaube ich weiß was du willst. Es geht glaube ich darum das du gerne mehrere Farames (Fenster) in einer Applikation haben möchtest?

Falls ich richtig liege, dann lese dir folgenden Thread durch. Dort hat mir damals Gerold bei dem Problem geholfen :)

http://www.python-forum.de/topic-8558.html?highlight=
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Zur Lockfile Diskussion: Hier ein Modul mit den man sowas realisiert: http://www.python-forum.de/topic-8282.h ... t=lockfile
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Hand hat geschrieben:[...]
Vielleicht hat noch jemand eine tolle Idee? :roll:
Leider nicht. In der Main.py von der wxsPython Demo, ist zu sehen wie das dort realisiert wird, aber ohne animiertes Splashscreen. Da ich mich mit dem Thema auch noch nicht beschäftigt habe (da es mich einfach auch nicht interessiert, da ich Splashscreens zu den unwichtigsten Dingen zähle), weiß ich nicht ob sich das Problem wirklich mit 2 Verschiedenen Apps löse lässt, wie du es jetzt versuchen willst, oder ob man das auch anders lösen kann.

Aber mal eine (Scherz-)Frage: Du nimmst ein Anim-Gif oder? Duration ist auf endless oder? *g* ^^
Hand
User
Beiträge: 65
Registriert: Sonntag 28. Januar 2007, 14:28

ich will doch nur el barto beim laden haben :lol:

Bild
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Weiß nicht, Hand, ob Du der Threadstarter auf der wxPythonmailingliste bist (der Fragesteller, klingt so deutsch ;-), aber da gibt es gerade eine interessante diesbezügliche Diskussion mit einem Post von Robin Dunn. Tenor: GIFAnimationCtrl braucht Timer, die wiederrum den Mailloop voraussetzen, während der Splashscreen welcher üblicherweise angezeigt wird, bevor der Mainloop beginnt.
M.a.W.: Animated GIFs im Splashscreen sind wohl keine sooo gute Idee.

Gruß,
Christian
oliver1974
User
Beiträge: 97
Registriert: Donnerstag 26. Oktober 2006, 15:01

Hmm, also ein SplashScreen kann imho durchaus sinnvoll sein... wenn die Anwendung wirklich so lange zum Initialisieren braucht (und es sich partout nicht vermeiden lässt), bin ich auch immer froh über einen SplashScreen der mir wenigstens sagt, dass die Anwendung noch "lebt" (also Infos über wechselnde Meldungen und/oder ProgressBar).

Wenn dazu noch ein bißchen EyeCandy drauf kommt und es damit gut aussieht.. warum nicht?

Der Link von Gerold ist tatsächlich richtig interessant.. sieht ganz gut aus, müsste noch mal testen, ob das Ding aber wirklich auch auf Linux-Kisten und dergleichen läuft, ich glaube der Autor war sich da selber nicht so ganz sicher.

Eventuell könnte man über die Schiene auch noch selbst eine Animation reinarbeiten.... Dazu müsste man das GIF zwar zerlegen und sich selbst einen Player bauen, der die einzelnen Frames anzeigt, aber das ist wohl im Bereich des machbaren... Wenn sich da nicht was mit SplashScreen bzw. dem Neuzeichnen desselben beisst, sollte das wohl gehen.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Also, vorweg: Ein SplashScreen ist in meinen Augen eine tolle Sache - setze ich selber auch ein.

Die Diskussion, die ich verlinkt habe, geht noch weiter: Andrea hat einen interessanten Gedanken geäußert. Sein Advanced Splash Screen benutzt ebenfalls Timer. Er meint, wenn nun die GIFAnimationCtrl nicht zu verwenden ist, dann könnte man - timergesteuert - einfach Bilder nacheinander anzeigen.

Ganz ehrlich: Ich habe z. Zt. keinen Nerv das zu basteln, weil zu viele andere Dinge um die Ohren. Aber wenn sich daran jemand austoben möchte, fände ich es sehr interessant den Code zu sehen - ob nun hier oder auf der Mailingliste oder sonstwo. ;-)

Gruß,
Christian
hmueller
User
Beiträge: 39
Registriert: Montag 27. November 2006, 16:07
Wohnort: Linz, Oberösterreich

CM hat geschrieben:Weiß nicht, Hand, ob Du der Threadstarter auf der wxPythonmailingliste bist (der Fragesteller, klingt so deutsch ;-)
nö, das war ich :)
I must not fear. Fear is the mind-killer. Fear is the little death that brings total obliteration.
I will face my fear. I will permit it to pass over me and through me. And when it has gone past I will turn the inner eye to see its path.
Antworten