Last active
August 29, 2015 13:56
-
-
Save rubik/8832630 to your computer and use it in GitHub Desktop.
Homework05 - program02.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'''Questo eserczio chiede di implementare una funzione che permette di disegnare | |
su una finestra (di Qt) in modo simile a come fatto nella lezione sulla grafica | |
interattiva. Si tratta quindi di implementare una funzione paint(painter) che | |
sara' chiamata ad ogni frame per aggiornare la grafica usando l'oggetto painter | |
che ha gli stessi metodi visti nella lezione suddetta. La funzione deve disegnare | |
solamente se il mouse e' premuto (painter.info.mouse_pressed e' True) seguendo il | |
movimento del mouse. Cio' che disegna dipendera' dallo stato in cui si trova. | |
Nello stato iniziale disegna un rettangolo con contorno bianco (255,255,255), | |
interno red (255,0,0) e che ha i due spigoli opposti rispetto ad una diagonale | |
nel punto precedente del mouse (painter.info.mouse_px, painter.info.mouse_py) e | |
nel punto corrente del mouse (painter.info.mouse_x, painter.info.mouse_y). Lo | |
stato e' modificato dalla pressione di alcuni tasti: | |
'r' --> colore interno red (255,0,0). | |
'g' --> colore interno green (0,255,0). | |
'b' --> colore interno blue (0,0,255). | |
'e' --> cambia la forma disegnata da rettangolo ad ellisse e | |
viceversa (il rettangolo e' sempre lo stesso). | |
't' --> cambia la trasparenza dell'interno da opaco a trasparente e | |
viceversa. | |
'd' --> cambia il rettangolo da quello di default ad uno di dimensione doppia | |
e viceversa. Il rettangolo doppio ha larghezza e altezza doppie | |
rispetto a quelle di default e uno spigolo rimane sul punto corrente | |
del mouse. | |
Per gli esempi vedere le immagini img02_XX_check.png che mostrano i disegni | |
che devono risultare eseguendo grade02.py. | |
Eseguendo direttamente program02.py si puo' provare a disegnare a piacimento. | |
Mentre l'esecuzione di grade02.py mette alla prova l'implementazione | |
controllando che disegni in base agli eventi e rispettando le richieste. | |
AVVERTENZE: non usare caratteri non ASCII, come le lettere accentate; | |
non usare moduli che non sono nella libreria standard o non sono forniti | |
nella cartella dell'homework o non sono esplicitamente autorizzati. | |
''' | |
import itertools | |
# NON MODIFICARE I SEGUENTI IMPORT | |
from PySide.QtGui import * | |
from PySide.QtCore import * | |
from testapp import run # NON IMPORTARE NIENT'ALTRO DA testapp | |
# In queste prime righe di codice viene mantenuto lo "stato" del painter | |
## Qui ci sono le opzioni che ciclano tra due valori, e che cambiano quando viene premuto il tasto corrispondente | |
## Vedi anche http://docs.python.org/2/library/itertools.html#itertools.cycle | |
transparency = itertools.cycle((0, 255)) | |
dimensions = itertools.cycle((2, 1)) | |
shape = itertools.cycle(('drawEllipse', 'drawRect')) | |
# In questo dizionario sono salvate tutte le opzioni, con i loro valori di default | |
config = { | |
'color': (255, 0, 0), # colore del ripieno | |
'outline': (255, 255, 255), # colore del bordo | |
'method': 'drawRect', # metodo per disegnare: drawRect disegna un rettangolo, mentre drawEllipse un ellisse | |
'd': 1, # le dimensioni della figura: 1 indica dimensioni normali, 2 dimensioni doppie | |
'alpha': 255, # la componente alpha del ripieno: un valore di 0 indica un ripieno trasparente | |
} | |
key = 'r' | |
def paint(painter): | |
'''Implementare qui la funzione che aggiorna la grafica ad ogni frame''' | |
if not painter.info.mouse_pressed: | |
return | |
if painter.info.key in 'rgbetd': | |
global key | |
key = painter.info.key | |
painter.info.key = '' # resetta il tasto premuto per evitare che il painter | |
# disegni anche quando non viene premuto nessun tasto | |
# rispettivamente le coordinate del punto precedente e di quello corrente | |
px, py = painter.info.mouse_px, painter.info.mouse_py | |
x, y = painter.info.mouse_x, painter.info.mouse_y | |
# esegue le azioni in base al tasto premuto | |
if key == 'r': | |
config['color'] = (255, 0, 0) | |
if key == 'g': | |
config['color'] = (0, 255, 0) | |
if key == 'b': | |
config['color'] = (0, 0, 255) | |
if key == 'e': | |
config['method'] = next(shape) | |
if key == 't': | |
config['alpha'] = next(transparency) | |
if key == 'd': | |
config['d'] = next(dimensions) | |
dx, dy = x - px, y - py | |
d = config['d'] | |
vals = (x - d * dx, y - d * dy, d * dx, d * dy) # calcola i punti e le dimensioni della figura | |
painter.setPen(QColor(*config['outline'])) | |
painter.setBrush(QColor(*(config['color'] + (config['alpha'],)))) | |
getattr(painter, config['method'])(*vals) | |
# Crea la GUI (la finestra) e chiama la funzione paint() ad ogni frame | |
run(paint, globals()) # NON MODIFICARE |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment