我正在设置 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)
答案 0 :(得分:1)
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_())