0

I'm trying to learn the basic usage of emitting/receiving signals and I'm running into some trouble.

I wanted to start with something basic so I created a MainWindow and put a QPushButton called "plot".

When the button is pushed it takes the arguments (self, xdata, ydata) and runs the method initiatePlot from my class MainWindow(QMainWindow)

    self.plotbtn = QPushButton("Plot")
    self.plotbtn.clicked.connect(partial(self.initiatePlot, xdata, ydata))

    def initiatePlot(self,x,y):
        PlotSignal = pyqtSignal(list, list)
        self.PlotSignal.emit(x, y)

Afterwards I tried to connect it to my plotter class, but I just get "Process finished exit code 1" I believe the error to be coming from this particular line of code in my below class.

self.PlotSignal.connect(self.plotData)

CODE FOR PLOTTER CLASS

class createFIG(FigureCanvas):
  def __init__(self):
    #super().__init__(Figure(tight_layout=True))
    self.figure = plt.figure()
    self.axes = self.figure.add_subplot(111)

    self.name = ""

    # xdata = [1,2,3,4,5]
    # ydata = [12,4,56,78,9]

    plt.figure()
    self.axes.set_xlabel('x label')

    #self.plotData(xdata,ydata)

    self.PlotSignal.connect(self.plotData)


  def plotData(self, xdata,ydata):
    print("plotting")
    self.axes.plot(xdata, ydata)
    self.draw()
    plt.show()

Sorry the whitespace might be a little messed up.

The current issue is how I go about receiving the signal I emit from my initiatePlot method.

The end goals is to be able to click the plot button and create a new window with a new plot figure each time.

If there is an easier way to link the button in my mainwindow to plotting class that would be helpful.

Here is a link to my full code: https://github.com/Silvuurleaf/InteractiveGraphing/blob/master/LiveGraphing.py

Markus T.
  • 113
  • 1
  • 13
  • Can you please create a [mcve] of the issue?! As SO puts it: Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: How to create a [mcve]. – ImportanceOfBeingErnest Jul 25 '17 at 17:20
  • This is the minimal amount of code and I can't give you a verifiable example because my IDE only gives my the error "Process finished exit code 1" when I run it. I believe the error occurs in the line "self.PlotSIgnal.connect(self.plotData)" – Markus T. Jul 25 '17 at 17:31
  • Exactly that's the idea: provide the [mcve] that lets everyone else reproduce the error you get. I.e. I need to be able to copy the code from the question, run it, get the same error as you, correct the code, paste it as answer and you'll be happy. – ImportanceOfBeingErnest Jul 25 '17 at 17:36
  • Okay I added a github link to give full access to my code. – Markus T. Jul 25 '17 at 17:43
  • Looking at the code, it's not clear to me what you need the signal and slot for at all. It seems you want to create a matplotlib plotting window each time the button is pressed. That would be done by initiating the `createFIG` class (it does not need to subclass `FigureCanvas`) and simply calling the plotting function from it. Am I missing something here? Is there another reason to use signals? – ImportanceOfBeingErnest Jul 25 '17 at 18:14
  • I tried that, but perhaps I didn't do it right. I wrote this earlier self.plotbtn.clicked.connect(partial(CreateFIG.plotData(xdata, ydata))) – Markus T. Jul 25 '17 at 18:36

1 Answers1

2

As said, I'm not sure if this is really what you are looking for, but the following code should create a new matplotlib window, each time the button is pressed.

import sys
#Importing PyQt5 library to construct widgets for Graphic User Interface (GUI) application
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import (QLineEdit, QPushButton, QSlider, QApplication, QVBoxLayout, QHBoxLayout,
                             QWidget, QLabel, QCheckBox, QRadioButton, QPlainTextEdit, QSizePolicy,
                             QMainWindow,QFrame, QFileDialog, QTableWidgetItem, QTableWidget, QMenu, QMessageBox,
                             QAction, QToolBar)
from PyQt5.QtCore import Qt, QAbstractTableModel, pyqtSignal

from functools import partial
import matplotlib
matplotlib.use("Qt5Agg")

from matplotlib import pyplot as plt
plt.style.use(['ggplot'])

class createFIG():
    def __init__(self):
        self.figure = plt.figure()
        self.axes = self.figure.add_subplot(111)
        self.name = ""
        self.axes.set_xlabel('x label')

    def plotData(self, xdata,ydata):
        print("plotting")
        self.axes.plot(xdata, ydata)
        plt.show()


class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setWindowTitle("Perspective")

        self.initializeUI()

    def initializeUI(self):

        xdata = [1,2,3,4,5]
        ydata = [12,4,56,78,9]

        #Main Widget
        self.main_widget = QWidget(self)
        self.setCentralWidget(self.main_widget)

        self.plotbtn = QPushButton("Plot")
        self.plotbtn.clicked.connect(partial(self.initiatePlot, xdata, ydata))

        self.hMAIN = QHBoxLayout(self.main_widget)
        self.vboxLeft = QVBoxLayout()
        self.vboxLeft.addWidget(self.plotbtn)

        self.hbox1 = QHBoxLayout()

        self.vboxLeft.addLayout(self.hbox1)

        self.PlotLayout = QVBoxLayout()

        self.hMAIN.addLayout(self.vboxLeft)
        self.hMAIN.addLayout(self.PlotLayout)

        self.show()

    def initiatePlot(self,x,y):
        print("emit signal")
        f = createFIG()
        f.plotData(x, y)


def main():
        # main loop
        app = QApplication(sys.argv)
        # instance
        window = MainWindow()
        window.show()
        # appWindow = MainWindow()
        sys.exit(app.exec_())

if __name__ == "__main__":
    main()
ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712
  • Yes thank you this is exactly what I wanted. I'll work on my communication skills next time I post to elucidate my problem. Thanks! – Markus T. Jul 25 '17 at 18:48
  • I'll look up how to properly utilize signals elsewhere – Markus T. Jul 25 '17 at 18:49
  • [This question](https://stackoverflow.com/questions/41156260/how-to-use-a-qthread-to-update-a-matplotlib-figure-with-pyqt) might show you how to use signal and also why: because different threads need to communicate through them. Also, [this question](https://stackoverflow.com/questions/42146922/variables-across-classes-to-scale-plot-in-pyqt-gui) seems similar to what you want. – ImportanceOfBeingErnest Jul 25 '17 at 18:54