Code erst ausführen, wenn Screen bereits sichtbar ist

  • Hallo


    Gibt es eine Möglichkeit, einen bestimmten Code erst auszuführen, wenn der Screen bereits vollständig geladen und bereits zu sehen ist?


    Wenn ich jetzt einen etwas zeitintensiveren Code direkt im Screen.__init__ ausführe, dauert es eben etwas länger, bis der Screen angezeigt wird.
    Ich würde aber gern erst den Screen anzeigen wollen und dann den bestimmten zeitintensiveren Code ausführen.
    Das Warten ist etwas angenehmer, wenn der Screen schon da ist :winking_face:


    Mit onLayoutFinish und onShown klappt das auch nicht, da gibt es von der Dauer bis zur Anzeige des Screens beim Start keinen Unterschied im Vergleich zur Variante direkt im Screen.__init__.
    Gibt es für onLayoutFinish eine andere Funktion, die erst nach dem Anzeigen des Screens eintritt?


    Hab es jetzt erst mal über einen gesonderten Tastendruck realisiert, aber es wäre schöner, wenn das direkt nach der Anzeige des Screens von allein ausgeführt wird.


    Danke schon mal

    Gruß Sven (aka Dreamy)


    DM920 mit unstable OE2.5 DP
    One mit unstable OE2.6 DP

  • ich mach sowas dann in eine Refresh Layout routine und einen Timer der sie Regelmässig ausführt, so kann man den Screen auch kontinuierlich updaten wenn sich was ändert.


    Also ins init:


    self.onLayoutFinish.append(self.refreshLayout)



    self.LayoutRefreshTimer.start(500, True)


    def refreshLayout(self,first=False):
    ...
    if first:
    self.LayoutRefreshTimer = eTimer()
    self.LayoutRefreshTimer_conn = self.LayoutRefreshTimer.timeout.connect(self.refreshLayout)
    .....


    self.LayoutRefreshTimer.start(200, True)


    Dann kannst du mit first steuern was beim ersten mal und bei refresh ausgeführt wird.


    KEINE schöne Lösung, aber funktioniert ... z.B. im AutoPin Plugin ... um im Skin dynamisch zu zeigen wenn ein Modul gestartet oder gestopp oder reingesteckt wird, etc.

  • Ok, Danke.
    An eine Timer-Variante dachte ich auch schon.
    Hatte aber gehofft, dass es da evtl. ein vorhandenes Event gibt :winking_face:


    Dann hab ich da ne weitere Frage:


    Wenn ich zwischen den Zeilen des zeitintensiveren Codes mit setText mehrere Statusausgaben an ein Label im Screen schicke, wird der geänderte Text im Screen nicht aktualisiert.
    Erst wenn der Code durch ist, wird der zuletzt mit setText gesetzte Inhalt angezeigt.


    In VB gab es dafür immer DoEvents, was muss ich denn hier machen, damit der mit setText gesetzte Text sofort im Screen aktualisiert wird?

    Gruß Sven (aka Dreamy)


    DM920 mit unstable OE2.5 DP
    One mit unstable OE2.6 DP

  • schau dir mal die skin.py an da findest du die ganzen Aktionen die du auf Skin elemente machen kannst setText und nachher evt gleich ein show sollten eigentlich für einen Refresh ausreichen.


    Aber du musst dir klar sein das dies nicht komplett asynchron gehandhabt wird, schon damit die engine die das dann in den Frame buffer pinseln muss nicht durcheinander kommen kann. Besser wäre dann für jede Änderung einen Event zu feuern (oder eben einen eigenen Timer) dann kann jeder Event auch einen eigenen skin event auslösen.


    Aber höre besser nicht auf mich, ich bin ein besch* Programmierer weil ich sobald es (irgendwie) geht einfach aufhöre darüber nachzudenken wie es richtig ginge :kissing_face:


    Das hat zwar den Vorteil das ich dadurch viele Sachen als erster gemacht habe, aber sowas hinterlässt dann verbrannte Erde weil es dann keiner mehr angreifen will da es "ja eh schon geht" und dann Dinge ewig an dir hängen bleiben :smiling_face_with_horns:

    Einmal editiert, zuletzt von Lost in Translation ()

  • Verdammt, beim Lesen deines Tipps bezüglich .show() nach .setText() hatte ich große Hoffnung.


    Aber irgendwie scheint der weitere Code (urllib2.urlopen) die Screen-Aktualisierung zu blockieren.
    Der Screen wird erst am Code-Ende von selbst refreshed.


    Danke dir trotzdem :winking_face:

    Gruß Sven (aka Dreamy)


    DM920 mit unstable OE2.5 DP
    One mit unstable OE2.6 DP

  • Nochnmals das show/hide sagt der engine nur was zu tun ist, nicht das es sofort passieren muss.


    Und manche libs sind sowieso ein Graus, du solltest also das holen der Daten vom web in einer eigene routine machen oder wenigstens auf das wtisted web umsteigen das hat ein besseres Thread handling.


    In der Data load routine machst du dann die daten auf self.xxxx variablen damit du sie in der ganzen Class benutzen kannst.


    Womit du dann die jeweils aktuellen werte in einer eigenen Screen update routine anzeigst.


    Sonst wird das immer holprig bleiben, egal was du machst.


    Ich stehe ja auch darauf alles sequentiell in einer routine zu machen (Spaghetti is my code) und zu hoffen das es irgendwie geht, aber das hat eben gerade bei webrequests rasch seine Grenzen.

  • Warum verwendest du urllib? Nimm twisted. Dann ist alles schön asynchron. onShown gäbe es auch noch. Also nebst onLayoutFinish

    Gruss
    Dre


    Boxen (im Einsatz): DM920, DM900, DMOne
    Developer Project Merlin - we are OpenSource

  • Ehrlich gesagt war ich froh, dass ich eine Lösung mit urllib2 gefunden habe. twisted muss ich mir erstmal anschauen :winking_face:


    Die einzelnen urlopen habe ich mit threading in einzelne threads gepackt, so dass sie offensichtlich parallel laufen, da deutlich schneller als normal nacheinander.
    Nur eben die Aktualisierung der Label-Texte funktioniert nicht zwischen den Thread.start()


    onShown hatte ich wie gesagt auch schon probiert.
    Da habe ich jedoch zu onLayoutFinnish zeitlich keinen Unterschied festgestellt. Braucht dann genauso lange bis der Screen zu sehen ist.


    Wegen der Aktualisierung der Label-Texte hatte ich gehofft, es gibt sowas wie screen.refresh(), was die Aktualisierung sofort anschiebt.


    So wichtig ist das aber auch nicht. Halt nur eine kosmetische Sache.

    Gruß Sven (aka Dreamy)


    DM920 mit unstable OE2.5 DP
    One mit unstable OE2.6 DP

  • Bei twisted machst du einfach ein addCallback rein. Diese Funktion wird dann immer aufgerufen, wenn der Call fertig ist. In dieser Funktion kannst du dann den Text mittels setText updaten.

    Gruss
    Dre


    Boxen (im Einsatz): DM920, DM900, DMOne
    Developer Project Merlin - we are OpenSource

  • Im opendreambox repo auf github kannst du z.B. beim weatherplugin Beispiele in MSNWeather.py finden. Einfach mal nach getPage suchen.

    Gruss
    Dre


    Boxen (im Einsatz): DM920, DM900, DMOne
    Developer Project Merlin - we are OpenSource

  • Grundsätzlich klappt das mit twisted jetzt schon super. :thumbs_up:
    Die Rückmeldungen an den Screen werden sofort ausgeführt.
    Man sieht auch, dass einige Rückmeldungen vom getpage eher kommen, obwohl sie später gestartet wurden.
    Ist also alles in Echtzeit :winking_face:


    Ein Problem hab ich nur noch und verzweifele gerade. :nauseated_face:


    Der Rückgabewert der Internetseite wird mit print super ausgegeben.
    Wenn ich dann aber wie bei urlopen versuche den Inhalt zeilenweise auszulesen, scheint in jeder Zeile nur 1 Zeichen zu sein.
    Wie bekomme ich aus dem Rückgabewert wieder einen normalen Text zum Durchsuchen?


    meine bisherige Suche hat so funktioniert:


    for line in contents:
    if search_strings in line:
    ...

    Gruß Sven (aka Dreamy)


    DM920 mit unstable OE2.5 DP
    One mit unstable OE2.6 DP

  • Super, Danke :thumbs_up:


    Geht ja wirklich viel einfacher.
    Wollte nur irgendwie am alten Code festhalten und dachte, man kann den Rückgabewert umwandeln :winking_face:

    Gruß Sven (aka Dreamy)


    DM920 mit unstable OE2.5 DP
    One mit unstable OE2.6 DP

  • klappt leider nicht, hab es extra nochmal probiert, obwohl es ja jetzt mit .find funktioniert.


    mit:
    for line in range(len(contents)):
    print line


    werden nur Zahlen ausgegeben, die sich immer um 2 erhöhen (geht bis 986).
    Aber eigentlich egal, es funktioniert ja jetzt mit .find.


    Um nochmal auf die Eingangsfrage einzugehen, es funktioniert jetzt auch mit der Code-Ausführung bei onLayoutFinnish oder onShonw. :smiling_face:
    Es lag tatsächlich am urlopen(), wodurch auch die Screenanzeige beim Start des Plugins blockiert wurde.


    Hier übrigens mal ein Screenshot vom Ergebnis des Ganzen :smiling_face:
    Ist ein Plugin, welches mir das Updaten der Plugins mit den Versionen im Github vereinfacht.
    So sehe ich auf einen Blick, ob es bereits neuere Versionen gibt und brauche keinen PC zum updaten.


    Vielen Dank nochmal an alle Hilfeleistenden :thumbs_up:

  • @dhwz


    Und warum nicht? Wo meinst du, sollte es klemmen?


    Das Plugin macht eigentlich nichts anderes als die händische Variante.
    (Zip vom git laden, Inhalt von scr auf die Box kopieren, fertig)


    So (also händisch) habe ich ja auch die jetzige EMC-Version auf die Box bekommen.

    Gruß Sven (aka Dreamy)


    DM920 mit unstable OE2.5 DP
    One mit unstable OE2.6 DP

  • Daran dass ich die Versionsnummer nur alle zeitlang (weil es sonst keiner tut) mal aktualisiere und es danach trotzdem relevante Änderungen gibt.
    Also anhand der Versionsnummer kannst du beim EMC leider nicht wirklich feststellen ob deine lokale Version aktuell ist.