Idea: I want to create a window with a plot that will be updated every 2 seconds. At the same time, you can perform other actions in the window (such as pressing buttons, etc.).
Implementation: I was trying to implement it in a different ways, but nothing worked correctly. Help me please to find a way to implement this, I feel that the solution is somewhere around. This is what I've tried:
- I've created a function of form:
while True:
PLOT_GRAPH
time.sleep(1)
But it was making whole window permanently load the plot.
- I used multiprocessing. I was creating process with the function that updates the plot. But this gives me an error: "TypeError: cannot pickle 'QWidget' object". I know this is because of constraints on types that can be given as args of the Process. But I don't know how to fix it.
You can see the code of the second case below:
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QVBoxLayout
from multiprocessing import Process, Queue
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
import matplotlib.pyplot as plt
import random
import time
def plot_cycle(ui_obj):
while True:
ui_obj.plot()
time.sleep(2)
class Ui_MainWindow(object):
def __init__(self, MainWindow):
self.setupUi(MainWindow)
p1 = Process(target=plot_cycle, args=(self, ))
p1.start()
p1.join()
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1399, 770)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.PLOT_FRAME = QtWidgets.QFrame(self.centralwidget)
self.PLOT_FRAME.setGeometry(QtCore.QRect(20, 20, 690, 690))
self.PLOT_FRAME.setStyleSheet("background: rgb(200, 200, 200);")
self.PLOT_FRAME.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.PLOT_FRAME.setFrameShadow(QtWidgets.QFrame.Raised)
self.PLOT_FRAME.setObjectName("PLOT_FRAME")
self.LOAD_SCRIPT_BUTTON = QtWidgets.QPushButton(self.centralwidget)
self.LOAD_SCRIPT_BUTTON.setGeometry(QtCore.QRect(720, 540, 131, 28))
self.LOAD_SCRIPT_BUTTON.setObjectName("LOAD_SCRIPT_BUTTON")
self.SCRIPT_EDITOR = QtWidgets.QTextEdit(self.centralwidget)
self.SCRIPT_EDITOR.setGeometry(QtCore.QRect(860, 20, 521, 691))
self.SCRIPT_EDITOR.setObjectName("SCRIPT_EDITOR")
self.EDITOR_SCROLLER = QtWidgets.QScrollBar(self.centralwidget)
self.EDITOR_SCROLLER.setGeometry(QtCore.QRect(1380, 20, 16, 691))
self.EDITOR_SCROLLER.setOrientation(QtCore.Qt.Vertical)
self.EDITOR_SCROLLER.setObjectName("EDITOR_SCROLLER")
self.cells_av_label = QtWidgets.QLabel(self.centralwidget)
self.cells_av_label.setGeometry(QtCore.QRect(740, 20, 91, 16))
self.cells_av_label.setObjectName("cells_av_label")
self.CELLS_AVAILABLE = QtWidgets.QLabel(self.centralwidget)
self.CELLS_AVAILABLE.setGeometry(QtCore.QRect(750, 50, 55, 16))
self.CELLS_AVAILABLE.setAlignment(QtCore.Qt.AlignCenter)
self.CELLS_AVAILABLE.setObjectName("CELLS_AVAILABLE")
self.SAVE_SCRIPT_BUTTON = QtWidgets.QPushButton(self.centralwidget)
self.SAVE_SCRIPT_BUTTON.setGeometry(QtCore.QRect(720, 590, 131, 28))
self.SAVE_SCRIPT_BUTTON.setObjectName("SAVE_SCRIPT_BUTTON")
self.NEW_SCRIPT_BUTTON = QtWidgets.QPushButton(self.centralwidget)
self.NEW_SCRIPT_BUTTON.setGeometry(QtCore.QRect(720, 490, 131, 28))
self.NEW_SCRIPT_BUTTON.setObjectName("NEW_SCRIPT_BUTTON")
self.PUT_CELL_BUTTON = QtWidgets.QPushButton(self.centralwidget)
self.PUT_CELL_BUTTON.setGeometry(QtCore.QRect(720, 180, 131, 28))
self.PUT_CELL_BUTTON.setObjectName("PUT_CELL_BUTTON")
self.X_COORD_CELL = QtWidgets.QLineEdit(self.centralwidget)
self.X_COORD_CELL.setGeometry(QtCore.QRect(752, 80, 101, 22))
self.X_COORD_CELL.setObjectName("X_COORD_CELL")
self.Y_COORD_CELL = QtWidgets.QLineEdit(self.centralwidget)
self.Y_COORD_CELL.setGeometry(QtCore.QRect(752, 130, 101, 22))
self.Y_COORD_CELL.setObjectName("Y_COORD_CELL")
self.x_coord_cell_label = QtWidgets.QLabel(self.centralwidget)
self.x_coord_cell_label.setGeometry(QtCore.QRect(720, 80, 21, 21))
self.x_coord_cell_label.setObjectName("x_coord_cell_label")
self.y_coord_cell_label = QtWidgets.QLabel(self.centralwidget)
self.y_coord_cell_label.setGeometry(QtCore.QRect(720, 130, 21, 21))
self.y_coord_cell_label.setObjectName("y_coord_cell_label")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 1399, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
self.figure = plt.figure()
self.canvas = FigureCanvas(self.figure)
layout = QVBoxLayout()
layout.addWidget(self.canvas)
self.PLOT_FRAME.setLayout(layout)
self.PUT_CELL_BUTTON.clicked.connect(self.plot)
def plot(self):
data = [[random.random() for i in range(10)] for j in range(10)]
self.figure.clear()
ax = self.figure.add_subplot(111)
ax.imshow(data)
ax.set(xticklabels=[])
ax.set(yticklabels=[])
ax.set(xlabel=None)
ax.set(ylabel=None)
ax.tick_params(bottom=False, left=False)
self.figure.tight_layout()
self.figure.subplots_adjust(left=0, right=1, top=1, bottom=0)
self.canvas.draw()
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.LOAD_SCRIPT_BUTTON.setText(_translate("MainWindow", "Load Script..."))
self.cells_av_label.setText(_translate("MainWindow", "Cells available:"))
self.CELLS_AVAILABLE.setText(_translate("MainWindow", "X"))
self.SAVE_SCRIPT_BUTTON.setText(_translate("MainWindow", "Save Script"))
self.NEW_SCRIPT_BUTTON.setText(_translate("MainWindow", "New Script..."))
self.PUT_CELL_BUTTON.setText(_translate("MainWindow", "Put Cell on board"))
self.x_coord_cell_label.setText(_translate("MainWindow", "X:"))
self.y_coord_cell_label.setText(_translate("MainWindow", "Y:"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow(MainWindow)
MainWindow.show()
sys.exit(app.exec_())