Skip to content

Instantly share code, notes, and snippets.

@ShikouYamaue
Created January 16, 2018 13:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ShikouYamaue/5b9ecc23f03a5211eff7c4cae6249527 to your computer and use it in GitHub Desktop.
Save ShikouYamaue/5b9ecc23f03a5211eff7c4cae6249527 to your computer and use it in GitHub Desktop.
マウスジェスチャーでUIにインプットするサンプル
# -*- coding: utf-8 -*-
import math
import imp
try:
imp.find_module('PySide2')
from PySide2.QtWidgets import *
from PySide2.QtGui import *
from PySide2.QtCore import *
except ImportError:
from PySide.QtGui import *
from PySide.QtCore import *
from maya.app.general.mayaMixin import MayaQWidgetBaseMixin
class MainWindow(MayaQWidgetBaseMixin, QMainWindow):
number = 0#表示初期値
mouse_flag = False#マウスが押されているかどうか
threshold = 4#マウスの座標を取得する間隔
limit_angle = 120#マウスが反転したと判定する角度
def __init__(self, parent = None):
super(MainWindow, self).__init__(parent)
wrapper = QWidget()
self.setCentralWidget(wrapper)
layout = QVBoxLayout()
wrapper.setLayout(layout)
#入力確認用UI
self.lcd = QLCDNumber()
layout.addWidget(self.lcd)
self.lcd.display(self.number)
self.lcd.installEventFilter(self)
self.show()
def eventFilter(self, obj, event):
if event.type() == QEvent.MouseButtonPress:
self.first_move_flag = True
self.pre_pos = map(float, [QCursor.pos().x(), QCursor.pos().y()*-1])
self.pre_vec = [0, 1]
self.count = 0
self.mouse_flag = True
return True
if event.type() == QEvent.MouseButtonRelease:
self.mouse_flag = False
return True
if self.mouse_flag:
if event.type() == QEvent.MouseMove:
mod = event.modifiers()
#print 'ev mod', mod
if mod == Qt.ControlModifier:
key_mod = 'ctrl'#100刻み
elif mod == Qt.ShiftModifier:
key_mod = 'shift'#10きざみ
else:
key_mod = None
delta = self.mouse_vector()
if delta is not None:
if key_mod == 'ctrl':
delta *= 100
if key_mod == 'shift':
delta *= 10
self.number += delta
self.lcd.display(self.number)
return True
return False
#マウスの座標計算してぐるぐる入力
def mouse_vector(self):
#一定間隔ごとに計算
if self.count <= self.threshold:
self.count += 1
return None
else:
self.count = 0
self.cur_pos = map(float, [QCursor.pos().x(), QCursor.pos().y()*-1])
if self.cur_pos != self.pre_pos:
#現在のベクトルを求める
self.cur_vec = [self.cur_pos[0]-self.pre_pos[0], self.cur_pos[1]-self.pre_pos[1]]
#動き出しの符号を決定する
if self.first_move_flag:
self.operator = self.get_first_operator(self.cur_vec)
self.first_move_flag = False
#正規化して内積をとる
self.angle = self.culc_angle(self.cur_vec, self.pre_vec)
if self.angle >= self.limit_angle:
self.operator *= -1
self.pre_pos = self.cur_pos
self.pre_vec = self.cur_vec
return self.operator
return None
#符号反転を左右で一意に決める
def get_first_operator(self, a):
value = a[0]
if value > 0:
return 1.0
else:
return -1.0
#2つのベクトルの角度を算出
def culc_angle(self, a, b):
dot = self.dot_poduct(a, b, norm=True)
try:
rad = math.acos(dot)
except Exception as e:#逆コサインエラーの対処
print e.message
print 'Arc cos error : dot ', dot
dot = round(dot, 0)
rad = math.acos(dot)
angle = rad*180/math.pi#ラジアンを弧度法に変換
return angle
#内積とる
def dot_poduct(self, a, b, norm=False):
if norm:#正規化オプション
a = self.normalize(a)
b = self.normalize(b)
dot = (a[0]*b[0])+(a[1]*b[1])
return dot
#ベクトルを正規化して戻す
def normalize(self, a):
length = self.get_length(a)
return [a[0]/length, a[1]/length]
#長さを出す
def get_length(self, a):
return math.sqrt(a[0]**2+a[1]**2)
MainWindow()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment