開始行:
[[FrontPage/Python/PySide]]
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, Q...
self.setFocusPolicy(QtCore.Qt.StrongFocus)
self.rubberBandIsShown = False
##########################################
# Setup UI
##########################################
# Zoom In Button セッティング
self.zoomInButton = QtGui.QToolButton(self)
self.zoomInButton.setIcon(QtGui.QIcon(":/images/z...
self.zoomInButton.adjustSize()
self.connect(self.zoomInButton, QtCore.SIGNAL("cl...
# Zoom Out Button セッティング
self.zoomOutButton = QtGui.QToolButton(self)
self.zoomOutButton.setIcon(QtGui.QIcon(":/images/...
self.zoomOutButton.adjustSize()
self.connect(self.zoomOutButton, QtCore.SIGNAL("c...
# 描画設定
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.Ma...
pass
def sizeHint(self):
'''ウィジェットの理想的なサイズ
'''
return QtCore.QSize( 12 * self.Margin, 8 * self.M...
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 < l...
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.normaliz...
# 3. ウィジェットがフォーカスされているときの色処理
if self.hasFocus():
option = QtGui.QStyleOptionFocusRect()
option.initFrom(self)
option.backgroundColor = self.palette().dark(...
option.backgroundColor = self.palette().shado...
painter.drawPrimitive(QtGui.QStyle.PE_FrameFo...
pass
def resizeEvent(self, event):
x = self.width() - (self.zoomInButton.width() + s...
self.zoomInButton.move(x, 5)
self.zoomOutButton.move(x + self.zoomInButton.wid...
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....
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 s...
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...
dy = prevSettings.spanY() / (self.height() - ...
settings.minX = prevSettings.minX + dx * rect...
settings.maxX = prevSettings.maxX + dx * rect...
settings.minY = prevSettings.minY - dy * rect...
settings.maxY = prevSettings.maxY - dy * rect...
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()...
self.update(rect.left(), rect.top(), 1, rect.heig...
self.update(rect.left(), rect.bottom(), rect.widt...
self.update(rect.right(), rect.top(), 1, rect.hei...
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)/set...
label = settings.minX + (i * settings.spanX()...
painter.setPen(quiteDark)
painter.drawLine(x, rect.top(), x, rect.botto...
painter.setPen(light)
painter.drawLine(x, rect.bottom(), x, rect.bo...
painter.drawText(x-50, rect.bottom()+5, 100, ...
QtCore.Qt.AlignCenter|QtCore...
unicode('%0.2f' % label))
# 縦軸の目盛線の描画
for j in range(settings.numYTicks+1):
y = rect.bottom() - (j * (rect.height() - 1)/...
label = settings.minY + (j * settings.spanY()...
painter.setPen(quiteDark)
painter.drawLine(rect.left(), y, rect.right()...
painter.setPen(light)
painter.drawLine(rect.left()-5, y, rect.left(...
painter.drawText(rect.left()-self.Margin, y-1...
QtCore.Qt.AlignRight|QtCore....
unicode('%0.2f' % label))
painter.drawRect(rect.adjusted(0,0,-1,-1))
def drawCurves(self, painter):
'''グリッドの上に曲線を描画する'''
colorForIds = [QtCore.Qt.red, QtCore.Qt.green, Qt...
settings = self.zoomStack[self.curZoom]
rect = QtCore.QRect(self.Margin, self.Margin, sel...
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)/...
y = rect.bottom() - (dy * (rect.height()-...
polyline.append(QtCore.QPointF(x,y))
painter.setPen( colorForIds[id % 6] )
painter.drawPolyline(polyline)
pass
終了行:
[[FrontPage/Python/PySide]]
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, Q...
self.setFocusPolicy(QtCore.Qt.StrongFocus)
self.rubberBandIsShown = False
##########################################
# Setup UI
##########################################
# Zoom In Button セッティング
self.zoomInButton = QtGui.QToolButton(self)
self.zoomInButton.setIcon(QtGui.QIcon(":/images/z...
self.zoomInButton.adjustSize()
self.connect(self.zoomInButton, QtCore.SIGNAL("cl...
# Zoom Out Button セッティング
self.zoomOutButton = QtGui.QToolButton(self)
self.zoomOutButton.setIcon(QtGui.QIcon(":/images/...
self.zoomOutButton.adjustSize()
self.connect(self.zoomOutButton, QtCore.SIGNAL("c...
# 描画設定
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.Ma...
pass
def sizeHint(self):
'''ウィジェットの理想的なサイズ
'''
return QtCore.QSize( 12 * self.Margin, 8 * self.M...
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 < l...
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.normaliz...
# 3. ウィジェットがフォーカスされているときの色処理
if self.hasFocus():
option = QtGui.QStyleOptionFocusRect()
option.initFrom(self)
option.backgroundColor = self.palette().dark(...
option.backgroundColor = self.palette().shado...
painter.drawPrimitive(QtGui.QStyle.PE_FrameFo...
pass
def resizeEvent(self, event):
x = self.width() - (self.zoomInButton.width() + s...
self.zoomInButton.move(x, 5)
self.zoomOutButton.move(x + self.zoomInButton.wid...
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....
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 s...
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...
dy = prevSettings.spanY() / (self.height() - ...
settings.minX = prevSettings.minX + dx * rect...
settings.maxX = prevSettings.maxX + dx * rect...
settings.minY = prevSettings.minY - dy * rect...
settings.maxY = prevSettings.maxY - dy * rect...
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()...
self.update(rect.left(), rect.top(), 1, rect.heig...
self.update(rect.left(), rect.bottom(), rect.widt...
self.update(rect.right(), rect.top(), 1, rect.hei...
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)/set...
label = settings.minX + (i * settings.spanX()...
painter.setPen(quiteDark)
painter.drawLine(x, rect.top(), x, rect.botto...
painter.setPen(light)
painter.drawLine(x, rect.bottom(), x, rect.bo...
painter.drawText(x-50, rect.bottom()+5, 100, ...
QtCore.Qt.AlignCenter|QtCore...
unicode('%0.2f' % label))
# 縦軸の目盛線の描画
for j in range(settings.numYTicks+1):
y = rect.bottom() - (j * (rect.height() - 1)/...
label = settings.minY + (j * settings.spanY()...
painter.setPen(quiteDark)
painter.drawLine(rect.left(), y, rect.right()...
painter.setPen(light)
painter.drawLine(rect.left()-5, y, rect.left(...
painter.drawText(rect.left()-self.Margin, y-1...
QtCore.Qt.AlignRight|QtCore....
unicode('%0.2f' % label))
painter.drawRect(rect.adjusted(0,0,-1,-1))
def drawCurves(self, painter):
'''グリッドの上に曲線を描画する'''
colorForIds = [QtCore.Qt.red, QtCore.Qt.green, Qt...
settings = self.zoomStack[self.curZoom]
rect = QtCore.QRect(self.Margin, self.Margin, sel...
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)/...
y = rect.bottom() - (dy * (rect.height()-...
polyline.append(QtCore.QPointF(x,y))
painter.setPen( colorForIds[id % 6] )
painter.drawPolyline(polyline)
pass
ページ名: