flatcam/Utils/vispy_example.py

196 lines
6.3 KiB
Python

from PyQt5.QtGui import QPalette
from PyQt5 import QtCore, QtWidgets
import vispy.scene as scene
from vispy.scene.visuals import Rectangle, Text
from vispy.color import Color
import sys
class VisPyCanvas(scene.SceneCanvas):
def __init__(self, config=None):
super().__init__(config=config, keys=None)
self.unfreeze()
# Colors used by the Scene
theme_color = Color('#FFFFFF')
tick_color = Color('#000000')
back_color = str(QPalette().color(QPalette.Window).name())
# Central Widget Colors
self.central_widget.bgcolor = back_color
self.central_widget.border_color = back_color
self.grid_widget = self.central_widget.add_grid(margin=10)
self.grid_widget.spacing = 0
# TOP Padding
top_padding = self.grid_widget.add_widget(row=0, col=0, col_span=2)
top_padding.height_max = 0
# RIGHT Padding
right_padding = self.grid_widget.add_widget(row=0, col=2, row_span=2)
right_padding.width_max = 0
# X Axis
self.xaxis = scene.AxisWidget(
orientation='bottom', axis_color=tick_color, text_color=tick_color,
font_size=8, axis_width=1,
anchors=['center', 'bottom']
)
self.xaxis.height_max = 30
self.grid_widget.add_widget(self.xaxis, row=2, col=1)
# Y Axis
self.yaxis = scene.AxisWidget(
orientation='left', axis_color=tick_color, text_color=tick_color,
font_size=8, axis_width=1
)
self.yaxis.width_max = 55
self.grid_widget.add_widget(self.yaxis, row=1, col=0)
# View & Camera
self.view = self.grid_widget.add_view(row=1, col=1, border_color=tick_color,
bgcolor=theme_color)
self.view.camera = scene.PanZoomCamera(aspect=1, rect=(-25, -25, 150, 150))
self.xaxis.link_view(self.view)
self.yaxis.link_view(self.view)
self.grid = scene.GridLines(parent=self.view.scene, color='dimgray')
self.grid.set_gl_state(depth_test=False)
self.rect = Rectangle(center=(65,30), color=Color('#0000FF10'), border_color=Color('#0000FF10'),
width=120, height=50, radius=[5, 5, 5, 5], parent=self.view)
self.rect.set_gl_state(depth_test=False)
self.text = Text('', parent=self.view, color='black', pos=(5, 30), method='gpu', anchor_x='left')
self.text.font_size = 8
self.text.text = 'Coordinates:\nX: %s\nY: %s' % ('0.0000', '0.0000')
self.freeze()
# self.measure_fps()
class PlotCanvas(QtCore.QObject):
def __init__(self, container, my_app):
"""
The constructor configures the VisPy figure that
will contain all plots, creates the base axes and connects
events to the plotting area.
:param container: The parent container in which to draw plots.
:rtype: PlotCanvas
"""
super().__init__()
# VisPyCanvas instance
self.vispy_canvas = VisPyCanvas()
self.vispy_canvas.unfreeze()
self.my_app = my_app
# Parent container
self.container = container
# <VisPyCanvas>
self.vispy_canvas.create_native()
self.vispy_canvas.native.setParent(self.my_app.ui)
# <QtCore.QObject>
self.container.addWidget(self.vispy_canvas.native)
# add two Infinite Lines to act as markers for the X,Y axis
self.v_line = scene.visuals.InfiniteLine(
pos=0, color=(0.0, 0.0, 1.0, 0.3), vertical=True,
parent=self.vispy_canvas.view.scene)
self.h_line = scene.visuals.InfiniteLine(
pos=0, color=(0.00, 0.0, 1.0, 0.3), vertical=False,
parent=self.vispy_canvas.view.scene)
self.vispy_canvas.freeze()
def event_connect(self, event, callback):
getattr(self.vispy_canvas.events, event).connect(callback)
def event_disconnect(self, event, callback):
getattr(self.vispy_canvas.events, event).disconnect(callback)
def translate_coords(self, pos):
"""
Translate pixels to canvas units.
"""
tr = self.vispy_canvas.grid.get_transform('canvas', 'visual')
return tr.map(pos)
class MyGui(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("VisPy Test")
# add Menubar
self.menu = self.menuBar()
self.menufile = self.menu.addMenu("File")
self.menuedit = self.menu.addMenu("Edit")
self.menufhelp = self.menu.addMenu("Help")
# add a Toolbar
self.file_toolbar = QtWidgets.QToolBar("File Toolbar")
self.addToolBar(self.file_toolbar)
self.button = self.file_toolbar.addAction("Open")
# add Central Widget
self.c_widget = QtWidgets.QWidget()
self.central_layout = QtWidgets.QVBoxLayout()
self.c_widget.setLayout(self.central_layout)
self.setCentralWidget(self.c_widget)
# add InfoBar
# self.infobar = self.statusBar()
# self.position_label = QtWidgets.QLabel("Position: X: 0.0000\tY: 0.0000")
# self.infobar.addWidget(self.position_label)
class MyApp(QtCore.QObject):
def __init__(self):
super().__init__()
self.ui = MyGui()
self.plot = PlotCanvas(container=self.ui.central_layout, my_app=self)
self.ui.show()
self.plot.event_connect(event="mouse_move", callback=self.on_mouse_move)
def on_mouse_move(self, event):
cursor_pos = event.pos
pos_canvas = self.plot.translate_coords(cursor_pos)
# we don't need all the info in the tuple returned by the translate_coords()
# only first 2 elements
pos_canvas = [pos_canvas[0], pos_canvas[1]]
self.ui.position_label.setText("Position: X: %.4f\tY: %.4f" % (pos_canvas[0], pos_canvas[1]))
# pos_text = 'Coordinates: \nX: {:<7.4f}\nY: {:<7.4f}'.format(pos_canvas[0], pos_canvas[1])
pos_text = 'Coordinates: \nX: {:<.4f}\nY: {:<.4f}'.format(pos_canvas[0], pos_canvas[1])
self.plot.vispy_canvas.text.text = pos_text
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
m_app = MyApp()
sys.exit(app.exec_())