Hallo an die Python Programmierer,
kennt jemand einen Weg wie man das Busy (drehendes Zahnradsymbol) per SW ein-
und ausblenden kann. Wenn ja wie?
/Willi/
Hallo an die Python Programmierer,
kennt jemand einen Weg wie man das Busy (drehendes Zahnradsymbol) per SW ein-
und ausblenden kann. Wenn ja wie?
/Willi/
ich weiss auch nicht wie aber man könnte die zugehörigen pngs löschen
die werden hintereinander geladen damit der Eindruck der Animation entsteht
/usr/share/enigma2/skin_default/spinner#dir
-rw-r--r-- 1 root root 678 Jan 23 2021 wait1.png
-rw-r--r-- 1 root root 659 Jan 23 2021 wait2.png
-rw-r--r-- 1 root root 676 Jan 23 2021 wait3.png
-rw-r--r-- 1 root root 684 Jan 23 2021 wait4.png
-rw-r--r-- 1 root root 671 Jan 23 2021 wait5.png
-rw-r--r-- 1 root root 668 Jan 23 2021 wait6.png
wenn dann keine unschöne Fehlermeldung kommt Problem gelöst, man könnte eigene pngs erstellen, z.B. nur ein weisser Pixel, es reicht dann wait1.png,
Hallo mr_viva,
vielen Dank für die Antwort,
Ich möchte den Spinner nicht generell loswerden.
Meine Frage ist eigentlich die:
Bei mir läuft ein Sortierungsprozess etwas länger. Und direkt beim Start des Sortierungsprozesses
sollen sich die Räder anfangen zu drehen. Dafür suche ich einen Start- und Stop Befehl unter Python.
Meine bisherige Erkenntnis ist allerdings die, dass der Binärteil von Enigma2 den Spinner selbst aktiviert
wenn für längerer Zeit die Prozessorlast hoch ist und deaktiviert wenn diese wieder sinkt.
Aber vielleicht hat noch jemand eine Idee wie man den Spinner manuell aktiviert.
/Willi/
Bei mir läuft ein Sortierungsprozess etwas länger. Und direkt beim Start des Sortierungsprozesses
sollen sich die Räder anfangen zu drehen
Nutzt du hierzu ein eigenes Plugin, wo du den code ändern kannst?
Wenn ja kannst du dir ja einen eigenen Spinner erstellen, so mach ich das auch, erst vor kurzen hab ich das begriffen einen weiteren Screen im Hauptscreen zu nutzen.
Bis her machte ich das noch anders.
So kannst du deinen Spinner dann im Plugin setzen:
self.spinner = self.session.instantiateDialog(MyInfoBarSpinner, zPosition=999)
Hier habe ich aber manchmal das Problem das zPosition nicht übernommen wird und der Screen dann hinterm Hauptscreen landet somit würde der nicht zu sehen sein wenn du keine Transparents nutzt.
Da gab mir Sven H einen Tip es bei self.onLayoutFinish.append() erst zu setzen.
PLEX_SPINNER_DIRECTORY = "/usr/lib/enigma2/python/Plugins/Extensions/PlexDream/images/spinner"
class MyInfoBarSpinner(Screen):
def __init__(self, session):
if DESKTOPSIZE.width() > 1920:
self.skin = """<screen backgroundColor="#70000000" flags="wfNoBorder" name="MyInfoBarSpinner" position="center,center" size="2560,1440" title="PlexDream">
<widget name="BackgroundPlexSpinner" position="0,0" size="2560,1440" gradient="#20000000,#70000000,horizontal" zPosition="98" />
<widget name="PlexSpinner" position="1233,673" size="93,93" zPosition="99" />
</screen>"""
elif DESKTOPSIZE.width() == 1920:
self.skin = """<screen backgroundColor="#70000000" flags="wfNoBorder" name="MyInfoBarSpinner" position="center,center" size="1920,1080" title="PlexDream">
<widget name="BackgroundPlexSpinner" position="0,0" size="1920,1080" gradient="#20000000,#70000000,horizontal" zPosition="98" />
<widget name="PlexSpinner" position="925,505" size="70,70" zPosition="99" />
</screen>
"""
else:
self.skin = """<screen backgroundColor="#70000000" flags="wfNoBorder" name="MyInfoBarSpinner" position="center,center" size="1280,720" title="PlexDream">
<widget name="BackgroundPlexSpinner" position="0,0" size="1280,720" gradient="#20000000,#70000000,horizontal" zPosition="98" />
<widget name="PlexSpinner" position="616,336" size="46,46" zPosition="99" />
</screen>
"""
Screen.__init__(self, session)
# Spinner Timer
self['BackgroundPlexSpinner'] = Pixmap()
self['PlexSpinner'] = Pixmap()
self['BackgroundPlexSpinner'].hide()
self['PlexSpinner'].hide()
self.PlexSpinner = eTimer()
self.PlexSpinnerStatus = False
self.PlexSpinnerTimer = 1
self.PlexSpinner_conn = self.PlexSpinner.timeout.connect(self.loadPlexSpinner)
def stopPlexSpinner(self):
self.hide()
self.PlexSpinnerStatus = False
def startPlexSpinner(self):
self.show()
self.PlexSpinnerStatus = True
self.loadPlexSpinner()
def loadPlexSpinner(self):
if self.PlexSpinnerStatus:
png = "%s/%s.png" % (PLEX_SPINNER_DIRECTORY, str(self.PlexSpinnerTimer))
self.showPlexSpinner(png)
else:
self['PlexSpinner'].hide()
self['BackgroundPlexSpinner'].hide()
def showPlexSpinner(self, png):
self['BackgroundPlexSpinner'].show()
self['PlexSpinner'].instance.setPixmapFromFile(png)
self['PlexSpinner'].show()
if self.PlexSpinnerTimer is not 8:
self.PlexSpinnerTimer += 1
else:
self.PlexSpinnerTimer = 1
self.PlexSpinner.start(400, True)
Display More
Dann kannst du den Screen im Plugin nutzen:
self.spinner.startPlexSpinner()
self.spinner.stopPlexSpinner()
if self.spinner.PlexSpinnerStatus - True oder False
Du könntest das dann so anpassen das du hier dir Originalen Spinner png's nutzt.
Vielleicht hilft dir das etwas weiter.
Hallo Murxer,
Vielen Dank für das ausführliche Beispiel:
Den Zusammenhang:
So kannst du deinen Spinner dann im Plugin setzen:
self.spinner = self.session.instantiateDialog(MyInfoBarSpinner, zPosition=999)
Hier habe ich aber manchmal das Problem das zPosition nicht übernommen wird und der Screen dann hinterm Hauptscreen landet somit würde der nicht zu sehen sein wenn du keine Transparents nutzt.
Da gab mir Sven H einen Tip es bei: self.onLayoutFinish.append() erst zu setzen.
hab ich noch nicht verstanden:
Wo finde ich: "self.onLayoutFinish.append()"
Hast Du da noch einen kurzen Beispiel Code?
/Willi/
Das setzt du in deinem Plugin code:
class DeinPlugin(Screen):
def __init__(self, session):
Screen.__init__(self, session)
# kommt dann ans ende
self.onLayoutFinish.append(self.setDialogs)
self.onLayoutFinish.append(self.createSetup)
self.onLayoutFinish.append(self.setNextArt)
def setDialogs(self):
self.spinner = self.session.instantiateDialog(MyInfoBarSpinner, zPosition=999)
Display More
self.onLayoutFinish wird dann erst ausgeführt wenn dein Plugin-Screen geladen ist.
Hoffe du kannst mir jetzt folgen
Ist jetzt klar! Probier ich aus!
Danke!
/Willi/
Nachtrag:
Das Beispiel läuft wenn man es wie folgt anpasst:
PLEX_SPINNER_DIRECTORY = "/usr/share/enigma2/skin_default/spinner"
class MyInfoBarSpinner(Screen):
def __init__(self, session):
from enigma import getDesktop
DESKTOPSIZE = getDesktop(0).size()
if DESKTOPSIZE.width() > 1920:
self.skin = """<screen backgroundColor="#70000000" flags="wfNoBorder" name="MyInfoBarSpinner" position="center,center" size="2560,1440" title="PlexDream">
<widget name="BackgroundPlexSpinner" position="0,0" size="2560,1440" gradient="#20000000,#70000000,horizontal" zPosition="98" />
<widget name="PlexSpinner" position="1233,673" size="93,93" zPosition="99" />
</screen>"""
elif DESKTOPSIZE.width() == 1920:
self.skin = """<screen backgroundColor="#70000000" flags="wfNoBorder" name="MyInfoBarSpinner" position="center,center" size="1920,1080" title="PlexDream">
<widget name="BackgroundPlexSpinner" position="0,0" size="1920,1080" gradient="#20000000,#70000000,horizontal" zPosition="98" />
<widget name="PlexSpinner" position="925,505" size="70,70" zPosition="99" />
</screen>
"""
else:
self.skin = """<screen backgroundColor="#70000000" flags="wfNoBorder" name="MyInfoBarSpinner" position="center,center" size="1280,720" title="PlexDream">
<widget name="BackgroundPlexSpinner" position="0,0" size="1280,720" gradient="#20000000,#70000000,horizontal" zPosition="10" />
<widget name="PlexSpinner" position="616,336" size="46,46" zPosition="100" />
</screen>
"""
Screen.__init__(self, session)
# Spinner Timer
self['BackgroundPlexSpinner'] = Pixmap()
self['PlexSpinner'] = Pixmap()
self['BackgroundPlexSpinner'].hide()
self['PlexSpinner'].hide()
self.PlexSpinner = eTimer()
self.PlexSpinnerStatus = False
self.PlexSpinnerTimer = 1
self.PlexSpinner_conn = self.PlexSpinner.timeout.connect(self.loadPlexSpinner)
def stopPlexSpinner(self):
self.hide()
self.PlexSpinnerStatus = False
def startPlexSpinner(self):
self.show()
self.PlexSpinnerStatus = True
self.loadPlexSpinner()
def loadPlexSpinner(self):
if self.PlexSpinnerStatus:
png = "%s/wait%s.png" % (PLEX_SPINNER_DIRECTORY, str(self.PlexSpinnerTimer))
self.showPlexSpinner(png)
else:
self['PlexSpinner'].hide()
self['BackgroundPlexSpinner'].hide()
def showPlexSpinner(self, png):
self['BackgroundPlexSpinner'].show()
self['PlexSpinner'].instance.setPixmapFromFile(png)
self['PlexSpinner'].show()
if self.PlexSpinnerTimer is not 9:
self.PlexSpinnerTimer += 1
else:
self.PlexSpinnerTimer = 1
self.PlexSpinner.start(50, True)
Display More
Allerdings zusammen mit der Aufgabenstellung nicht. Denn was ich nicht erwartet habe ist:
Führt man eine Callback Routine aus (z.B. per FB Kommando) die länger läuft, dann werden alle
weiteren Events geblockt. Dazu gehören Screenupdates, FB und Timer Events. Dies solange,
bis der länger laufende Programmteil beendet ist. Nach 4 Sekunden gibt Enigma2 im log aus:
main thread is non-idle! display spinner!
Heißt: Baut man den Aktivierungscode für den Spinner im Start der länger laufenden Sortierroutine
ein, so wird der Spinner erst angezeigt nachdem die Sortierroutine beendet ist. Dann wird er allerdings
nicht mehr benötigt.
Startet man den Spinner bereits vorher, stoppt die Drehung, solange die Sortieroutine läuft.
Leider ein unerwünschtes Ergebnis.
Hat jemand noch einen Tipp?
/Willi/
nach deiner ergebnisbeschreibung liegt das problem darin, dass deine sortierroutine nicht unterbrechbar ist.
das kann man prinzipiell auf zwei arten loesen:
1. sortierroutine in kleine stuecke zerteilen, die z.b. durch einen timer aufgerufen werden. in der zwischenzeit kann dann der spinner weiterlaufen.
2. sortierroutine in einem eigenen thread laufen lassen, dann sorgt das linux dafuer, dass sortieren und spinner quasi parallel laufen.
etwas einfacher ist die 2. methode. ich kann dazu spaeter noch ein kleines beispiel posten.
Hierzu musst du deine Abfrage oder was auch immer in den Backgrund verschieben so das Enigma nicht geblockt wird.
from twisted.internet import reactor, threads, ssl, defer
def gotPlaybackInfo(self, Id, callback):
self.error = False
media = self.account.getPlaybackInfo(Id)
if media.get("error"):
error = "[EmbyDream]: gotPlaybackInfo error: %s " % str(media.get("message", ""))
errorLog(error)
self.error = True
reactor.callFromThread(callback, media)
def getPlaybackInfo(self, Id, callback):
threads.deferToThread(self.gotPlaybackInfo, Id, callback)
Display More
Oder so:
from threading import Thread
thread = Thread(target=self.emby.getUpdateTimeline, args=(self.item, self.seekTranscoding, None, True, 0))
thread.start()
Somit sollte der ich sag mal Default Spinner nicht mehr kommen.
So mach ich das, vielleicht gibt es auch noch bessere Vorschläge.
LG
Der "Oder so" Vorschlag gefällt mir schon sehr gut. Allerdings scheint man bei
Funktionsaufrufen die direkt das Enigma2 betreffen vorsichtig sein zu müssen.
Aber damit sollte ich es hinbekommen!
Nochmals Danke!
/Willi/
Display MoreDer "Oder so" Vorschlag gefällt mir schon sehr gut. Allerdings scheint man bei
Funktionsaufrufen die direkt das Enigma2 betreffen vorsichtig sein zu müssen.
Aber damit sollte ich es hinbekommen!
Nochmals Danke!
/Willi/
Du darfst nur keine GUI Updates aus einem anderen Thread aufrufen, sonst crashed der Core.