Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# -*- coding: utf-8 -*-
"""
Demonstrates adding a custom context menu to a GraphicsItem
and extending the context menu of a ViewBox.
PyQtGraph implements a system that allows each item in a scene to implement its
own context menu, and for the menus of its parent items to be automatically
displayed as well.
"""
import initExample ## Add path to library (just for examples; you do not need this)
import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
import numpy as np
win = pg.GraphicsWindow()
win.setWindowTitle('pyqtgraph example: context menu')
view = win.addViewBox()
# add two new actions to the ViewBox context menu:
zoom1 = view.menu.addAction('Zoom to box 1')
zoom2 = view.menu.addAction('Zoom to box 2')
# define callbacks for these actions
def zoomTo1():
# note that box1 is defined below
view.autoRange(items=[box1])
zoom1.triggered.connect(zoomTo1)
def zoomTo2():
# note that box1 is defined below
view.autoRange(items=[box2])
zoom2.triggered.connect(zoomTo2)
class MenuBox(pg.GraphicsObject):
"""
This class draws a rectangular area. Right-clicking inside the area will
raise a custom context menu which also includes the context menus of
its parents.
"""
def __init__(self, name):
self.name = name
self.pen = pg.mkPen('r')
# menu creation is deferred because it is expensive and often
# the user will never see the menu anyway.
self.menu = None
# note that the use of super() is often avoided because Qt does not
# allow to inherit from multiple QObject subclasses.
pg.GraphicsObject.__init__(self)
# All graphics items must have paint() and boundingRect() defined.
def boundingRect(self):
return QtCore.QRectF(0, 0, 10, 10)
def paint(self, p, *args):
p.setPen(self.pen)
p.drawRect(self.boundingRect())
# On right-click, raise the context menu
def mouseClickEvent(self, ev):
if ev.button() == QtCore.Qt.RightButton:
if self.raiseContextMenu(ev):
ev.accept()
def raiseContextMenu(self, ev):
menu = self.getContextMenus()
# Let the scene add on to the end of our context menu
# (this is optional)
menu = self.scene().addParentContextMenus(self, menu, ev)
pos = ev.screenPos()
menu.popup(QtCore.QPoint(pos.x(), pos.y()))
return True
# This method will be called when this item's _children_ want to raise
# a context menu that includes their parents' menus.
def getContextMenus(self, event=None):
if self.menu is None:
self.menu = QtGui.QMenu()
self.menu.setTitle(self.name+ " options..")
green = QtGui.QAction("Turn green", self.menu)
green.triggered.connect(self.setGreen)
self.menu.addAction(green)
self.menu.green = green
blue = QtGui.QAction("Turn blue", self.menu)
blue.triggered.connect(self.setBlue)
self.menu.addAction(blue)
self.menu.green = blue
alpha = QtGui.QWidgetAction(self.menu)
alphaSlider = QtGui.QSlider()
alphaSlider.setOrientation(QtCore.Qt.Horizontal)
alphaSlider.setMaximum(255)
alphaSlider.setValue(255)
alphaSlider.valueChanged.connect(self.setAlpha)
alpha.setDefaultWidget(alphaSlider)
self.menu.addAction(alpha)
self.menu.alpha = alpha
self.menu.alphaSlider = alphaSlider
return self.menu
# Define context menu callbacks
def setGreen(self):
self.pen = pg.mkPen('g')
# inform Qt that this item must be redrawn.
self.update()
def setBlue(self):
self.pen = pg.mkPen('b')
self.update()
def setAlpha(self, a):
self.setOpacity(a/255.)
# This box's context menu will include the ViewBox's menu
box1 = MenuBox("Menu Box #1")
view.addItem(box1)
# This box's context menu will include both the ViewBox's menu and box1's menu
box2 = MenuBox("Menu Box #2")
box2.setParentItem(box1)
box2.setPos(5, 5)
box2.scale(0.2, 0.2)
## Start Qt event loop unless running in interactive mode or using pyside.
if __name__ == '__main__':
import sys
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
QtGui.QApplication.instance().exec_()