103 lines
2.6 KiB
Python
103 lines
2.6 KiB
Python
from math import hypot
|
|
from ..Qt import QtGui, QtCore, mkQApp
|
|
|
|
|
|
__all__ = ['JoystickButton']
|
|
|
|
class JoystickButton(QtGui.QPushButton):
|
|
sigStateChanged = QtCore.Signal(object, object) ## self, state
|
|
|
|
def __init__(self, parent=None):
|
|
QtGui.QPushButton.__init__(self, parent)
|
|
self.radius = 200
|
|
self.setCheckable(True)
|
|
self.state = None
|
|
self.setState(0, 0)
|
|
self.setFixedWidth(50)
|
|
self.setFixedHeight(50)
|
|
|
|
|
|
def mousePressEvent(self, ev):
|
|
self.setChecked(True)
|
|
lpos = ev.position() if hasattr(ev, 'position') else ev.localPos()
|
|
self.pressPos = lpos
|
|
ev.accept()
|
|
|
|
def mouseMoveEvent(self, ev):
|
|
lpos = ev.position() if hasattr(ev, 'position') else ev.localPos()
|
|
dif = lpos - self.pressPos
|
|
self.setState(dif.x(), -dif.y())
|
|
|
|
def mouseReleaseEvent(self, ev):
|
|
self.setChecked(False)
|
|
self.setState(0,0)
|
|
|
|
def wheelEvent(self, ev):
|
|
ev.accept()
|
|
|
|
|
|
def doubleClickEvent(self, ev):
|
|
ev.accept()
|
|
|
|
def getState(self):
|
|
return self.state
|
|
|
|
def setState(self, *xy):
|
|
xy = list(xy)
|
|
d = hypot(xy[0], xy[1]) # length
|
|
nxy = [0, 0]
|
|
for i in [0,1]:
|
|
if xy[i] == 0:
|
|
nxy[i] = 0
|
|
else:
|
|
nxy[i] = xy[i] / d
|
|
|
|
if d > self.radius:
|
|
d = self.radius
|
|
d = (d / self.radius) ** 2
|
|
xy = [nxy[0] * d, nxy[1] * d]
|
|
|
|
w2 = self.width() / 2
|
|
h2 = self.height() / 2
|
|
self.spotPos = QtCore.QPoint(
|
|
int(w2 * (1 + xy[0])),
|
|
int(h2 * (1 - xy[1]))
|
|
)
|
|
self.update()
|
|
if self.state == xy:
|
|
return
|
|
self.state = xy
|
|
self.sigStateChanged.emit(self, self.state)
|
|
|
|
def paintEvent(self, ev):
|
|
super().paintEvent(ev)
|
|
p = QtGui.QPainter(self)
|
|
p.setBrush(QtGui.QBrush(QtGui.QColor(0,0,0)))
|
|
p.drawEllipse(
|
|
self.spotPos.x() - 3,
|
|
self.spotPos.y() - 3,
|
|
6,
|
|
6
|
|
)
|
|
|
|
def resizeEvent(self, ev):
|
|
self.setState(*self.state)
|
|
super().resizeEvent(ev)
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
app = mkQApp()
|
|
w = QtGui.QMainWindow()
|
|
b = JoystickButton()
|
|
w.setCentralWidget(b)
|
|
w.show()
|
|
w.resize(100, 100)
|
|
|
|
def fn(b, s):
|
|
print("state changed:", s)
|
|
|
|
b.sigStateChanged.connect(fn)
|
|
|
|
app.exec() if hasattr(app, 'exec') else app.exec_()
|