Sketch window: Dragging ist nach dem Zoomen langsam

Plattformunabhängige GUIs mit wxWidgets.
Benutzeravatar
ennemoser
User
Beiträge: 7
Registriert: Freitag 31. August 2007, 18:48
Wohnort: Graz

Sketch window: Dragging ist nach dem Zoomen langsam

Beitragvon ennemoser » Montag 1. Oktober 2007, 21:19

Servus,

ich habe von wxPython in Action das Sketch Beispiel übernommen und abgewandelt. Ich habe "dragging"(linke Maustaste) und "zoom"(Mausrad) implementiert. Außerdem verwende ich GraphicsContext, da ich Antialiasing und später Transparenz verwenden möchte.
Wenn ich nun zoome (größer), lässt sich das ganze kaum mehr "draggen". Wenn ich das Ganze wieder verkleinere, dann habe ich full speed.

Was mache ich falsch? Hängt das mit dem event.Skip() zusammen? :?

Python: 2.4, Enthought edition
wxPython Version: wx-2.8-msw-ansi

Andi

[code=]#!c:/python24/python

import wx

class Canvas(wx.Window):
def __init__(self, parent, ID):
wx.Window.__init__(self, parent, ID)
self.SetBackgroundColour("White")
self.color = "Black"
self.thickness = 2
self.pen = wx.Pen(self.color, self.thickness, wx.SOLID)
self.brush = wx.Brush(wx.Colour( 80, 80, 255, 255))
self.lines = [(-20,-20), (20,-20), (20,20), (-20,20), (-20,-20)]
self.zoom = 1.0

self.Bind(wx.EVT_MOTION, self.OnMotion)
self.Bind(wx.EVT_MOUSEWHEEL, self.OnMotion)
self.Bind(wx.EVT_SIZE, self.OnSize)
self.Bind(wx.EVT_IDLE, self.OnIdle)
self.Bind(wx.EVT_PAINT, self.OnPaint)

self.SetSizeandOrigin()
self.InitBuffer()

def InitBuffer(self):

self.buffer = wx.EmptyBitmap(self.width, self.height)
dc = wx.BufferedDC(None, self.buffer)
dc.SetMapMode(wx.MM_METRIC)

# Drawing upside down (i.e. natural orientation)
dc.SetAxisOrientation(True, True)

# Original position is top left of window
dc.SetDeviceOrigin(self.origin[0], self.origin[1])

dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
dc.Clear()

gc = wx.GraphicsContext.Create(dc)

if self.lines:
self.DrawLines(gc)

# Prevent redraw in OnIdle
self.reInitBuffer = False

def OnPaint(self, event):
# For double buffered drawing; content of self.buffer is blit here to the DC
dc = wx.BufferedPaintDC(self, self.buffer)

def DrawLines(self, gc):
path = gc.CreatePath()
path.MoveToPoint(self.lines[0]) # Move to start point of airfoil
for index, coord in enumerate(self.lines):
#if index == 0: pass
path.AddLineToPoint(coord)
gc.SetPen(self.pen)
gc.SetBrush(self.brush)
gc.Scale(self.zoom, self.zoom)
gc.DrawPath(path)

def OnMotion(self, event):
# Drag
if event.Dragging() and event.LeftIsDown() and not event.m_controlDown:
actPos = event.GetPositionTuple()
xact = actPos[0]
yact = actPos[1]
xold = self.pos[0]
yold = self.pos[1]
vx = xact - xold
vy = yact - yold
self.origin = (self.origin[0] + vx, self.origin[1] + vy)
self.pos = actPos
self.InitBuffer()
self.Refresh(False)
# Zoom
elif event.GetWheelRotation():
self.zoom = self.zoom - event.GetWheelRotation()/float(self.height) # Change zoom factor
self.InitBuffer()
self.Refresh(False)
else:
self.pos = event.GetPositionTuple() # Initialize for dragging

event.Skip() # ???

def OnSize(self, event):
self.width, self.height = self.GetClientSize()
self.SetSizeandOrigin(0)
self.reInitBuffer = True # Redraw is automatically performed in OnIdle

def OnIdle(self, event):
if self.reInitBuffer:
self.InitBuffer()
self.Refresh(False) # generates EVT_PAINT; False means background not erased

def SetSizeandOrigin(self, fit=0):
self.width, self.height = self.GetClientSize()
if fit == 0:
or_x = 0.5*self.width # to be changed for all
or_y = 0.5*self.height # to be changed for all
self.zoom = 1.0

self.origin = (or_x, or_y)

class SketchFrame(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent, -1, "Test",
size=(800,600))
self.sketch = Canvas(self, -1)

if __name__ == '__main__':
app = wx.App(redirect=False)
frame = SketchFrame(None)
frame.Show(True)
app.MainLoop()

[/code]
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Re: Sketch window: Dragging ist nach dem Zoomen langsam

Beitragvon gerold » Dienstag 2. Oktober 2007, 09:03

ennemoser hat geschrieben:Wenn ich nun zoome (größer), lässt sich das ganze kaum mehr "draggen". Wenn ich das Ganze wieder verkleinere, dann habe ich full speed.

Hallo ennemoser!

Du zeichnest dein Objekt immer wieder neu. Ich habe im Code mal mitzählen lassen, wie oft das Bild neu gezeichnet wird, wenn ich das Objekt von links oben nach rechts unten bewege. Im Schnitt 50 mal.

Bei einem kleinen Bild ist das nicht so schlimm. Das sind insgesamt wenige Pixel die gezeichnet werden müssen. Aber je größer das Bild wird, desto mehr Pixel müssen neu gezeichnet werden. Und das bis zu xxx mal pro Sekunde.

Ich glaube, dass du einen Geschwindigkeitsvorteil heraus holen kannst, wenn du nach dem Zoomen das gezeichnete Bild in ein Bitmap (buffer) speicherst und das Bild beim Bewegen nicht ständig neu zeichnen lässt.

Es sollte genügen, wenn du das gepufferte Bitmap mit Blit() in den Hauptbuffer überträgst. Hinter Blit() steckt nicht so viel Computerarbeit als hinter den Zeichenbefehlen. Blit() überträgt einfach nur den angegebenen Speicherbereich. Ich gehe davon aus, dass damit dein Programm viel schneller wird.

Probier es mal aus. Vielleicht hilft es.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.

Wer ist online?

Mitglieder in diesem Forum: Google [Bot]