# HG changeset patch # User David Douard # Date 1200073808 -3600 # Node ID 66b7cd43bac1d0282ccbe93a6ee85783249b27a2 # Parent de60b63b227530740268ea5653939bdd7b79c064 Add HPGL plotter backend for Qt4 diff -r de60b63b2275 -r 66b7cd43bac1 hpgl_qt.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hpgl_qt.py Fri Jan 11 18:50:08 2008 +0100 @@ -0,0 +1,129 @@ +# -*- 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) + + 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 = QtGui.QGraphicsView(self.qscene, self) + self.qview.scale(0.5,-0.5) + l = QtGui.QVBoxLayout(self) + l.addWidget(self.qview) + self.setBackgroundRole(QtGui.QPalette.Base) + self.setSizePolicy(QtGui.QSizePolicy.Expanding, + QtGui.QSizePolicy.Expanding) + HPGLParser.__init__(self) + + 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) + self.qpen.setColor(QtGui.QColor(self.pen_colors[self.pen])) + + 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.5 * cw/mw, -2.0 * ch/mh) + x, y = self.pos + t.moveBy(x,y) + br = t.boundingRect() + t.moveBy(-0.5*cw, math.sqrt(2)*ch) + + +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_() +