Add HPGL plotter backend for Qt4

Fri, 11 Jan 2008 18:50:08 +0100

author
David Douard <david.douard@logilab.fr>
date
Fri, 11 Jan 2008 18:50:08 +0100
changeset 21
66b7cd43bac1
parent 20
de60b63b2275
child 22
b2f4646161be

Add HPGL plotter backend for Qt4

hpgl_qt.py file | annotate | diff | comparison | revisions
--- /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_()
+    

mercurial