Source code for kf.QtWinch

"""PyQt5 widgets to render cartoons of winch and line systems.
"""

################################################################
# Written in 2018-2019 by Garth Zeglin <garthz@cmu.edu>

# To the extent possible under law, the author has dedicated all copyright
# and related and neighboring rights to this software to the public domain
# worldwide. This software is distributed without any warranty.

# You should have received a copy of the CC0 Public Domain Dedication along with this software.
# If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.

################################################################

# for documentation on the PyQt5 API, see http://pyqt.sourceforge.net/Docs/PyQt5/index.html
from PyQt5 import QtCore, QtGui, QtWidgets

################################################################
[docs]class QtWinchCartoon(QtWidgets.QWidget): """Custom widget representing a single winch as a 2D cartoon view.""" def __init__(self): super().__init__() self.setMinimumSize(QtCore.QSize(100, 100)) self.setAutoFillBackground(True) # graphical state variables self.position = 0.0 # units are microsteps # Create a path representing the basic glyph. The default coordinates # have +X to the right, +Y down. self.winch_symbol = QtGui.QPainterPath() self.winch_symbol.addEllipse(QtCore.QPointF(0.0, 0.0), 0.9, 0.9) # center, rx, ry self.winch_symbol.moveTo( 0.25, -0.8) self.winch_symbol.lineTo( 0.00, -0.5) self.winch_symbol.lineTo(-0.25, -0.8) # finish initialization self.show() return
[docs] def update_position(self, position): self.position = position self.repaint()
[docs] def paintEvent(self, e): geometry = self.geometry() width = geometry.width() height = geometry.height() qp = QtGui.QPainter() qp.begin(self) # qp.fillRect(QtCore.QRectF(0, 0, width, height), QtCore.Qt.white) # qp.setRenderHint(QtGui.QPainter.Antialiasing) # set up a unit coordinate system centered in the visible area qp.save() scaling = width/2 if width < height else height/2 qp.translate(QtCore.QPointF(width/2, height/2)) qp.scale(scaling, scaling) # The default coordinate system rotation uses +Z pointing into the # screen; this changes sign so positive displacements are # counter-clockwise, i.e. right-hand-rule on the vector pointing *out* # of the screen. This rescales from microsteps to degrees. qp.rotate(-self.position*(360/800)) if False: # draw the winch symbol pen = QtGui.QPen(QtCore.Qt.black) pen.setWidthF(0.1) qp.setPen(pen) qp.setBrush(QtCore.Qt.NoBrush) qp.drawPath(self.winch_symbol) else: # use simplified line graphics for better drawing speed pen = QtGui.QPen(QtCore.Qt.black) pen.setWidthF(0.05) qp.setPen(pen) qp.drawLine(QtCore.QPointF(0,0), QtCore.QPointF(0,-0.8)) qp.drawRect(QtCore.QRectF(-0.2, -0.2, 0.4, 0.4)) qp.restore() # draw the text annotation qp.drawText(10, height-4, "%d" % int(self.position)) qp.end()
################################################################
[docs]class QtWinchSet(QtWidgets.QWidget): """Composite widget representing a set of winches as a 2D cartoon view.""" def __init__(self, count=4): super().__init__() self._layout = QtWidgets.QHBoxLayout() self._winches = list() for winch in range(count): winch = QtWinchCartoon() self._layout.addWidget(winch) self._winches.append(winch) self.setLayout(self._layout) return
[docs] def winches(self): """Return a list of QtWinch objects contained in the set.""" return self._winches
################################################################