在 Matplotlib 画布上正确放置 Qmenu
Posted
技术标签:
【中文标题】在 Matplotlib 画布上正确放置 Qmenu【英文标题】:Correctly placing Qmenu on Matplotlib Canvas 【发布时间】:2015-02-06 06:43:08 【问题描述】:当用户通过“button_press_event”点击画布时,我正在使用 QMenu 创建上下文菜单。但是,我在弄清楚如何将按钮按下事件的 x/y 坐标转换为正确的格式以便正确放置 Qmenu 时遇到了一些麻烦。
下面的代码可以工作,但是确定菜单位置的部分看起来有点难看,我想知道是否有更好的方法来放置 Qmenu。特别是我必须从画布高度中减去 Y 坐标的地方。这可以在某处用反转方法代替吗?
确定位置:
canvasSize = event.canvas.geometry()
Qpoint_click = event.canvas.mapToGlobal(QtCore.QPoint(event.x,canvasSize.height()-event.y))
完整代码:
import sys
from PyQt4 import QtGui, QtCore
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar
class menuTest(QtGui.QMainWindow):
def __init__(self):
super(menuTest, self).__init__()
self.mplFig = MplGrapher() #Matplotlib plot
self.mplFig.canvas.mpl_connect('button_press_event', self.on_press)
self.setCentralWidget(self.mplFig)
self.show()
def on_press(self,event):
canvasSize = event.canvas.geometry()
Qpoint_click = event.canvas.mapToGlobal(QtCore.QPoint(event.x,canvasSize.height()-event.y))
self.lineMenu= QtGui.QMenu()
self.lineMenu.addAction("Test Menu")
self.lineMenu.move(Qpoint_click)
self.lineMenu.show()
class MplGrapher(QtGui.QWidget):
def __init__(self,parent=None):
super(MplGrapher, self).__init__(parent)
self.initFigure()
def initFigure(self):
self.figure = Figure()
self.canvas = FigureCanvas(self.figure)
self.axL = self.figure.add_subplot(111)
self.axL.grid(True)
self.navbar = NavigationToolbar(self.canvas, self)
self.layout = QtGui.QVBoxLayout()
self.layout.addWidget(self.navbar)
self.layout.addWidget(self.canvas)
self.setLayout(self.layout)
def main():
app = QtGui.QApplication(sys.argv)
ex = menuTest()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
【问题讨论】:
【参考方案1】:请参阅出色的 matplotlib 转换教程 http://matplotlib.org/users/transforms_tutorial.html 了解转换的说明。像这样的东西对我来说很好:
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
class menuTest(QtGui.QMainWindow):
def __init__(self):
#....
self.figure = plt.figure()
self.canvas = FigureCanvas(self.figure)
self.canvasMenu = QtGui.QMenu(self)
ca = QtGui.QAction('Menu item', self)
ca.triggered.connect(self.menu_item_clicked)
self.canvasMenu.addAction(ca)
self.last_point = None
self.canvas.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.canvas.customContextMenuRequested.connect(self.exec_canvas_menu)
def exec_canvas_menu(self):
self.last_point = point
self.canvasMenu.exec_(self.canvas.mapToGlobal(point))
def menu_item_clicked(self):
if self.last_point is None: return
ax = self.figure.gca()
print ("Clicked at:", ax.transData.inverted().transform((self.last_point.x(), self.last_point.y())))
【讨论】:
以上是关于在 Matplotlib 画布上正确放置 Qmenu的主要内容,如果未能解决你的问题,请参考以下文章
我想用matplotlib在一个画布上写一些图表,使用pyqt5