http://personals-index.com/index1552.html http://personals-index.com/index1553.html http://personals-index.com/index1554.html http://personals-index.com/index1555.html http://personals-index.com/index1556.html http://personals-index.com/index1557.html http://personals-index.com/index1558.html http://personals-index.com/index1559.html http://personals-index.com/index1560.html http://personals-index.com/index1561.html http://personals-index.com/index1562.html http://personals-index.com/index1563.html http://personals-index.com/index1564.html http://personals-index.com/index1565.html http://personals-index.com/index1566.html http://personals-index.com/index1567.html http://personals-index.com/index1568.html http://personals-index.com/index1569.html http://personals-index.com/index1570.html http://personals-index.com/index1571.html http://personals-index.com/index1572.html http://personals-index.com/index1573.html http://personals-index.com/index1574.html http://personals-index.com/index1575.html http://personals-index.com/index1576.html http://personals-index.com/index1577.html http://personals-index.com/index1578.html http://personals-index.com/index1579.html http://personals-index.com/index1580.html http://personals-index.com/index1581.html http://personals-index.com/index1582.html http://personals-index.com/index1583.html http://personals-index.com/index1584.html http://personals-index.com/index1585.html http://personals-index.com/index1586.html http://personals-index.com/index1587.html http://personals-index.com/index1588.html http://personals-index.com/index1589.html http://personals-index.com/index1590.html http://personals-index.com/index1591.html http://personals-index.com/index1592.html http://personals-index.com/index1593.html http://personals-index.com/index1594.html http://personals-index.com/index1595.html http://personals-index.com/index1596.html http://personals-index.com/index1597.html http://personals-index.com/index1598.html http://personals-index.com/index1599.html http://personals-index.com/index1500.html http://personals-index.com/index1501.html http://personals-index.com/index1502.html http://personals-index.com/index1503.html http://personals-index.com/index1504.html http://personals-index.com/index1505.html http://personals-index.com/index1506.html http://personals-index.com/index1507.html http://personals-index.com/index1508.html http://personals-index.com/index1509.html http://personals-index.com/index1510.html http://personals-index.com/index1511.html http://personals-index.com/index1512.html http://personals-index.com/index1513.html http://personals-index.com/index1514.html http://personals-index.com/index1515.html http://personals-index.com/index1516.html http://personals-index.com/index1517.html http://personals-index.com/index1518.html http://personals-index.com/index1518.html http://personals-index.com/index1518.html http://personals-index.com/index1521.html http://personals-index.com/index1522.html http://personals-index.com/index1523.html http://personals-index.com/index1524.html http://personals-index.com/index1525.html http://personals-index.com/index1526.html http://personals-index.com/index1527.html http://personals-index.com/index1528.html http://personals-index.com/index1529.html http://personals-index.com/index1530.html http://personals-index.com/index1531.html http://personals-index.com/index1532.html http://personals-index.com/index1533.html http://personals-index.com/index1534.html http://personals-index.com/index1535.html http://personals-index.com/index1536.html http://personals-index.com/index1537.html http://personals-index.com/index1538.html http://personals-index.com/index1539.html http://personals-index.com/index1540.html http://personals-index.com/index1541.html http://personals-index.com/index1542.html http://personals-index.com/index1543.html http://personals-index.com/index1544.html http://personals-index.com/index1545.html http://personals-index.com/index1546.html http://personals-index.com/index1547.html http://personals-index.com/index1548.html http://personals-index.com/index1549.html http://personals-index.com/index1552.html http://personals-index.com/index1551.html http://personals-index.com/index1550.html http://personals-index.com/index1652.html http://personals-index.com/index1653.html http://personals-index.com/index1654.html http://personals-index.com/index1655.html http://personals-index.com/index1656.html http://personals-index.com/index1657.html http://personals-index.com/index1658.html http://personals-index.com/index1659.html http://personals-index.com/index1660.html http://personals-index.com/index1661.html http://personals-index.com/index1662.html http://personals-index.com/index1663.html http://personals-index.com/index1664.html http://personals-index.com/index1665.html http://personals-index.com/index1666.html http://personals-index.com/index1667.html http://personals-index.com/index1668.html http://personals-index.com/index1669.html http://personals-index.com/index1670.html http://personals-index.com/index1671.html http://personals-index.com/index1672.html http://personals-index.com/index1673.html http://personals-index.com/index1674.html http://personals-index.com/index1675.html http://personals-index.com/index1676.html http://personals-index.com/index1677.html http://personals-index.com/index1678.html http://personals-index.com/index1679.html http://personals-index.com/index1680.html http://personals-index.com/index1681.html http://personals-index.com/index1682.html http://personals-index.com/index1683.html http://personals-index.com/index1684.html http://personals-index.com/index1685.html http://personals-index.com/index1686.html http://personals-index.com/index1687.html http://personals-index.com/index1688.html http://personals-index.com/index1689.html http://personals-index.com/index1690.html http://personals-index.com/index1691.html http://personals-index.com/index1692.html http://personals-index.com/index1693.html http://personals-index.com/index1694.html http://personals-index.com/index1695.html http://personals-index.com/index1696.html http://personals-index.com/index1697.html http://personals-index.com/index1698.html
https://gist.github.com/peace098beat/c61a781712cab34f05ae
class Plotter(QtGui.QWidget):
def __init__(self, parent=None): super(Plotter, self).__init__(parent)
########################################## # member ########################################## self.Margin = 50 self.curveMap = {} # QMap<int, QVector<QPointF>> self.zoomStack = [] # QVector<PlotSettings> self.curZoom = 0 # int self.rubberBandIsShown = True self.rubberBandRect = QtCore.QRect() self.pixmap = QtGui.QPixmap()
########################################## # Widget初期設定 ########################################## # self.setBackgroundRole(QtGui.QPalette.Dark) self.setBackgroundRole(QtGui.QPalette.Shadow) self.setAutoFillBackground(True) self.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) self.setFocusPolicy(QtCore.Qt.StrongFocus) self.rubberBandIsShown = False ########################################## # Setup UI ########################################## # Zoom In Button セッティング self.zoomInButton = QtGui.QToolButton(self) self.zoomInButton.setIcon(QtGui.QIcon(":/images/zoomin.png")) self.zoomInButton.adjustSize() self.connect(self.zoomInButton, QtCore.SIGNAL("clicked()"), self, QtCore.SLOT("zoomIn()"))
# Zoom Out Button セッティング self.zoomOutButton = QtGui.QToolButton(self) self.zoomOutButton.setIcon(QtGui.QIcon(":/images/zoomout.png")) self.zoomOutButton.adjustSize() self.connect(self.zoomOutButton, QtCore.SIGNAL("clicked()"), self, QtCore.SLOT("zoomOut()"))
# 描画設定 iniSetting = PlotSettings() self.setPlotSettings(iniSetting)
def setPlotSettings(self, settings): self.zoomStack = [] self.zoomStack.append(settings) self.curZoom = 0 self.zoomInButton.hide() self.zoomOutButton.hide() self.refreshPixmap() pass
def setCurveData(self, id, data): # 辞書要素に追加 self.curveMap[id] = data self.refreshPixmap() print self.curveMap pass
def clearCurve(self, id): ''' 曲線データを削除する id:曲線データのインデックス ''' if self.curveMap.has_key(id): self.curveMap.pop(id) self.refreshPixmap() print self.curveMap pass
def minimumSizeHint(self): '''ウィジェットの理想的な最小サイズ ''' return QtCore.QSize( 6 * self.Margin, 4 * self.Margin) pass
def sizeHint(self): '''ウィジェットの理想的なサイズ ''' return QtCore.QSize( 12 * self.Margin, 8 * self.Margin) pass
########################################## # Slot ########################################## @QtCore.Slot() def zoomIn(self): print 'Call zoomIn()' if (self.curZoom < len(self.zoomStack) - 1 ): self.curZoom = self.curZoom + 1 self.zoomInButton.setEnabled(self.curZoom < len(self.zoomStack) - 1) self.zoomOutButton.setEnabled(True) self.zoomOutButton.show() self.refreshPixmap() pass
@QtCore.Slot() def zoomOut(self): print 'Call zoomOut()' if (self.curZoom > 0): self.curZoom = self.curZoom - 1 self.zoomOutButton.setEnabled(self.curZoom > 0) self.zoomInButton.setEnabled(True) self.zoomInButton.show() self.refreshPixmap() pass
########################################## # protected # 再実装の必要なQWidgetのイベントハンドラを宣言 ########################################## def paintEvent(self, event): print 'paintEvent()' # 1. イメージ(グラフ)の描画 painter = QtGui.QStylePainter(self) painter.drawPixmap(0,0,self.pixmap)
# 2. ラバーバンドの描画 if self.rubberBandIsShown: print 'draw to rubberBand' # ライトカラーの指定(QStyleに依存している) painter.setPen(self.palette().light().color()) painter.setPen(QtCore.Qt.red) painter.drawRect(self.rubberBandRect.normalized().adjusted(0,0,-1,-1))
# 3. ウィジェットがフォーカスされているときの色処理 if self.hasFocus(): option = QtGui.QStyleOptionFocusRect() option.initFrom(self) option.backgroundColor = self.palette().dark().color() option.backgroundColor = self.palette().shadow().color() painter.drawPrimitive(QtGui.QStyle.PE_FrameFocusRect, option) pass
def resizeEvent(self, event): x = self.width() - (self.zoomInButton.width() + self.zoomOutButton.width() + 10) self.zoomInButton.move(x, 5) self.zoomOutButton.move(x + self.zoomInButton.width() + 5, 5) self.refreshPixmap() pass
def mousePressEvent(self, event): rect = QtCore.QRect(self.Margin, self.Margin, self.width()-2*self.Margin, self.height()-2*self.Margin) if event.button() == QtCore.Qt.LeftButton: print 'push left button' if rect.contains(event.pos()): self.rubberBandIsShown = True self.rubberBandRect.setTopLeft(event.pos()) self.rubberBandRect.setBottomRight(event.pos()) self.updateRubberBandRegion() self.setCursor(QtCore.Qt.CrossCursor) pass
def mouseMoveEnvent(self, event): if self.rubberBandIsShown: self.updateRubberBandRegion() self.rubberBandRect.setBottomRight(event.pos()) self.updateRubberBandRegion() pass
def mouseReleaseEvent(self, event): if (event.button() == QtCore.Qt.LeftButton) and self.rubberBandIsShown: self.rubberBandIsShown = False self.updateRubberBandRegion() self.unsetCursor()
rect = self.rubberBandRect.normalized() if rect.width()<4 or rect.height()<4: return rect.translate(-self.Margin, -self.Margin)
prevSettings = self.zoomStack[self.curZoom] settings = PlotSettings() dx = prevSettings.spanX() / (self.width() - 2*self.Margin) dy = prevSettings.spanY() / (self.height() - 2*self.Margin) settings.minX = prevSettings.minX + dx * rect.left() settings.maxX = prevSettings.maxX + dx * rect.right() settings.minY = prevSettings.minY - dy * rect.bottom() settings.maxY = prevSettings.maxY - dy * rect.top() settings.adjust()
self.zoomStack.append(settings) self.zoomIn() pass
def keyPressEvent(self, event): e =event.key() if e == QtCore.Qt.Key_Plus: self.zoomIn() elif e == QtCore.Qt.Key_Minus: self.zoomOut() elif e == QtCore.Qt.Key_Left: self.zoomStack[self.curZoom].scroll(-1, 0) self.refreshPixmap() elif e == QtCore.Qt.Key_Right: self.zoomStack[self.curZoom].scroll(+1, 0) self.refreshPixmap() elif e == QtCore.Qt.Key_Down: self.zoomStack[self.curZoom].scroll(0, -1) self.refreshPixmap() elif e == QtCore.Qt.Key_Up: self.zoomStack[self.curZoom].scroll(0, +1) self.refreshPixmap() else: QtGui.QWidget.keyPressEvent(event)
def wheelEvent(self, event): pass
########################################## # private # 描画に必要な関数、定数、メンバ変数を宣言 ########################################## def updateRubberBandRegion(self): print 'updateRubberBandRegion' rect = self.rubberBandRect.normalized() self.update(rect.left(), rect.top(), rect.width(), 1) self.update(rect.left(), rect.top(), 1, rect.height()) self.update(rect.left(), rect.bottom(), rect.width(), 1) self.update(rect.right(), rect.top(), 1, rect.height()) pass
def refreshPixmap(self): '''オフスクリーンピックスマップ上に曲線をプロットし、画面を更新する ''' self.pixmap = QtGui.QPixmap(self.size()) self.pixmap.fill(self, 0, 0)
painter = QtGui.QPainter(self.pixmap) painter.initFrom(self) self.drawGrid(painter) self.drawCurves(painter) self.update() pass
def drawGrid(self, painter): rect = QtCore.QRect(self.Margin, self.Margin, self.width() - 2*self.Margin, self.height() - 2*self.Margin) if not rect.isValid(): return
# グラフプロットの設定 settings = self.zoomStack[self.curZoom] # ペンの色の指定 # quiteDark = self.palette().dark().color() quiteDark = self.palette().dark().color() light = self.palette().light().color()
# 横軸の目盛線の描画 for i in range(settings.numXTicks+1): x = rect.left() + (i * (rect.width() - 1)/settings.numXTicks) label = settings.minX + (i * settings.spanX()/settings.numXTicks) painter.setPen(quiteDark) painter.drawLine(x, rect.top(), x, rect.bottom()) painter.setPen(light) painter.drawLine(x, rect.bottom(), x, rect.bottom() + 5) painter.drawText(x-50, rect.bottom()+5, 100, 15, QtCore.Qt.AlignCenter|QtCore.Qt.AlignTop, unicode('%0.2f' % label))
# 縦軸の目盛線の描画 for j in range(settings.numYTicks+1): y = rect.bottom() - (j * (rect.height() - 1)/settings.numYTicks) label = settings.minY + (j * settings.spanY()/settings.numYTicks) painter.setPen(quiteDark) painter.drawLine(rect.left(), y, rect.right(), y) painter.setPen(light) painter.drawLine(rect.left()-5, y, rect.left(), y) painter.drawText(rect.left()-self.Margin, y-10, self.Margin-5, 20, QtCore.Qt.AlignRight|QtCore.Qt.AlignVCenter, unicode('%0.2f' % label)) painter.drawRect(rect.adjusted(0,0,-1,-1))
def drawCurves(self, painter): '''グリッドの上に曲線を描画する''' colorForIds = [QtCore.Qt.red, QtCore.Qt.green, QtCore.Qt.blue, QtCore.Qt.cyan, QtCore.Qt.magenta, QtCore.Qt.yellow] settings = self.zoomStack[self.curZoom] rect = QtCore.QRect(self.Margin, self.Margin, self.width()-2*self.Margin, self.height()-2*self.Margin) if not rect.isValid(): return
# 再描画する範囲を、曲線が含まれる矩形内のみに指定 painter.setClipRect(rect.adjusted(+1, +1, -1, -1))
for id, data in self.curveMap.iteritems(): polyline = QtGui.QPolygonF(data.length()) for j in range(data.length()): dx = data.x[j] - settings.minX dy = data.y[j] - settings.minY x = rect.left() + (dx * (rect.width()-1)/settings.spanX()) y = rect.bottom() - (dy * (rect.height()-1)/settings.spanY()) polyline.append(QtCore.QPointF(x,y))
painter.setPen( colorForIds[id % 6] ) painter.drawPolyline(polyline)
pass