verwenden von global um eine variable Funktionsübergreifend zu Ändern

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
sveni_lee
User
Beiträge: 92
Registriert: Montag 14. März 2016, 09:50

Ich möchte gern eine globale Variable inner einer Funktion auf globaler Ebene ändern...

zum start des Programms ist die Variable wie folgt definiert:

Code: Alles auswählen

import urllib
import urllib2
import os
import re
import sys
import xbmc
import xbmcgui
import xbmcaddon
import xbmcplugin
import time
import datetime
import json
import sqlite3
from datetime import timedelta
import _strptime
from xml.dom import minidom
from resources.lib.serienplaner import WLScraper

Kategorie = ''
innerhalb einer Funktion soll die Variable dann global geändert werden..

Code: Alles auswählen

elif methode=='show_select_dialog':
    writeLog('Methode: show select dialog', level=xbmc.LOGDEBUG)
    dialog = xbmcgui.Dialog()
    cats = [__LS__(30120), __LS__(30121), __LS__(30122), __LS__(30123), __LS__(30116)]
    ret = dialog.select(__LS__(30011), cats)

    if ret == 6:
        refreshWidget()
    elif 0 <= ret <= 5:
        writeLog('%s selected' % (cats[ret]), level=xbmc.LOGDEBUG)

        global Kategorie
        Kategorie = (cats[ret])        
        refreshWidget()
        WINDOW.setProperty('SerienPlaner.Countdown', unicode(time.time()))

    else:
        pass
in der Funktion refreshWidget ist die Kategorie auch noch geändert, das zeigt mir das log

Code: Alles auswählen

13:29:48 T:6656 DEBUG: [plugin.program.serienplaner 0.0.1]: Methode from external script: show_select_dialog
13:29:48 T:6656 DEBUG: [plugin.program.serienplaner 0.0.1]: Detailurl from external script:
13:29:48 T:6656 DEBUG: [plugin.program.serienplaner 0.0.1]: pvrid from external script:
13:29:48 T:6656 DEBUG: [plugin.program.serienplaner 0.0.1]: Methode: show select dialog
13:29:53 T:6656 DEBUG: [plugin.program.serienplaner 0.0.1]: Klassiker selected
13:29:53 T:6656 DEBUG: [plugin.program.serienplaner 0.0.1]: refresh Widget Kategorie: Klassiker
wird dann aber von außen die selbe Funktion noch einmal aufgerufen ist die Variable wieder zurück auf den ursprung

Code: Alles auswählen

13:29:55 T:7784 DEBUG: [plugin.program.serienplaner 0.0.1]: Methode from external script: get_item_serienplaner
13:29:55 T:7784 DEBUG: [plugin.program.serienplaner 0.0.1]: Detailurl from external script: None
13:29:55 T:7784 DEBUG: [plugin.program.serienplaner 0.0.1]: pvrid from external script: None
13:29:55 T:7784 DEBUG: [plugin.program.serienplaner 0.0.1]: refresh Widget Kategorie:
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@sveni_lee: Du solltest _strptime nicht verwenden, des Unterstrichs wegen, und Du willst nicht minidom verwenden, der schrecklichen API wegen. Und Du solltest keine globalen Variablen verwenden. Und was meinst Du mit "von außen nochmal aufgerufen"? Würdest Du keine globalen Variablen benutzen, wüßtest Du wann welche Variable welchen Wert bekommt. Ist vielleicht cats[ret] leer?
sveni_lee
User
Beiträge: 92
Registriert: Montag 14. März 2016, 09:50

das ganze hat folgernden Hintergrund:

refreshWidget wird all 5 min selbständig aufgerufen. Damit ändert sich dann auch der Wert von listitems, da dieser
ja aus dem SELECT der SQLite-db resultiert...

aus KODI heraus werden die ListItem wie folgt aufgerufen

Code: Alles auswählen

<content>plugin://plugin.program.serienplaner/?methode=get_item_serienplaner&reload=$INFO[Window(Home).Property(SerienPlaner.Countdown)]</content>
damit sich dieser content auch ändert, muß sich der Pfad dahin ändern... weil nur dan KODI den Inhalt aktalisiert...
Darum auch das ``$INFO[Window(Home).Property(SerienPlaner.Countdown)]`` dieses Item ist eine ``time.time()`` der jedesmal neugesetzt wird wenn ein ``refreshWidget`` aufgerufen wird...
Dieser Teil funktioniert schon ohne Probleme!

Zusätzlich solle es select_dialog geben. Dieser soll dann nur die in diesem Dialog gewählte Kategorie anzeigen. der select_Dialog wird wie folgt aufgerufen.

Code: Alles auswählen

RunScript(plugin.program.serienplaner,"?methode=show_select_dialog")
dort wird das ``cats[ret]`` definiert... und danach dann ``refreshWidget(cats[ret])`` aufgerufen.
UND da kommt dann das Problem:

es wird dann wirder ``listitems`` neu geschrieben und auch nur für die Kategorie cats[ret] aber damit diese auch wieder
angezeigt werden bzw. in Kodi aktualisiert werden ein erneuter

Code: Alles auswählen

<content>plugin://plugin.program.serienplaner/?methode=get_item_serienplaner&reload=$INFO[Window(Home).Property(SerienPlaner.Countdown)]</content>
und damit werden die "richtigen" listitems wieder überschrieben.

darum dachte ich an eine globale variable die in der methode=='show_select_dialog': geändert wird

Code: Alles auswählen

elif methode=='show_select_dialog':
    writeLog('Methode: show select dialog', level=xbmc.LOGDEBUG)
    dialog = xbmcgui.Dialog()
    cats = [__LS__(30120), __LS__(30121), __LS__(30122), __LS__(30123), __LS__(30116)]
    ret = dialog.select(__LS__(30011), cats)

    if ret == 6:
        refreshWidget()
    elif 0 <= ret <= 5:
        writeLog('%s selected' % (cats[ret]), level=xbmc.LOGDEBUG)

        global Kategorie
        Kategorie = (cats[ret])        
        refreshWidget()
        WINDOW.setProperty('SerienPlaner.Countdown', unicode(time.time()))


countdown muß ich neu setzen damit die Aktualisierung in KODI erfolgt. dabei wird dann aber auch ``refreshWidget`` erneut aufgerufen aber die globale Variable ist dann nicht mehr cats[ret]...

Ich hoffe das war jetzt verständlicher...
sveni_lee
User
Beiträge: 92
Registriert: Montag 14. März 2016, 09:50

okay, ich habe für mein empfinden eine elegantere Lösung gefunden.

Ich lasse jetzt eine Property mit der Kategorie setzen

Code: Alles auswählen

elif methode=='show_select_dialog':
    writeLog('Methode: show select dialog', level=xbmc.LOGDEBUG)
    dialog = xbmcgui.Dialog()
    cats = [__LS__(30120), __LS__(30121), __LS__(30122), __LS__(30123), __LS__(30116)]
    ret = dialog.select(__LS__(30011), cats)

    if ret == 6:
        refreshWidget()
    elif 0 <= ret <= 5:
        writeLog('%s selected' % (cats[ret]), level=xbmc.LOGDEBUG)

        WINDOW.setProperty('Kategorie', unicode(cats[ret]))        
        refreshWidget()
        WINDOW.setProperty('SerienPlaner.Countdown', unicode(time.time()))
for der Datenbankabfrage hole ich mir dann das Property mit ``getProperty`` zurück:

Code: Alles auswählen

def refreshWidget(offset=0):

    Kategorie = WINDOW.getProperty('Kategorie')

    writeLog('refreshWidget Kategorie:  %s' % (Kategorie), level=xbmc.LOGDEBUG)
    listitems = []

    conn = sqlite3.connect(SerienPlaner)
    cur = conn.cursor()
    query = """SELECT %s
           FROM TVShowData
           WHERE julianday(_Starttime) + (_RunningTime / 24.0 / 60.0) > julianday('now', 'localtime')
           %s
           ORDER BY _Starttime
           LIMIT %s"""

    filter = ""
    parameters = []

    if not Kategorie or Kategorie == __LS__(30116):
        filter += ""
        parameters += ()
    else:
        filter += " AND WatchType = ?"
        parameters += (Kategorie,)
    if __series_in_db__:
        filter += " AND Serie_in_DB = ?"
        parameters += (True,)
    if __firstaired__:
        filter += " AND neueEpisode LIKE ?"
        parameters += ('%'+'NEU'+'%',)

    query = query % (','.join(properties), filter, __maxHLCat__)
    cur.execute(query, parameters)
    try:
        for idx, data in enumerate(cur, offset):
            for field, item in zip(properties, data):     
            
                WINDOW.setProperty('SerienPlaner.%d.%s' % (idx, field), item)
                
            listitems.append(dict(zip(properties, data)))    

        return listitems
    finally:
    
        cur.execute("""DELETE FROM TVShowData WHERE julianday(_Starttime) + (_RunningTime / 24.0 / 60.0) < julianday('now', 'localtime')""")
        conn.commit()
        conn.close()
läuft bisher ohne Probleme...
Antworten