Mon, 04 Feb 2008 19:19:32 +0100
constant adjustments for string plots
# -*- coding: utf-8 -*- import numpy import pylab import math import new # monkey patching... from PyQt4 import QtGui, QtCore from PyQt4.QtCore import Qt, SIGNAL from hpgl_parser import HPGLParser class QHPGLPlotterWidget(HPGLParser, QtGui.QWidget): pen_styles = {2: [0.4, 0.6], 3: [0.6, 0.4], 4: [0.7, 0.1, 0.1, 0.1], 5: [0.6, 0.1, 0.2, 0.1], 6: [0.45, 0.1, 0.1, 0.2, 0.1, 0.05], } pen_colors = ["black", "green", "red", "blue", "yellow", "cyan", "magenta", "darkred", "darkblue"] def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) l = QtGui.QVBoxLayout(self) l.setMargin(1) self.qview = QtGui.QGraphicsView(self) self.qview.setRenderHints(QtGui.QPainter.Antialiasing) self.qview.scale(0.5,-0.5) l = self.layout() l.addWidget(self.qview) self.setBackgroundRole(QtGui.QPalette.Base) self.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) self.clear() HPGLParser.__init__(self) def parse(self, data): HPGLParser.parse(self, data) self.resize(self.size()) def clear(self): self.qpen = QtGui.QPen(QtCore.Qt.blue) self.qbrush = QtGui.QBrush(QtCore.Qt.blue) self.qfont = QtGui.QFont('Courier') self.qantialiased = False self.qtransformed = False self.qscene = QtGui.QGraphicsScene() self.qview.setScene(self.qscene) def _get_PW(self): return self._pen_width def _set_PW(self, value): value = float(value) #print "set pen width", value, value*300.0/75.0 #self.qpen.setWidthF(value*300.0/75.0) self._pen_width = value pen_width = property(_get_PW, _set_PW) def LT(self): HPGLParser.LT(self) if self.line_type == 0: self.qpen.setStyle(Qt.SolidLine) elif self.line_type == 1: self.qpen.setStyle(Qt.DotLine) else: pattern = numpy.array(self.pen_styles[self.line_type]) x0, x1, y0, y1 = self.scale dist = math.sqrt((x1-x0)**2 + (y1-y0)**2) pattern = self.pattern_len*dist/100.0 * pattern if self.qpen.widthF()>0: pattern = pattern/self.qpen.widthF() self.qpen.setDashPattern(pattern.tolist()) def SP(self): HPGLParser.SP(self) color = self.pen_colors[self.pen] if isinstance(color, tuple): color = QtGui.QColor(*color) else: color = QtGui.QColor(color) self.qpen.setColor(color) def parse(self, data): HPGLParser.parse(self, data) self.update() self.qview.fitInView(self.qscene.sceneRect(), Qt.KeepAspectRatio) def minimumSizeHint(self): return QtCore.QSize(100, 100) def sizeHint(self): return QtCore.QSize(400, 400) def resizeEvent(self, event): self.qview.fitInView(self.qscene.sceneRect(), Qt.KeepAspectRatio) QtGui.QWidget.resizeEvent(self, event) def plot_lines(self, points): if len(points) == 1: return pa = QtGui.QPainterPath() pa.addPolygon(QtGui.QPolygonF([QtCore.QPointF(*p) for p in points])) self.qscene.addPath(pa, self.qpen) def plot_symbols(self, points): pass def plot_string(self, s): cw, ch = self.get_char_size() # this is very ugly and so, but I don't understand haw is # computed string positionning in HPGL... t0 = self.qscene.addSimpleText(" ", self.qfont) br = t0.boundingRect() mw = br.width() mh = br.height() self.qscene.removeItem(t0) # don't ask me why theses constants are here, they seem OK, that's all t = self.qscene.addSimpleText(s, self.qfont) t.scale(1.0 * cw/mw, -1.6 * ch/mh) x, y = self.pos t.moveBy(x,y) br = t.boundingRect() t.moveBy(-0.5*cw+8, math.sqrt(2)*ch - 13) if __name__=='__main__': import sys a = QtGui.QApplication(sys.argv) mw = QtGui.QMainWindow() w = QtGui.QWidget(mw) mw.setCentralWidget(w) l = QtGui.QVBoxLayout(w) p = QHPGLPlotterWidget(w) l.addWidget(p, 1) b = QtGui.QPushButton("Replot", w) l.addWidget(b) def plot(): p.parse(open(sys.argv[1]).read()) b.connect(b, SIGNAL('pressed()'), plot) mw.show() plot() a.exec_()