Почему графический интерфейс pyside6 сбивается с графическим интерфейсом после того, как сделал несколько вызовов в matpPython

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Почему графический интерфейс pyside6 сбивается с графическим интерфейсом после того, как сделал несколько вызовов в matp

Сообщение Anonymous »

Я был бы очень благодарен за вашу помощь в объяснении того, почему этот графический интерфейс Pyside6 вылетает при выполнении нескольких вызовов в метод Matplotlib flush_events () в быстрой последовательности. Минимальный воспроизводимый код предоставляется в нижней части этого вопроса. В приложении ниже приложений я создаю два Canvase Figues с использованием класса Matplotlib с использованием класса FigureCanvasqtagg (и qt5agg бэкэнд) и отображайте их в QApplication pyside6 .
Затем я подключаю метод (mouse_moved_in_canvas()) к matplotlib motion_notify_event для Canvas 1. Если мышь колеблется в осях холста 1, mouse_moved_in_canvas на графике прямой линии, которая проходит через мышь на Canvas 1, и копия Строка на холсте. Блайтинг управляется через экземпляры класса BlitManager , скопируемый и вставлен из учебника Blitting Matplotlib без модификаций. Важно отметить, что этот класс включает в себя призыв к canvas.flush_events () , который, по -видимому, вызывает поведение сбоя. Медленно перемещается по осям холста. Следующее сообщение напечатано в моем терминале в Pycharm Community Edition: < /p>
Process finished with exit code -1073741571 (0xC00000FD)

В этом сообщении на форуме говорится, что код 0xc00000fd - это «переполнение стека». > s, который каждый вызывает метод mouse_mov_in_canvas , который вызывает метод обновления обоих экземпляров Blitmanager , и, наконец, Canvas.flush_events () метод обоих mplcanvas экземпляры.
Это сбоевое поведение надежно предотвращено, когда вызов CV.Flush_events () в методе обновления BlitManager класса комментируется. Никакое количество или продолжительность быстрого движения мыши в осях холста 1, по -видимому, не вызывает сбоя.
Удаление вызова в CV.flush_events , похоже, не влияет на производительность приложение любым другим заметным способом. < /p>
Таким образом, я задаю два вопроса: < /p>

(заголовок) почему Разрут ли графический интерфейс pyside6 после того, как сделал несколько вызовов в matplotlib flush_events () в быстрой последовательности? в обновлении метод класса Blitmanager ? Чтобы быть зависимым от бэкэнд, и я не могу найти исходный код для бэкэнда qt5agg , который я использую. Комментарий выше вызов к CV.Flush_events в классе BlitManager говорит: «Пусть цикл графического интерфейса обрабатывает все, что ему нужно сделать». Я обеспокоен тем, что удаление Call The Cv.flush_events вызовет другие проблемы. Можно ли это снять безопасно, или есть альтернативное решение проблемы сбоя? < /Li>
< /ul>
< /li>
< /ol>
< P> Большое спасибо за ваше время и помощь. < /p>
Информация о версии: < /p>

Python 3.13 < /li>
matplotlib 3.10.0 < /li>
pyside6 6.8.2.1 < /li>
pycharm 2024.3.2 (Edition Edition) < /li> Windows 11 Home 23h2 < /li>
< /ul>
Минимальный воспроизводимый код: < /p>
import sys
from PySide6.QtWidgets import QApplication, QMainWindow, QHBoxLayout, QWidget
import matplotlib
matplotlib.use('Qt5Agg')
from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg
from matplotlib.figure import Figure
import numpy as np

class MplCanvas(FigureCanvasQTAgg):
def __init__(self, parent=None, width=5, height=4, dpi=100):
self.fig = Figure(figsize=(width, height), dpi=dpi, layout="constrained")
self.ax = self.fig.add_subplot(1, 1, 1)
super(MplCanvas, self).__init__(self.fig)

self.setParent(parent)

class BlitManager:
def __init__(self, canvas, animated_artists=()):
"""
Parameters
----------
canvas : FigureCanvasAgg
The canvas to work with, this only works for subclasses of the Agg
canvas which have the `~FigureCanvasAgg.copy_from_bbox` and
`~FigureCanvasAgg.restore_region` methods.

animated_artists : Iterable[Artist]
List of the artists to manage
"""
self.canvas = canvas
self._bg = None
self._artists = []

for a in animated_artists:
self.add_artist(a)
# grab the background on every draw
self.cid = canvas.mpl_connect("draw_event", self.on_draw)

def on_draw(self, event):
"""Callback to register with 'draw_event'."""
cv = self.canvas
if event is not None:
if event.canvas != cv:
raise RuntimeError
self._bg = cv.copy_from_bbox(cv.figure.bbox)
self._draw_animated()

def add_artist(self, art):
"""
Add an artist to be managed.

Parameters
----------
art : Artist

The artist to be added. Will be set to 'animated' (just
to be safe). *art* must be in the figure associated with
the canvas this class is managing.

"""
if art.figure != self.canvas.figure:
raise RuntimeError
art.set_animated(True)
self._artists.append(art)

def _draw_animated(self):
"""Draw all of the animated artists."""
fig = self.canvas.figure
for a in self._artists:
fig.draw_artist(a)

def update(self):
"""Update the screen with animated artists."""
cv = self.canvas
fig = cv.figure
# paranoia in case we missed the draw event,
if self._bg is None:
self.on_draw(None)
else:
# restore the background
cv.restore_region(self._bg)
# draw all of the animated artists
self._draw_animated()
# update the GUI state
cv.blit(fig.bbox)
# let the GUI event loop process anything it has to do
cv.flush_events()

class MyMainWindow(QMainWindow):
def __init__(self):
super().__init__()

# Add two instances of a Matplotlib canvas:
mpl_canvas_1 = MplCanvas()
mpl_canvas_2 = MplCanvas()

# Label the plots:
mpl_canvas_1.ax.set_title('Canvas 1')
mpl_canvas_2.ax.set_title('Canvas 2')

# On each canvas, create a line plot with fixed x data and y data initially set to all zeros:
n_points = 3
self.x_data = np.linspace(0, 100, n_points)
y_data_initial = np.zeros(n_points)
self.line1, = mpl_canvas_1.ax.plot(self.x_data, y_data_initial)
self.line2, = mpl_canvas_2.ax.plot(self.x_data, y_data_initial)

# Adjust the axes limits:
mpl_canvas_1.ax.set_xlim(0, 100)
mpl_canvas_1.ax.set_ylim(0, 100)
mpl_canvas_2.ax.set_xlim(0, 100)
mpl_canvas_2.ax.set_ylim(0, 100)

# For each canvas, create an instance of the BlitManager class to manage blitting:
self.blit_manager_1 = BlitManager(mpl_canvas_1, [self.line1])
self.blit_manager_2 = BlitManager(mpl_canvas_2, [self.line2])

# Create a horizontal layout:
h_layout = QHBoxLayout()
# Add the Mpl canvases:
h_layout.addWidget(mpl_canvas_1)
h_layout.addWidget(mpl_canvas_2)

# Create a widget to hold the layout:
widget = QWidget()
widget.setLayout(h_layout)

self.setCentralWidget(widget)

# Connect the matplotlib 'motion_notify_event' to the mouse_moved_in_canvas method:
mpl_canvas_1.fig.canvas.mpl_connect('motion_notify_event', self.mouse_moved_in_canvas)

def mouse_moved_in_canvas(self, event):
if event.inaxes:
# Mouse is in data axes.
# Get data co-ordinates of cursor:
x_hover = event.xdata
y_hover = event.ydata

# Draw line passing through zero and hover point:
# Compute y values for fixed x vector:
gradient = y_hover / x_hover
y_vector = gradient * self.x_data

# Set ydata for lines:
self.line1.set_ydata(y_vector)
self.line2.set_ydata(y_vector)

# Blit changes:
self.blit_manager_1.update()
self.blit_manager_2.update()

app = QApplication(sys.argv)
app.setStyle('Fusion')
window = MyMainWindow()
window.show()
app.exec()



Подробнее здесь: https://stackoverflow.com/questions/794 ... -flush-eve
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»