1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
from GUIComponent import *
class GUISkin:
def __init__(self):
pass
def createGUIScreen(self, parent):
for (name, val) in self.items():
if isinstance(val, GUIComponent):
val.GUIcreate(parent, None)
def deleteGUIScreen(self):
for (name, val) in self.items():
if isinstance(val, GUIComponent):
val.GUIdelete()
try:
val.fix()
except:
pass
# DIESER KOMMENTAR IST NUTZLOS UND MITTLERWEILE VERALTET! (glaub ich)
# BITTE NICHT LESEN!
# note: you'll probably run into this assert. if this happens, don't panic!
# yes, it's evil. I told you that programming in python is just fun, and
# suddently, you have to care about things you don't even know.
#
# but calm down, the solution is easy, at least on paper:
#
# Each Component, which is a GUIComponent, owns references to each
# instantiated eWidget (namely in screen.data[name]["instance"], in case
# you care.)
# on deleteGUIscreen, all eWidget *must* (!) be deleted (otherwise,
# well, problems appear. I don't want to go into details too much,
# but this would be a memory leak anyway.)
# The assert beyond checks for that. It asserts that the corresponding
# eWidget is about to be removed (i.e., that the refcount becomes 0 after
# running deleteGUIscreen).
# (You might wonder why the refcount is checked for 2 and not for 1 or 0 -
# one reference is still hold by the local variable 'w', another one is
# hold be the function argument to sys.getrefcount itself. So only if it's
# 2 at this point, the object will be destroyed after leaving deleteGUIscreen.)
#
# Now, how to fix this problem? You're holding a reference somewhere. (References
# can only be hold from Python, as eWidget itself isn't related to the c++
# way of having refcounted objects. So it must be in python.)
#
# It could be possible that you're calling deleteGUIscreen trough a call of
# a PSignal. For example, you could try to call screen.doClose() in response
# to a Button::click. This will fail. (It wouldn't work anyway, as you would
# remove a dialog while running it. It never worked - enigma1 just set a
# per-mainloop variable on eWidget::close() to leave the exec()...)
# That's why Session supports delayed closes. Just call Session.close() and
# it will work.
#
# Another reason is that you just stored the data["instance"] somewhere. or
# added it into a notifier list and didn't removed it.
#
# If you can't help yourself, just ask me. I'll be glad to help you out.
# Sorry for not keeping this code foolproof. I really wanted to archive
# that, but here I failed miserably. All I could do was to add this assert.
# assert sys.getrefcount(w) == 2, "too many refs hold to " + str(w)
def close(self):
self.deleteGUIScreen()
|