Zeichenfehler beim scrollen?!

Plattformunabhängige GUIs mit wxWidgets.
Antworten
.D0T
User
Beiträge: 21
Registriert: Donnerstag 17. August 2006, 17:45

Gerade erst angefangen und schon ein kleines Problem bei meinem neuen Zeitvertreibsprojekt. Ich will eine Art Raster in ein Scrolled Window zeichen und das ganze dann natürlich auch scrollen lassen. Dazu habe ich ein bufferedDC benutzt um Flackern zu vermeiden. Funktioniert an sich auch alles ganz schön aber wenn ich unter Windows (hab linux noch nicht probiert) den Scrollbalken mit der Maus bewege zeigen sich an den Rändern der Box Zeichenfehler (die Punktreihen haben nicht den richtigen abstand usw.). Lasse ich den Balken los wird neugezeichnet und alles is wies sein soll. Hoffe ihr habt da eine Lösung, generelle Tipps zum Programmierstiel nehme ich auch dankend entgegen da ich in python quasi keine Erfahrung habe!

Hier natürlich noch der code:
http://www.ubuntuusers.de/paste/12858/

Vielen Dank schonmal!
MfG
.D0T

ps: Fast hät ichs vergessen:
Python 2.5 32bit @ WindowsXp
wxPython 2.8.4.0 (msw-unicode)
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

.D0T hat geschrieben:Dazu habe ich ein bufferedDC benutzt um Flackern zu vermeiden.
Hallo .DOT!

Ich würde in deinem Fall den BufferedPaintDC einsetzen.

Beispiel: http://www.python-forum.de/post-73340.html

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
.D0T
User
Beiträge: 21
Registriert: Donnerstag 17. August 2006, 17:45

Aaah, ich glaub langsam kapier ich wo das problem liegt. Bei EVT_SCROLL und EVT_SIZE kommt auch ein EVT_PAINT...

Hät ich mir auch denken können ;-)

Danke!
MfG
.D0T
.D0T
User
Beiträge: 21
Registriert: Donnerstag 17. August 2006, 17:45

Habe jetzt mal wieder ein wenig an dem Code rumgespielt war aber nicht in der Lage das so zum funktionieren zu bringen wie es soll. Gute Beispiele sind leider auch rar und ich bin das googeln langsam Leid :-(. Aber vllt. kann mir einer auf diese Weise helfen:

Wie würdet ihr es erreichen, sauber in einem ScrolledWindow mit sehr großer VirtualSize immer den sichtbaren Teil neuzuzeichnen, sowohl bei einfachem repaint als auch bei jeder Art von Scrollen und resize?

Hier trotzdemein aktueller sample code: http://paste.pocoo.org/show/1911

ps: Natürlich will ich keinen Buffer in der Größe der VirtualSize ;-) Und das ganze möglichst schnell zu machen wäre nat. auch toll^^ Reichtum, Glück und Schönheit wären auch ein Plus :P

Danke schonmal!

@gerold:
Leider ist dein Beispiel nicht wirklich auf das anwendbar was ich vorhabe, style = wx.BUFFER_VIRTUAL_AREA würde ja die volle virtualsize puffern, oder? Habe aber trotzdem ne Frage zu deinem Beispiel:

Code: Alles auswählen

    def on_paint(self, event = None): 
        dc = wx.BufferedPaintDC(self, self.buffer_bmp, style = wx.BUFFER_VIRTUAL_AREA) 
        dc.DrawBitmap(self.buffer_bmp, 0, 0)
Wieso das dc.DrawBitmap? Ich dachte das BufferedPaintDC blittet automatisch den Buffer rüber wenn es aufhört zu existieren (am ende von on_paint), dafür ist es doch da. Kannst du mich da erleuchten? Vielen Dank für deine Antwort btw ;-)
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Hallo!
.D0T hat geschrieben:Wie würdet ihr es erreichen, sauber in einem ScrolledWindow mit sehr großer VirtualSize immer den sichtbaren Teil neuzuzeichnen, sowohl bei einfachem repaint als auch bei jeder Art von Scrollen und resize?
Genau so wie in meinem Beispiel. ;-)
Wie groß ist sehr groß? Die ganzen 32.000 * 32.000 Pixel die möglich sind? Das könnte dann wirklich groß werden. Aber eine 10 MB große Bitmap im Speicher tut mir persönlich nicht wirklich weh.
.D0T hat geschrieben:ps: Natürlich will ich keinen Buffer in der Größe der VirtualSize
Entweder so oder bei jeder kleinsten Bewegung neu zeichnen. Was ist dir lieber? Neu zeichnen würde bedeute, dass du dir die neuen Positionen der Linien errechnen musst. Das ist sicher schaffbar.
.D0T hat geschrieben:style = wx.BUFFER_VIRTUAL_AREA würde ja die volle virtualsize puffern, oder?
Nein, so wie ich das verstanden habe, zeigt dieses Flag dem BufferedPaintDC auf, dass im Bitmap der gesamte virtuelle Bereich gespeichert ist. Jetzt weiß der DC, dass er zuerst PrepareDC aufrufen muss um nur den sichtbaren Bereich aus dem Bitmap raus zu holen und neu zu zeichnen.
.D0T hat geschrieben:Ich dachte das BufferedPaintDC blittet automatisch den Buffer rüber wenn es aufhört zu existieren
Das macht es auch. Ich hatte den Code irgendwo abgeschrieben und da war ``dc.DrawBitmap`` drinnen. Das kann man in diesem Fall getrost weg lassen.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
.D0T
User
Beiträge: 21
Registriert: Donnerstag 17. August 2006, 17:45

Danke Gerold. Ich denke ich werd vorerst mal einfach den gesamten virtuellen Berreich puffern. Das könnte aber wirklich zu einem Problem mit dem Speicher werden wenns Raster mal wirklich groß wird. Nunja, aber Hauptsache er macht erstmal keine Spirenzchen mehr ;-)

EDIT: So, hab das mal probiert und es funktioniert fluffig. Eine Fräge hätte ich dann doch noch. Wie kriege ich das Fenster aus dem Hintergrund dazu sich neu zu zeichnen? Hab bis jetzt nirgends gesehen das ich EVT_PAINT selber auslösen kann und die Update Funktion zeichnet laut doku nur den invalidierten Berreich neu und da es keine InvalidateRgn Funktion gibt....nunja^^
Antworten