Как обновить окно в PyQt
Есть небольшая программа, которая считывает показания с датчиков и отображает коды датчиков в QListWidgets. Затем при нажатии на пункт в этом списке строит его график в этом же окне (пример на картинке)
После нажатия на другой пункт QListWidgets, график должен быть перерисован, но он не перерисовывается до тех пор пока не обновлю размер окна, а методы update, repaint не приносят никакого результата. В чем может быть ошибка?
class MyWindow(QtWidgets.QWidget):
def __init__(self, parent = None):
QtWidgets.QWidget.__init__(self,parent)
self.detectorList = DetectorList()
self.filesNames = None
self.resize(1200,600)
mainBox = QtWidgets.QHBoxLayout()
dataBox = QtWidgets.QVBoxLayout()
self.btnOpenFile = QtWidgets.QPushButton('Выбор файла')
self.btnOpenFile.clicked.connect(self.on_clicked_open_file)
self.kksView = QtWidgets.QListWidget()
self.kksView.installEventFilter(self)
self.kksView.clicked.connect(self.on_draw_line)
dataBox.addWidget(self.btnOpenFile)
dataBox.addWidget(self.kksView)
#MPL для рисования графика
self.canvas = Canvas(self)
mainBox.addLayout(dataBox, stretch=1)
mainBox.addWidget(self.canvas,stretch=2)
self.setLayout(mainBox)
self.show()
def on_clicked_open_file(self):
'''Выбор файлов'''
self.filesNames = QtWidgets.QFileDialog.getOpenFileNames(self, 'Open files')[0]
if self.filesNames:
print('readFiles', self.filesNames)
self.kksView.clear()
self.detectorList.read_files(self.filesNames)
self.kksView.addItems(self.detectorList.get_all_kks())
print('readFiles finished', self.filesNames)
@QtCore.pyqtSlot()
def on_draw_line(self):
index = self.kksView.currentIndex()
kks = self.kksView.model().data(index)
detector = self.detectorList.get_detector(kks)
dateList = np.array(detector.get_date())
indicationList = np.array(detector.get_indication())
self.canvas.clear_plot()
self.canvas.add_plot(dateList,indicationList)
#это работает
#self.resize(self.window().width()-1,self.window().height()-1)
self.canvas.update()
self.update()
self.window().update()
self.window().repaint()
def eventFilter(self, source:QtWidgets.QListWidget, event:QtGui.QHideEvent):
'''обработка событий при клике на listview'''
if (event.type() == QtCore.QEvent.ContextMenu and source is self.kksView):
menu = QtWidgets.QMenu()
menu.addAction('Draw graph', self.on_draw_graph)
menu.addAction('Close window', QtWidgets.qApp.quit)
if menu.exec_(event.globalPos()):
item:QtWidgets.QListWidgetItem = source.itemAt(event.pos())
return super(MyWindow,self).eventFilter(source,event)
@QtCore.pyqtSlot()
def on_draw_graph(self):
index = self.kksView.currentIndex()
kks = self.kksView.model().data(index)
print(kks)
kksList = [kks]
detectors = self.detectorList.get_detectors(kksList)
draw_plot(detectors)
class Canvas(FigureCanvas):
def __init__(self, parent = None, width = 5, height = 5, dpi = 100):
self.fig = Figure(figsize=(width,height), dpi = dpi)
self.ax = self.fig.add_subplot()
FigureCanvas.__init__(self, self.fig)
self.setParent(parent)
self.add_plot()
def add_plot(self,x=[],y=[]):
self.ax.plot(x,y)
def clear_plot(self):
self.ax.clear()
Ответы (1 шт):
Автор решения: S. Nick
→ Ссылка
Вы предоставили не воспроизводимый пример. На маленьком своем примере, попробую продемонстрировать как это обычно делается:
- создаем объект
self.canvas = FigureCanvas(self.fig) - вставляем в макет
layout.addWidget(self.canvas, 0, 1, 6, 1) - когда нам нужно что-то нарисовать/перерисовать , вызываем метод
_update_canvas. У меня обновляется по событию таймера, вам нужно вызвать этот метод по нажатию на элементQListWidget.
import sys
import time
from PyQt5 import QtCore, QtGui, QtWidgets
from matplotlib.figure import Figure
import numpy as np
from matplotlib.backends.backend_qt5agg import FigureCanvas
class ApplicationWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self._main = QtWidgets.QWidget()
self.setCentralWidget(self._main)
self.btnOpenFile = QtWidgets.QPushButton('Выбор файла')
self.kksView = QtWidgets.QListWidget()
self.kksView.addItems(['item1', 'item2', 'item3', 'item4', 'item5', ])
self.fig = Figure()
self.canvas = FigureCanvas(self.fig)
layout = QtWidgets.QGridLayout(self._main)
layout.addWidget(self.btnOpenFile, 0, 0, 1, 1)
layout.addWidget(self.canvas, 0, 1, 6, 1)
layout.addWidget(self.kksView, 1, 0, 5, 1)
self._ax = self.fig.subplots()
self._timer = self.canvas.new_timer(
100, [(self._update_canvas, (), {})])
self._timer.start()
def _update_canvas(self):
self._ax.clear()
t = np.linspace(0, 10, 101)
self._ax.plot(t, np.sin(t + time.time()))
self.canvas.draw()
if __name__ == "__main__":
qapp = QtWidgets.QApplication(sys.argv)
app = ApplicationWindow()
app.show()
qapp.exec_()

