Python exemplarisch
deutsch     english

MAUSEVENTS



 

Callbacks registrieren

   

Die Mausklicks bzw. Mausbewegungen werden vom System erfasst und führen zum Aufruf von Callbackfunktionen. Die Callbackfunktionen werden mit benannten Parametern beim Erzeugen des Grafikfensters mit makeGPanel() registriert. Folgende Callbacks können registriert werden:

  • mousePressed : reagiert auf das Drücken der Maustaste
  • mouseReleased : reagiert auf das Loslassen der Maustaste
  • mouseMoved: reagiert auf die Mausbewegungen
  • mouseDragged: reagiert auf die Mausbewegung mit gedrückten Maustaste
 

Die Callbackfunktionen liefern die Koordinaten des Mausklicks bzw. die aktuellen Koordinaten des Mauszeigers.

Im Beispiel setzt die Callbackfunktion onMousePressed()den Grafikcursor auf die Koordinaten des Mausklicks und zeichnet einen kleinen grünen Kreis.

Die Callbackfunktion onMouseDragged() folgt dem Mauszeiger und zeichnet an jeder neuen Position einen roten Kreis mit einem schwarzen Rand.

 

 

Programm: [►]

# MouseeventEx1.py

from gpanel import *

def onMousePressed(x, y):
    setColor("green")
    pos(x, y) 
    fillCircle(0.02) 

def onMouseDragged(x, y):
    setColor("red") 
    pos(x, y)
    setColor("red")
    fillCircle(.04) 
    setColor("black")
    circle(.04)  

makeGPanel(mousePressed = onMousePressed, mouseDragged = onMouseDragged)

keep()
Progammcode markieren (Ctrl+C kopieren, Ctrl+V einfügen)

  Erklärungen zum Programmcode
 

Es können mehrere Callbackfunktionen gleichzeitig registriert werden. Die Namen der Callbackfunktion sind frei wählbar, die Parameternamen bei der Registrierung sind aber festgelegt.

 

 

Dynamische Punktlisten

 

In diesem Beispiel werden die Punkte mit einem Mausklick erzeugt und zu der Liste graph, die zu Beginn leer ist, hinzugefügt.

Mit jedem neuen Punkt werden die Verbindungslinien zu den bereits vorhandenen Knotenpunkten gezeichnet.

 

 

Programm: [►]

# MouseeventEx2.py

from gpanel import *

def drawLines(p):
    for q in graph[:-1]:
        line(p, q)

def addNode(x, y):
    p = [x, y]    
    pos(p) 
    fillCircle(1)
    graph.append(p)    
    drawLines(p)

makeGPanel(0, 100, 0, 100, mousePressed = addNode)
graph = []
keep()
Progammcode markieren (Ctrl+C kopieren, Ctrl+V einfügen)

  Erklärungen zum Programmcode
 

Mit jedem Mausklick wird die Callbackfunktion addNote() aufgerufen, die einen kleinen Kreis an der Position des Mausklicks zeichne und den Punkt mit den aktuellen Koordinaten zu der Liste graph hinzufügt. In drawLines() wird die Liste ohne das letzte Element durchlaufen und es werden die Verbindungslinien gezeichnet.

 

 

Ausschnitt einer Grafik vergrössern (Zoom)

 

Die Grafik stellt die Funktion y = a · e-5x · cos(2 π ·f·x) dar (gedämpfte Schwingung).  .

Die ursprüngliche Darstellung zeigt Artefakte, die auf Rundungsfehler zurückzuführen sind. Um die Funktion genauer zu untersuchen, wird mit der gedrückten Maustaste Ausschnitt ausgewählt. Dabei entsteht ein "Gummiband-Rechteck". Beim Loslassen der Maustaste wird dieser Ausschnitt vergrössert dargestellt.

 

Programm: [►]

# MouseeventsEx3.py

from gpanel import *
from math import cos, exp, pi
import thread

def f(x):
    y = a * exp(-5 *x) * cos(2 * pi * f1 * x)
    return y
   
def drawGraph(xmin, xmax, ymin, ymax):
    clear()
    setColor("black")
    lineWidth(1)
    xspan = xmax - xmin
    yspan = ymax - ymin
    dx = xspan / 1000.0
    window(xmin - 0.1 * xspan, xmax + 0.1 * xspan, 
           ymin - 0.1 * yspan, ymax + 0.1 * yspan)
    drawGrid(1.0 * xmin, xmax, 1.0 * ymin, ymax, "gray")
    x = xmin
    while x <= xmax:
        y = f(x)
        pos(x, y) if x == xmin else draw(x, y)
        x += dx

def onMousePressed(x, y):
    global x1, y1, x2, y2
    setColor("white")
    lineWidth(2)
    setXORMode("blue") # set XOR paint mode
    x1 = x2 = x
    y1 = y2 = y

def onMouseDragged(x, y):
    global x2, y2
    rectangle(x1, y1, x2, y2) # erase old
    x2 = x
    y2 = y
    rectangle(x1, y1, x2, y2) # draw new
    repaint()

def onMouseReleased(x, y):
    rectangle(x1, y1, x2, y2) # erase old
    setPaintMode() # establish normal paint mode
    repaint()
    xmin = min(x1, x2)
    xmax = max(x1, x2)
    ymin = min(y1, y2)
    ymax = max(y1, y2)
    thread.start_new_thread(drawGraph, (xmin, xmax, ymin, ymax))

a = 1
f1 = 100
makeGPanel(mousePressed = onMousePressed,
    mouseDragged = onMouseDragged,
    mouseReleased = onMouseReleased)
drawGraph(0, 1, -2, 2)
keep() 
Progammcode markieren (Ctrl+C kopieren, Ctrl+V einfügen)

  Erklärungen zum Programmcode
 

Die Erzeugung von Gummiband-Linien ist typisch: Im Callback onMousePressed() merkt man sich den Anfangspunkt (x1, y1) und stellt auf den XOR-Modus um. In diesem Zeichenmodus kann man einen über ein Hintergrundpixel  gezeichneten Punkt wieder entfernen, indem man ihn ein zweites Mal zeichnet. Dabei erscheint wieder das Hintergrundpixel. Im Callback onMouseDragged()zeichnet man fortlaufend das Auswahlrechteck. In onMouseRelease() erhält man den ausgewählten zweiten Eckpunkt (x2  y2) des Rechtecks. Man stellt wieder auf den normalen Zeichnungsmodus um und führt die Zoomoperation aus.

Da in Maus-Callbacks die Grafik nicht gerendert wird (auch wenn man repaint() aufruft), erfolgt das Zeichnen in einem eigenen Thread.