Hallo,
ich möchte 5 Bilderchen (wx.StaticBitmap) in einem frame anzeigen und habe sie zu diesem
Zweck in einen BoxSizer gesteckt. Allerdings soll das 'dynamisch' passieren können, also
nicht nur in der __init__ Methode, wie in zahlreichen Schriftstücken gezeigt.
Außer Add(...) und Clear(..) habe ich zum BoxSizer nichts gefunden, muß ich also immer erst
alles löschen und dann neu füllen?
Gruß
joh
widget im BoxSizer dynamisch anlegen
Es gibt eine Remove Methode.joh# hat geschrieben:Hallo,
ich möchte 5 Bilderchen (wx.StaticBitmap) in einem frame anzeigen und habe sie zu diesem
Zweck in einen BoxSizer gesteckt. Allerdings soll das 'dynamisch' passieren können, also
nicht nur in der __init__ Methode, wie in zahlreichen Schriftstücken gezeigt.
Außer Add(...) und Clear(..) habe ich zum BoxSizer nichts gefunden, muß ich also immer erst
alles löschen und dann neu füllen?
Gruß
joh
help(wx.BoxSizer)
...
" | Remove(*args, **kwargs)
| Remove(self, item) -> bool
|
| Removes an item from the sizer and destroys it. ...
"...
Es ist vielleicht einfacher die Bitmaps auszutauschen (`wx.StaticBitmap.SetBitmap()`) statt die Widgets aus dem Sizer zu entfernen und neue Widgets zu erstellen.
Das klingt elegant, nur wie mache ich das denn. Einfach nut SetBitmap() aufrufen führt bei mir zuBlackJack hat geschrieben:Es ist vielleicht einfacher die Bitmaps auszutauschen (`wx.StaticBitmap.SetBitmap()`) statt die Widgets aus dem Sizer zu entfernen und neue Widgets zu erstellen.
Da muß doch dann auch noch ein Neuaufbau des Bildes eingeleitet werden oder?wx._core.PyDeadObjectError: The C++ part of the BoxSizer object has been deleted, attribute access no longer allowed
Gruß
joh
@joh#: Hm ohne konkreten Quelltext kann ich dazu jetzt auch nichts sagen. Bei mir funktioniert das.
In diesem Beispiel ist es natürlich unsinnig die beiden Bilder immer wieder neu zu laden, die könnte man auch einmal in der `__init__()` laden und als `wx.StaticBitmap`\s an den Frame binden.
Code: Alles auswählen
import random
import wx
class Main(wx.Frame):
def __init__(self, parent, image_count=5):
wx.Frame.__init__(self, parent)
vsizer = wx.BoxSizer(wx.VERTICAL)
sizer = wx.BoxSizer()
bitmap = wx.BitmapFromImage(wx.Image('test0.png'))
self.bitmaps = [wx.StaticBitmap(self, wx.ID_ANY, bitmap)
for dummy in xrange(image_count)]
for bitmap in self.bitmaps:
sizer.Add(bitmap)
vsizer.Add(sizer)
button = wx.Button(self, wx.ID_ANY, '&Random change')
vsizer.Add(button, 0, wx.CENTRE)
self.Bind(wx.EVT_BUTTON, self.OnRandomChange, button)
self.SetSizer(vsizer)
self.Fit()
def OnRandomChange(self, _event):
for bitmap in self.bitmaps:
image = wx.Image('test%s.png' % random.randint(0, 1))
bitmap.SetBitmap(wx.BitmapFromImage(image))
def main():
app = wx.PySimpleApp()
frame = Main(None)
frame.Show()
app.SetTopWindow(frame)
app.MainLoop()
if __name__ == '__main__':
main()
Ich wollte die Bitmaps nicht an den Frame sondern an den sizer binden, aber das geht lt. Doku nicht.BlackJack hat geschrieben: In diesem Beispiel ist es natürlich unsinnig die beiden Bilder immer wieder neu zu laden, die könnte man auch einmal in der `__init__()` laden und als `wx.StaticBitmap`\s an den Frame binden.
Oder gibt es da einen Trick?
@joh#: Ich verstehe nicht was Du damit sagen willst. Ich meinte das es bei meinem Beispiel Unsinnig ist in der `OnRandomChange()` die beiden Bilder immer neu zu laden. Ich hätte die auch in der `__init__()` in eine Liste stecken können in `OnRandomChange()` dann aus dieser Liste auswählen können. Das kommt halt darauf an, ob es möglich ist alle möglichen Bilder vorher zu laden und ob sich das lohnt, oder ob man die erst bei Bedarf lädt. Wenn ich zum Beispiel Yatzee implementieren wollte, würde ich Bilder von den Würfelseiten einmal am Anfang alle laden.
Funktioniert mein Beispiel denn bei Dir? Wenn nicht, wo hakts? Wenn's einen Traceback gibt, dann bitte den ganzen zeigen. Das Beispiel braucht zwei Bilder mit den Namen `test0.png` und `test1.png`.
Funktioniert mein Beispiel denn bei Dir? Wenn nicht, wo hakts? Wenn's einen Traceback gibt, dann bitte den ganzen zeigen. Das Beispiel braucht zwei Bilder mit den Namen `test0.png` und `test1.png`.
Ich hatte auf einer manual Seite gelesen, daß ein bitmap keinenBlackJack hat geschrieben:@joh#: Ich verstehe nicht was Du damit sagen willst.
sizer als parent haben kann, nur z.B. ein panel, aber in Deinem Bsp.
geht das ja locker mit
Code: Alles auswählen
sizer.Add(bitmap)
Es funktioniert bestens, und ist genau das was ich gebraucht habe. Besten Dank!BlackJack hat geschrieben: Funktioniert mein Beispiel denn bei Dir?
@joh#: Die Dokumentation stimmt schon. Meine `StaticBitmaps`\s haben ja `self` als "parent" und nicht den `Sizer`. Widgets müssen andere Widgets als "parent"s haben -- oder etwas korrekter `wx.Window`\s. `Sizer` sind selbst keine Widgets sondern Hilfsobjekte, die für Containerwidgets das Layout von deren Kindern erledigen.