简体   繁体   中英

How can I update a figure when button is pressed in a different class in PyQt5?

I am building a GUI in python using PyQt5. Data is imported using on_pushButtonLoad_clicked() and get_file() located in TabWidget .

My goal is to:

  1. transfer this data (importedfile) to FirstTab()
  2. update the plot MRChart(importedfile) using the recently imported data.

I have completed the first goal in transferring the data to FirstTab() whereby the plot is generated and can be shown (for demonstrative purposes) in the browser using fig.show() . Although MRChart(importedfile) is connected to the plotting widget energy() by self.browser , the figure fails to show in the GUI.

Code:

class TabWidget(QDialog):
    def __init__(self, data):
        super(TabWidget, self).__init__()
        self.data = data

        self.showMaximized()

        #create filter object
        FilterLayout = QHBoxLayout()
        FilterLayout.addWidget(self.createHeader1a(), 2)#column width

        #create tab widget object
        tabwidget = QTabWidget()
        tabwidget.addTab(FirstTab(self.data), "Tab 1")

        vbox = QVBoxLayout()
        vbox.addLayout(FilterLayout)
        vbox.addWidget(tabwidget)

        self.setLayout(vbox)

    def createHeader1a(self): # function defining characteristics of each group/grid object
        HeaderBox = QGroupBox("Import Data")

        inputfilebtn = QPushButton("Import")
        inputfilebtn.resize(150, 50)
        inputfilebtn.clicked.connect(self.on_pushButtonLoad_clicked)

        #importrow1
        importrow1layout = QHBoxLayout()
        importrow1layout.addWidget(inputfilebtn)
        importrow1layout.addStretch()

        HeaderLayout = QGridLayout()
        HeaderLayout.addLayout(importrow1layout, 0, 1)
        HeaderBox.setLayout(HeaderLayout)
        HeaderBox.setFlat(True)

        return HeaderBox

    def getfile(self):
        option = QFileDialog.Options()
        fname = QFileDialog.getOpenFileName(self, 'Open file',
                                            'c:\\', "CSV files (*.csv)", options=option)

        global importedfile
        importedfile = pd.read_csv(fname[0])

    @QtCore.pyqtSlot()
    def on_pushButtonLoad_clicked(self):
        self.getfile()
        FT=FirstTab(data=importedfile)
        FT.MRChart(importedfile)

class FirstTab(QWidget):
    def __init__(self, data):
        super(FirstTab, self).__init__() 
        self.data = data

        # Grid layout of entire tab
        layout = QGridLayout()
        layout.addWidget(self.energy(), 3, 0)
        layout.setRowStretch(3, 3)
        layout.setColumnStretch(0, 1)

        self.setLayout(layout)


    def MRChart(self, importedfile): # pie
        fig = go.Pie(labels=importedfile["Label1"], values=importedfile["Label2"])
        layout = go.Layout(autosize=True, legend=dict(orientation="h",xanchor='center', x=0.5))# height = 600, width = 1000,
        fig = go.Figure(data=fig, layout=layout)
        fig.update_layout(margin=dict(t=0, b=0, l=0, r=0))
        fig.show()# only included to prove that figure has been created
        self.browser.setHtml(fig.to_html(include_plotlyjs='cdn'))


    def energy(self):
        groupBox = QGroupBox("Box Title")

        self.browser = QtWebEngineWidgets.QWebEngineView(self)
        exportfilebtn = QCheckBox("tickbox1")
        middleright = QHBoxLayout()
        middleright.addWidget(self.browser)
        middleright.addWidget(exportfilebtn)
        groupBox.setLayout(middleright)
        groupBox.setFlat(True)

        return groupBox

if __name__ == "__main__":
    app = QApplication(sys.argv)
    tabwidget = TabWidget(data=None)
    tabwidget.show()
    app.exec()

Updated code in line with musicamante's answer

class TabWidget(QDialog):
    def __init__(self, data):
        super(TabWidget, self).__init__()
        self.data = data
        self.firstTab = FirstTab(self.data)

        #create filter object
        FilterLayout = QHBoxLayout()
        FilterLayout.addWidget(self.createHeader1a(), 2)#column width

        #create tab widget object
        tabwidget = QTabWidget()
        tabwidget.addTab(self.firstTab "Tab 1")

        vbox = QVBoxLayout()
        vbox.addLayout(FilterLayout)
        vbox.addWidget(tabwidget)

        self.setLayout(vbox)

    def createHeader1a(self): # function defining characteristics of each group/grid object
        HeaderBox = QGroupBox("Import Data")

        inputfilebtn = QPushButton("Import")
        inputfilebtn.resize(150, 50)
        inputfilebtn.clicked.connect(self.on_pushButtonLoad_clicked)

        #importrow1
        importrow1layout = QHBoxLayout()
        importrow1layout.addWidget(inputfilebtn)
        importrow1layout.addStretch()

        HeaderLayout = QGridLayout()
        HeaderLayout.addLayout(importrow1layout, 0, 1)
        HeaderBox.setLayout(HeaderLayout)
        HeaderBox.setFlat(True)

        return HeaderBox

    def getfile(self):
        option = QFileDialog.Options()
        fname = QFileDialog.getOpenFileName(self, 'Open file',
                                            'c:\\', "CSV files (*.csv)", options=option)

        return pd.read_csv(fname[0])

    @QtCore.pyqtSlot()
    def on_pushButtonLoad_clicked(self):
    importedfile = self.getfile()
    if importedfile is None:
            return
    self.firstTab.MRChart(importedfile)



class FirstTab(QWidget):
    def __init__(self, data):
        super(FirstTab, self).__init__() 
        self.data = data

        # Grid layout of entire tab
        layout = QGridLayout()
        layout.addWidget(self.energy(), 3, 0)
        layout.setRowStretch(3, 3)
        layout.setColumnStretch(0, 1)

        self.setLayout(layout)


    def MRChart(self, importedfile): # pie
        fig = go.Pie(labels=importedfile["Label1"], values=importedfile["Label2"])
        layout = go.Layout(autosize=True, legend=dict(orientation="h",xanchor='center', x=0.5))# height = 600, width = 1000,
        fig = go.Figure(data=fig, layout=layout)
        fig.update_layout(margin=dict(t=0, b=0, l=0, r=0))
        fig.show()# only included to provde figure is created
        self.browser.setHtml(fig.to_html(include_plotlyjs='cdn'))


    def energy(self):
        groupBox = QGroupBox("Box Title")

        self.browser = QtWebEngineWidgets.QWebEngineView(self)
        exportfilebtn = QCheckBox("tickbox1")
        middleright = QHBoxLayout()
        middleright.addWidget(self.browser)
        middleright.addWidget(exportfilebtn)
        groupBox.setLayout(middleright)
        groupBox.setFlat(True)

        return groupBox

if __name__ == "__main__":
    app = QApplication(sys.argv)
    tabwidget = TabWidget(data=None)
    tabwidget.show()
    app.exec()

You're creating a new instance of FirstTab , instead of using the existing one.

You must keep a reference to the first instance and then call its MRChart function.

Also, you should not use globals: getfile() should return the value, and you should use that returned value in on_pushButtonLoad_clicked .

class TabWidget(QDialog):
    def __init__(self, data):
        # ...
        self.firstTab = FirstTab(self.data)
        tabwidget.addTab(self.firstTab, "Tab 1")
        # ...

    def getfile(self):
        option = QFileDialog.Options()
        fname, _ = QFileDialog.getOpenFileName(self, 'Open file',
                                            'c:\\', "CSV files (*.csv)", options=option)

        if fname:
            return pd.read_csv(fname)

    @QtCore.pyqtSlot()
    def on_pushButtonLoad_clicked(self):
        importedfile = self.getfile()
        if importedfile is None:
            return
        self.firstTab.MRChart(importedfile)

Note that it's good practice to show the window only after adding its elements, and it's also usually better to not call show*() in the __init__ . It's also pointless to use resize() on a widget that is being added to a layout.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM