gpt4 book ai didi

python - matplotlib 事件监听器在 PyQT 小部件中不起作用

转载 作者:太空宇宙 更新时间:2023-11-03 14:55:50 24 4
gpt4 key购买 nike

我有一个可拖动的 matplotlib 对象库,我正尝试将其与 PyQt5 GUI 一起使用。对象的 event listeners在独立的 matplotlib 图形窗口中正常运行,但在图形嵌入 QT 小部件时不起作用。两个图都正确呈现,并且当我尝试在 QT 小部件中拖动补丁时没有错误消息。

对象 MCVE:

import matplotlib.patches as patches

class _DragObj:
def __init__(self, ax):
self.parentcanvas = ax.figure.canvas
self.parentax = ax

self.clickpress = self.parentcanvas.mpl_connect('button_press_event', self.on_click)
self.clicked = False

def on_click(self, event):
if event.inaxes != self.parentax: return

self.mousemotion = self.parentcanvas.mpl_connect('motion_notify_event', self.on_motion)
self.clickrelease = self.parentcanvas.mpl_connect('button_release_event', self.on_release)

self.clickx = event.xdata
self.clicky = event.ydata

self.clicked = True

def on_release(self, event):
self.clicked = False
self.disconnect()

def disconnect(self):
self.parentcanvas.mpl_disconnect(self.mousemotion)
self.parentcanvas.mpl_disconnect(self.clickrelease)
self.parentcanvas.draw()

def stopdrag(self):
self.myobj.set_url('')
self.parentcanvas.mpl_disconnect(self.clickpress)

class _DragPatch(_DragObj):
def __init__(self, ax, xy):
super().__init__(ax)

self.oldxy = xy

def on_motion(self, event):
if not self.clicked: return
if event.inaxes != self.parentax: return

oldx, oldy = self.oldxy
dx = event.xdata - self.clickx
dy = event.ydata - self.clicky
newxy = [oldx + dx, oldy + dy]
self.myobj.xy = newxy

self.parentcanvas.draw()

def on_release(self, event):
self.clicked = False
self.oldxy = self.myobj.xy

self.disconnect()

class DragRectangle(_DragPatch):
def __init__(self, ax, xy, width, height, angle=0.0, **kwargs):
self.myobj = patches.Rectangle(xy, width, height, angle, **kwargs)
ax.add_artist(self.myobj)

super().__init__(ax, xy)

功能性 matplotlib 示例:

import minidrag
import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111)
rect = minidrag.DragRectangle(ax, (0, 0), 2, 1)

ax.set_xlim(-5, 5)
ax.set_ylim(-5, 5)

plt.show()

非功能性 PyQT 示例:

import sys
from PyQt5 import QtWidgets as QtW
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure
import minidrag

class windowGUI(QtW.QDialog):
def __init__(self):
super().__init__()

# Set up figure
width_px = 800
height_px = 600

rect = QtW.QDesktopWidget().availableGeometry()
screenrez = (rect.width(), rect.height())
left_px = (screenrez[0] - width_px)/2
top_px = (screenrez[1] - height_px)/2
self.setGeometry(left_px, top_px, width_px, height_px)
self.canvas = PlotCanvas()

layout = QtW.QVBoxLayout()
layout.addWidget(NavigationToolbar(self.canvas, self))
layout.addWidget(self.canvas)
self.setLayout(layout)

class PlotCanvas(FigureCanvas):
def __init__(self):
fig = Figure(frameon=False)
super().__init__(fig)
super().setSizePolicy(QtW.QSizePolicy.Expanding, QtW.QSizePolicy.Expanding)
super().updateGeometry()

ax = fig.add_subplot(111)
rect = minidrag.DragRectangle(ax, (0, 0), 2, 1)

ax.set_xlim(-5, 5)
ax.set_ylim(-5, 5)

app = QtW.QApplication(sys.argv)
window = windowGUI()
window.show()
sys.exit(app.exec_())

我正在使用 Python 3.6.0、matplotlib (2.0.0) 和 PyQt5 (5.8)

我错过了什么?

最佳答案

事实证明,问题不在于拖动事件,而在于您的 minidrag.DragRectangle 实例正在被垃圾回收(而 Canvas 仍然在其原始位置显示矩形)。

作为修复,您可以将矩形设置为实例变量:

self.rect = minidrag.DragRectangle(ax, (0, 0), 2, 1)

(使用 Python2.7 和 PyQt4 测试。)

关于python - matplotlib 事件监听器在 PyQT 小部件中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42650119/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com