Skip to content

Instantly share code, notes, and snippets.

@peace098beat
Created November 19, 2015 23:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save peace098beat/db002e83002cc16c7981 to your computer and use it in GitHub Desktop.
Save peace098beat/db002e83002cc16c7981 to your computer and use it in GitHub Desktop.
[PySide] QPainterのスケルトンコード
#! coding:utf-8
"""
pyside-painter-skelton.py
pysideでグラフィックを描画するためのスケルトンコード
Created by 0160929 on 2015/11/19 7:28
"""
__version__ = '0.3'
import sys
import os
# PySide系モジュール
from PySide.QtGui import *
from PySide.QtCore import *
# 演算系モジュール
import numpy as np
# logを保存
from datetime import datetime
import csv
def resetlog(file):
if os.path.exists(file):
os.remove(file)
# ログファイルを削除
resetlog('log.cav')
def debuglog(s=None, data=None):
d = datetime.now().isoformat()
with open('log.csv', 'a') as f:
writer = csv.writer(f, lineterminator='\n')
if not s is None:
writer.writerow([d, s])
print d, s
if not data is None:
writer.writerow([d, data])
print d, data
return
# 描画用PySideクラス
class GameWindow(QWidget):
# -- 定数(画面サイズ) -----------------
SCREEN_HEIGHT = 500
SCREEN_WIDTH = 700
MARGIN_HEIGHT = 50
MARGIN_WIDTH = 50
STAGE_HEIGHT = SCREEN_HEIGHT - 2 * MARGIN_HEIGHT
STAGE_WIDTH = SCREEN_WIDTH - 2 * MARGIN_WIDTH
# -- 定数(タイマー ms) -------------------
INTERVAL_TIME = 1
# -- 定数(その他) ---------------------
def __init__(self, parent=None):
QWidget.__init__(self, parent)
self.resize(self.SCREEN_WIDTH, self.SCREEN_HEIGHT)
# -- 定数 ----------------------------
self.step = 0
# -- 画面バッファ --------------------
self.pixmap = QPixmap(self.size())
# -- 解析用オブジェクト --------------
# -- 操作用変数 ----------------------
# -- 初期画面の準備 ------------------
self.refreshPixmap() # 画面バッファの初期化
painter = QPainter(self.pixmap)
self.drawGrid(painter) # グリッドの表示
self.update()
# メインループの準備と開始
# -------------------------
if False:
self.timer = QTimer()
self.timer.timeout.connect(self.mainloop)
self.timer.start(self.INTERVAL_TIME)
# ************************************************************* #
# メインループ
# ************************************************************* #
def mainloop(self):
"""
アニメーションのメインループ
アルゴリズムの時間更新等はここで行う
"""
self.step += 1
# -- アルゴリズム処理-----------
# -- 描画 ----------------------
painter = QPainter(self.pixmap)
self.drawGrid(painter)
self.drawGeoPoints(painter)
# -- 画面更新 (AppのタイミングでpaintEventが呼ばれる) ---
self.update()
def paintEvent(self, *args, **kwargs):
# -- おまじない ---------------------------
painter = QStylePainter(self) # QPainterを生成
painter.setRenderHint(QPainter.Antialiasing, True) # アンチエイリアス
painter.drawPixmap(0, 0, self.pixmap) # QPainterでバッファに準備したデータを描画
# 描画用QPenのデフォルト
pen_default = QPen()
pen_default.setColor(Qt.black)
pen_default.setWidth(2)
painter.setPen(pen_default)
brush_default = QBrush(Qt.red, Qt.NoBrush)
painter.setBrush(brush_default)
# -- アクセス用定数 -----------------------
x, y = 0, 1
# -- 車両の位置情報を取得 -----------------
pos = self.locateXY([self.STAGE_WIDTH / 2., self.STAGE_HEIGHT / 2.])
# -- 車両位置のプロット -------------------
pen = QPen(Qt.red, 5)
painter.setPen(pen)
painter.drawPoint(pos[x], pos[y])
# -- 車両位置に 円を描画 -----------------------------
pen = QPen(Qt.black, 1, Qt.DotLine, Qt.RoundCap, Qt.RoundJoin)
painter.setPen(pen)
painter.setBrush(QBrush(QColor(0, 255, 0, 175)))
circle_size = 50
painter.drawEllipse(pos[x] - circle_size / 2, pos[y] - circle_size / 2, circle_size, circle_size)
# -- 車両位置に四角を描画 -----------------------------
pen = QPen(Qt.black, 1, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)
painter.setPen(pen)
painter.setBrush(QBrush(QColor(0, 255, 0, 255), Qt.NoBrush))
painter.drawRect(pos[x] - circle_size / 2, pos[y] - circle_size / 2, circle_size, circle_size)
# qpoints = [QPoint(*lv) for lv in v]
# polygon = QPolygon(qpoints)
# painter.drawPolygon(polygon)
# -- 進行方向(速度ベクトル)を描画 ---------
pen = QPen(Qt.gray, 1, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)
painter.setPen(pen)
painter.drawLine(pos[x], pos[y], (pos[x] + 50), (pos[y] + 50))
# -- 棒グラフを表示 -------------------------
r = QRect(0, 0, 20, 30)
r.setHeight(200)
p0 = self.locateXY([20, 20], 'qp')
r.moveBottomLeft(p0)
painter.setBrush(QBrush(Qt.green, Qt.Dense4Pattern))
painter.drawRect(r)
# ************************************************************* #
# 描画系補助関数
# ************************************************************* #
def drawDebugLog(self, painter):
pass
def drawGrid(self, painter):
""" マップを表示する関数
"""
# -- 定数 ---------------------------------------
Nx = 10
Ny = 10
Lx = self.STAGE_WIDTH
Ly = self.STAGE_HEIGHT
# -- 線の色と種類の選定 --------------------------
painter.setPen(QPen(Qt.black, 0.5))
painter.setBrush(QBrush(QColor(200, 200, 200, 150), Qt.Dense1Pattern))
# -- 横線を描画 ----------------------------------
for xi in range(Nx + 1):
p1 = self.locateXY([xi * Lx / Nx, 0], 'qp')
p2 = self.locateXY([xi * Lx / Nx, Ly], 'qp')
painter.drawLine(p1, p2)
# -- 縦線を描画 ----------------------------------
for yi in range(Ny + 1):
p1 = self.locateXY([0, yi * Ly / Ny], 'qp')
p2 = self.locateXY([Lx, yi * Ly / Ny], 'qp')
painter.drawLine(p1, p2)
def locateXY(self, pos, type='np'):
"""
オブジェクトのローカル座標を、スクリーン上の座標へ変換
"""
_pos = np.asarray(pos)
local_x, local_y = _pos.copy()
srn_x = local_x + self.MARGIN_WIDTH
srn_y = (self.SCREEN_HEIGHT - local_y - self.MARGIN_HEIGHT)
if type is 'np':
return np.asarray([srn_x, srn_y])
elif type is 'qp':
return QPoint(srn_x, srn_y)
elif type is 'qpF':
return QPointF(srn_x, srn_y)
elif type is 'list':
return [srn_x, srn_y]
return 'ERROR:: check type option'
def locateVec(self, vec, type='np'):
"""
オブジェクトのベクトルを、スクリーン上の座標空間へ変換
(※yを反転させるだけ)
"""
srn_vec = [vec[0], -1 * vec[1]]
if type is 'np':
return np.asarray(srn_vec)
elif type is 'qp':
return QPoint(*srn_vec)
elif type is 'qpF':
return QPointF(*srn_vec)
elif type is 'list':
return srn_vec
return 'ERROR:: check type option'
# ************************************************************* #
# その他Qt関連補助関数
# ************************************************************* #
def refreshPixmap(self):
"""
画面バッファの初期化関数
"""
# 画面バッファの初期化
self.pixmap = QPixmap(self.size())
# 画面を塗りつぶし (おまじない)
self.pixmap.fill(self, 0, 0)
self.pixmap.fill(Qt.white)
# ぺインターの生成 (おまじない)
painter = QPainter(self.pixmap)
# ぺインターによる初期化 (おまじない)
painter.initFrom(self)
pass
def sizeHint(self):
return QSize(self.SCREEN_WIDTH, self.SCREEN_HEIGHT)
def keyPressEvent(self, event):
e = event.key()
if e == Qt.Key_Up:
pass
elif e == Qt.Key_Down:
pass
elif e == Qt.Key_Left:
pass
elif e == Qt.Key_Right:
pass
elif e == Qt.Key_Plus:
pass
elif e == Qt.Key_Minus:
pass
elif e == Qt.Key_Q:
self.close()
else:
pass
print 'Presskey', e
self.update()
# *******************************************************
# main関数
# *******************************************************
def mainGUI():
app = QApplication(sys.argv)
win = GameWindow()
win.show()
sys.exit(app.exec_())
if __name__ == "__main__":
mainGUI()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment