ASD/graphique.py
2018-01-09 17:53:28 +01:00

195 lines
6.5 KiB
Python

# coding: utf-8
import sys
import numpy as np
import math
import copy
import PySide.QtCore as qtcore
import PySide.QtGui as qtgui
import traceback
class Afficheur(qtgui.QWidget):
afficheurs = []
size = (800, 600)
coord = np.array((50, 50))
decalage = np.array((40,40))
def __init__(self, sujet, centre, ech):
super(Afficheur, self).__init__()
if(not "trace" in dir(sujet)):
raise Exception('Méthode "trace" non définie dans la classe ' + str(sujet.__class__))
app = qtgui.QApplication.instance()
if not app:
app = qtgui.QApplication(sys.argv)
desktop = app.desktop()
screen = desktop.screenGeometry(desktop.screenNumber(self))
self.rayon = 4
self.ech = ech
self.centre = np.array(centre)
self.crayon = None
self.sujet = sujet
self.setStyleSheet("background-color: white")
self.center = np.array(Afficheur.size) / 2.
self.setGeometry(Afficheur.coord[0] + screen.x(), Afficheur.coord[1] + screen.y(), Afficheur.size[0], Afficheur.size[1])
Afficheur.coord += Afficheur.decalage
self.setWindowTitle("Afficheur")
self.show()
def __pointVersPixel(self, p):
p = np.array(p)
pixel = (p - self.centre) * self.ech
pixel[1] = -pixel[1]
pixel += self.center
return qtcore.QPoint(pixel[0],pixel[1])
def __pixelVersPoint(self, pixel):
p = np.array((pixel.x(), pixel.y())) - self.center
p[1] = -p[1]
p = p / self.ech + self.centre
return p
def __pixelVersVecteur(self, pixel1, pixel2):
assert isinstance(pixel1, qtcore.QPoint)
assert isinstance(pixel2, qtcore.QPoint)
v = np.array((pixel2.x(), pixel2.y())) - np.array((pixel1.x(), pixel1.y()))
v[1] = -v[1]
v = v / self.ech
return v
def tracePoint(self, p):
assert self.crayon != None
assert isinstance(p, tuple) or isinstance(p, np.ndarray)
assert isinstance(p[0], float)
assert isinstance(p[1], float)
pixel = self.__pointVersPixel(p)
self.crayon.drawEllipse(pixel, self.rayon, self.rayon)
def traceLigne(self, p1, p2):
assert self.crayon != None
assert isinstance(p1, tuple) or isinstance(p1, np.ndarray)
assert isinstance(p1[0], float)
assert isinstance(p1[1], float)
assert isinstance(p2, tuple) or isinstance(p2, np.ndarray)
assert isinstance(p2[0], float)
assert isinstance(p2[1], float)
pixel1 = self.__pointVersPixel(p1)
pixel2 = self.__pointVersPixel(p2)
self.crayon.drawLine(pixel1, pixel2)
def changeCouleur(self, couleur):
assert self.crayon != None
assert isinstance(couleur, tuple)
assert isinstance(couleur[0], float)
assert isinstance(couleur[1], float)
assert isinstance(couleur[2], float)
c = qtgui.QColor(couleur[0]*255, couleur[1]*255, couleur[2]*255)
self.crayon.setPen(c)
self.crayon.setBrush(c)
def traceTexte(self, p, texte):
assert isinstance(p, tuple) or isinstance(p, np.ndarray)
assert isinstance(p[0], float)
assert isinstance(p[1], float)
assert isinstance(texte, str)
pixel = self.__pointVersPixel(p)
pixel += qtcore.QPoint(10,-10)
self.crayon.drawText(pixel, texte)
def renomme(self, titre):
# assert isinstance(titre, str)
# titre = unicode(titre, 'utf-8')
self.setWindowTitle(titre)
def mousePressEvent(self, QMouseEvent):
pos = QMouseEvent.pos()
self.clic = pos
pos = self.__pixelVersPoint(pos)
self.centre = self.centre
def mouseMoveEvent(self, QMouseEvent):
pos = QMouseEvent.pos()
self.centre -= self.__pixelVersVecteur(self.clic, pos)
self.clic = pos
self.update()
def mouseReleaseEvent(self, QMouseEvent):
pos = QMouseEvent.pos()
self.centre -= self.__pixelVersVecteur(self.clic, pos)
self.clic = pos
self.update()
def wheelEvent(self, event):
pos = event.pos()
C = self.__pixelVersPoint(pos)
k1 = self.ech
k2 = k1 * math.exp(0.001 * event.delta())
self.centre = (self.centre * k1 + C * (k2 -k1)) / k2
self.ech = k2
self.update()
def paintEvent(self, event):
if(self.crayon != None):
return
self.crayon = qtgui.QPainter(self)
self.trace()
self.crayon = None
def trace(self):
self.crayon.setFont(qtgui.QFont('Decorative', 10))
if(self.sujet != None):
try:
self.sujet.trace(self)
except AttributeError:
self.close()
qtgui.QApplication.quit()
raise Exception('Méthode "trace" non définie dans la classe ' + str(self.sujet.__class__))
except BaseException:
traceback.print_exc()
self.close()
qtgui.QApplication.quit()
L = 100.;
x = 20; y = 20;
self.crayon.setPen('black')
msg = '{0:.2f} km'.format(L / self.ech)
l = self.crayon.fontMetrics().boundingRect(msg).width()
self.crayon.drawText(x + (L-l)/2, y-2, msg);
self.crayon.drawLine(x, y, x + L, y);
self.crayon.drawLine(x, y - L/20, x, y + L/10);
self.crayon.drawLine(x + L, y - L/20, x + L, y + L/10);
def sauvegarde(self):
filename = qtgui.QFileDialog.getSaveFileName(self, 'Fichier PDF')
if filename:
printer = qtgui.QPrinter(qtgui.QPrinter.HighResolution)
printer.setPageSize(qtgui.QPrinter.A4)
printer.setColorMode(qtgui.QPrinter.Color)
printer.setOutputFormat(qtgui.QPrinter.PdfFormat)
printer.setOutputFileName(filename)
self.crayon = qtgui.QPainter(printer)
self.trace()
self.crayon = None
def affiche(sujet, centre, ech, blocage = True):
'''Affiche dans une fenêtre l'objet sujet qui doit avoir une méthode trace'''
assert isinstance(centre, tuple)
assert isinstance(ech, float)
sujet = copy.deepcopy(sujet)
app = qtgui.QApplication.instance()
if not app:
app = qtgui.QApplication(sys.argv)
a = Afficheur(sujet, centre, ech)
Afficheur.afficheurs.append(a)
if(blocage):
bloque()
return a
def bloque():
app = qtgui.QApplication.instance()
if not app:
app = qtgui.QApplication(sys.argv)
app.exec_()