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
################################################################