1 # -*- coding: utf-8 -*- |
|
2 import numpy |
|
3 import pylab |
|
4 import math |
|
5 import new # monkey patching... |
|
6 |
|
7 from PyQt4 import QtGui, QtCore |
|
8 from PyQt4.QtCore import Qt, SIGNAL |
|
9 |
|
10 from hpgl_parser import HPGLParser |
|
11 |
|
12 class QHPGLPlotterWidget(HPGLParser, QtGui.QWidget): |
|
13 pen_styles = {2: [0.4, 0.6], |
|
14 3: [0.6, 0.4], |
|
15 4: [0.7, 0.1, 0.1, 0.1], |
|
16 5: [0.6, 0.1, 0.2, 0.1], |
|
17 6: [0.45, 0.1, 0.1, 0.2, 0.1, 0.05], |
|
18 } |
|
19 pen_colors = ["black", "green", "red", "blue", "yellow", "cyan", "magenta", |
|
20 "darkred", "darkblue"] |
|
21 |
|
22 def __init__(self, parent=None): |
|
23 QtGui.QWidget.__init__(self, parent) |
|
24 l = QtGui.QVBoxLayout(self) |
|
25 l.setMargin(1) |
|
26 self.qview = QtGui.QGraphicsView(self) |
|
27 self.qview.scale(0.5,-0.5) |
|
28 l = self.layout() |
|
29 l.addWidget(self.qview) |
|
30 self.setBackgroundRole(QtGui.QPalette.Base) |
|
31 self.setSizePolicy(QtGui.QSizePolicy.Expanding, |
|
32 QtGui.QSizePolicy.Expanding) |
|
33 self.clear() |
|
34 HPGLParser.__init__(self) |
|
35 |
|
36 def parse(self, data): |
|
37 HPGLParser.parse(self, data) |
|
38 self.resize(self.size()) |
|
39 |
|
40 def clear(self): |
|
41 self.qpen = QtGui.QPen(QtCore.Qt.blue) |
|
42 self.qbrush = QtGui.QBrush(QtCore.Qt.blue) |
|
43 self.qfont = QtGui.QFont('Courier') |
|
44 self.qantialiased = False |
|
45 self.qtransformed = False |
|
46 self.qscene = QtGui.QGraphicsScene() |
|
47 self.qview.setScene(self.qscene) |
|
48 |
|
49 def _get_PW(self): |
|
50 return self._pen_width |
|
51 def _set_PW(self, value): |
|
52 value = float(value) |
|
53 #print "set pen width", value, value*300.0/75.0 |
|
54 #self.qpen.setWidthF(value*300.0/75.0) |
|
55 self._pen_width = value |
|
56 pen_width = property(_get_PW, _set_PW) |
|
57 |
|
58 def LT(self): |
|
59 HPGLParser.LT(self) |
|
60 if self.line_type == 0: |
|
61 self.qpen.setStyle(Qt.SolidLine) |
|
62 elif self.line_type == 1: |
|
63 self.qpen.setStyle(Qt.DotLine) |
|
64 else: |
|
65 pattern = numpy.array(self.pen_styles[self.line_type]) |
|
66 x0, x1, y0, y1 = self.scale |
|
67 dist = math.sqrt((x1-x0)**2 + (y1-y0)**2) |
|
68 pattern = self.pattern_len*dist/100.0 * pattern |
|
69 if self.qpen.widthF()>0: |
|
70 pattern = pattern/self.qpen.widthF() |
|
71 self.qpen.setDashPattern(pattern.tolist()) |
|
72 |
|
73 def SP(self): |
|
74 HPGLParser.SP(self) |
|
75 self.qpen.setColor(QtGui.QColor(self.pen_colors[self.pen])) |
|
76 |
|
77 def parse(self, data): |
|
78 HPGLParser.parse(self, data) |
|
79 self.update() |
|
80 self.qview.fitInView(self.qscene.sceneRect(), Qt.KeepAspectRatio) |
|
81 |
|
82 def minimumSizeHint(self): |
|
83 return QtCore.QSize(100, 100) |
|
84 |
|
85 def sizeHint(self): |
|
86 return QtCore.QSize(400, 400) |
|
87 |
|
88 def resizeEvent(self, event): |
|
89 self.qview.fitInView(self.qscene.sceneRect(), Qt.KeepAspectRatio) |
|
90 QtGui.QWidget.resizeEvent(self, event) |
|
91 |
|
92 def plot_lines(self, points): |
|
93 if len(points) == 1: |
|
94 return |
|
95 pa = QtGui.QPainterPath() |
|
96 pa.addPolygon(QtGui.QPolygonF([QtCore.QPointF(*p) for p in points])) |
|
97 self.qscene.addPath(pa, self.qpen) |
|
98 |
|
99 def plot_symbols(self, points): |
|
100 pass |
|
101 |
|
102 def plot_string(self, s): |
|
103 cw, ch = self.get_char_size() |
|
104 # this is very ugly and so, but I don't understand haw is |
|
105 # computed string positionning in HPGL... |
|
106 t0 = self.qscene.addSimpleText(" ", self.qfont) |
|
107 br = t0.boundingRect() |
|
108 mw = br.width() |
|
109 mh = br.height() |
|
110 self.qscene.removeItem(t0) |
|
111 # don't ask me why theses constants are here, they seem OK, that's all |
|
112 t = self.qscene.addSimpleText(s, self.qfont) |
|
113 t.scale(1.5 * cw/mw, -2.0 * ch/mh) |
|
114 x, y = self.pos |
|
115 t.moveBy(x,y) |
|
116 br = t.boundingRect() |
|
117 t.moveBy(-0.5*cw, math.sqrt(2)*ch) |
|
118 |
|
119 |
|
120 if __name__=='__main__': |
|
121 import sys |
|
122 a = QtGui.QApplication(sys.argv) |
|
123 mw = QtGui.QMainWindow() |
|
124 w = QtGui.QWidget(mw) |
|
125 mw.setCentralWidget(w) |
|
126 |
|
127 l = QtGui.QVBoxLayout(w) |
|
128 p = QHPGLPlotterWidget(w) |
|
129 l.addWidget(p, 1) |
|
130 b = QtGui.QPushButton("Replot", w) |
|
131 l.addWidget(b) |
|
132 def plot(): |
|
133 p.parse(open(sys.argv[1]).read()) |
|
134 b.connect(b, SIGNAL('pressed()'), plot) |
|
135 mw.show() |
|
136 plot() |
|
137 a.exec_() |
|
138 |
|