python - 如何让 matplotlib.Figure() 接受 Drop 事件来绘制数据?
问题描述
我正在设置一个启用拖放模式的QListWidget并使用一些数据的名称,我想将这些名称拖放到matplotlib.figure然后绘制它。
如何使 Figure() 接受 Drop 事件?
我正在使用库PyQt5 和 Matplotlib。
class Window(QDialog):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
# ...
self.parametersList = QListWidget()
self.parametersList.setDragDropMode(QAbstractItemView.DragDrop)
self.parametersList.setSelectionMode(QAbstractItemView.ExtendedSelection)
self.parametersList.setAcceptDrops(True)
# Right side of the screen
self.graphFigure = Figure()
self.graphCanvas = FigureCanvas(self.graphFigure)
self.toolbar = NavigationToolbar(self.graphCanvas, self)
self.ax = self.graphFigure.add_subplot(111)
self.ax.tick_params(axis='y', labelcolor='tab:red')
def enterDrop (self, data):
''' Something to pass data via Drop '''
self.ax.plot(data)
解决方案
FigureCanvas 是一个 QWidget,因此您必须实现拖放的 dragEnterEvent 和 dropEvent 方法。
import random
import string
from PyQt5 import QtCore, QtGui, QtWidgets
from matplotlib.backends.backend_qt5agg import (
FigureCanvasQTAgg as FigureCanvas,
NavigationToolbar2QT as NavigationToolbar,
)
from matplotlib.figure import Figure
import numpy as np
def random_string(string_length=10):
letter = string.ascii_lowercase
return "".join(random.sample(letter, string_length))
class DropCanvas(FigureCanvas):
def __init__(self, parent=None, width=5, height=4, dpi=100):
fig = Figure(figsize=(width, height), dpi=dpi)
FigureCanvas.__init__(self, fig)
self.setParent(parent)
self.setAcceptDrops(True)
self.axes = self.figure.add_subplot(111)
self.axes.tick_params(axis="y", labelcolor="tab:red")
t = np.arange(0.0, 5.0, 0.01)
y = 100 * np.exp(-t) * np.cos(2 * np.pi * t)
self.axes.plot(t, y)
def dragEnterEvent(self, event):
if event.mimeData().hasFormat(
"application/x-qabstractitemmodeldatalist"
):
event.acceptProposedAction()
def dropEvent(self, event):
if (
isinstance(event.source(), QtWidgets.QListView)
and event.possibleActions() & QtCore.Qt.CopyAction
):
monkey_model = QtGui.QStandardItemModel()
if monkey_model.dropMimeData(
event.mimeData(),
QtCore.Qt.CopyAction,
0,
0,
QtCore.QModelIndex(),
):
if (
monkey_model.rowCount() >= 1
and monkey_model.columnCount() >= 1
):
it = monkey_model.item(0, 0)
# get text
text = it.text()
p = event.pos()
width, height = self.get_width_height()
# In matplotlib, 0,0 is the lower left corner,
# whereas it's usually the upper
# right for most image software, so we'll flip the y-coords
x_pixel, y_pixel = p.x(), height - p.y()
x, y = self.axes.transData.inverted().transform(
(x_pixel, y_pixel)
)
self.axes.scatter(x, y)
self.axes.text(x, y, text, fontsize=12)
self.axes.figure.canvas.draw()
event.acceptProposedAction()
class Dialog(QtWidgets.QDialog):
def __init__(self, parent=None):
super(Dialog, self).__init__(parent)
list_widget = QtWidgets.QListWidget(
dragDropMode=QtWidgets.QAbstractItemView.DragOnly
)
for _ in range(10):
text = random_string()
it = QtWidgets.QListWidgetItem(text)
list_widget.addItem(text)
canvas = DropCanvas()
toolbar = NavigationToolbar(canvas, self)
hlay = QtWidgets.QHBoxLayout(self)
vlay = QtWidgets.QVBoxLayout()
hlay.addWidget(list_widget)
hlay.addLayout(vlay)
vlay.addWidget(toolbar)
vlay.addWidget(canvas)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = Dialog()
w.show()
sys.exit(app.exec_())
推荐阅读
- laravel - Laravel 类在 config:clear 后未定义
- java - 关于最后一封带有 getSubject().contains 的电子邮件的 IMAP 问题
- c++ - 为什么会出现分段错误?
- stata - 如何在 coefplot 中添加阴影区域和线段?
- android - Kotlin - 通用类型安全,错误警告?java.lang.ClassCastException
- ios - Selector 方法必须与观察者所在的实例相同吗?
- hadoop - “WARN hdfs.DFSUtil: Namenode for null 对于 ID null 仍未解决。”
- amazon-web-services - AWS SQS - 队列消费者数量与传输中消息数量之间的关系
- sap - 动态隐藏 Adobe Form 中的徽标?
- android - 如何在editText上放置单选按钮