Issue
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:
- transfer this data (importedfile) to
FirstTab()
- 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()
Solution
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.
Answered By – musicamante
Answer Checked By – Mary Flores (BugsFixing Volunteer)