Seite 1 von 1

Zeichenfehler beim scrollen?!

Verfasst: Mittwoch 18. Juli 2007, 16:29
von .D0T
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)

Re: Zeichenfehler beim scrollen?!

Verfasst: Mittwoch 18. Juli 2007, 18:52
von gerold
.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
:-)

Verfasst: Donnerstag 19. Juli 2007, 15:23
von .D0T
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

Verfasst: Montag 23. Juli 2007, 10:53
von .D0T
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 ;-)

Verfasst: Montag 23. Juli 2007, 12:30
von gerold
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
:-)

Verfasst: Dienstag 24. Juli 2007, 10:20
von .D0T
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^^