Reputation: 17
I am developing a GUI that imports and plots data (csv file). Data are initially imported in the TabWidget()
class using getfile()
and on_pushButtonLoad_clicked()
and passed to the FirstTab()
class, where MRChart()
is plotted in the infrastructure()
widget. To achieve this, I created the firstTab
instance in TabWidget()
(apologies if my terminology is incorrect here).
The end goal is to update the plot based on the numerical range selected on a rangeslider. Firstly, I want to pass the value of slider1
to FirstTab()
and I should be able to manage from there. To do this, I have attempted to create the tabwidget
instance in FirstTab()
. However, I get the following: "RecursionError: maximum recursion depth exceeded". I presume this is due to each class having an instance of itself contained in the other.
Any help appreciated.
Code:
class TabWidget(QDialog):
def __init__(self, data):
super(TabWidget, self).__init__()
self.data = data
self.firstTab = FirstTab(self.data)
self.showMaximized()
# create Header
FilterLayout = QHBoxLayout()
FilterLayout.addWidget(self.createHeader1a(), 1)
FilterLayout.addWidget(self.createHeader2a(), 4)
# create Tab
tabwidget = QTabWidget()
tabwidget.addTab(self.firstTab, "Tab 1")
vbox = QVBoxLayout()
vbox.addLayout(FilterLayout)
vbox.addWidget(tabwidget)
self.setLayout(vbox)
def createHeader1a(self): #Import
HeaderBox = QGroupBox("Import Data")
inputfilebtn = QPushButton("Import")
inputfilebtn.clicked.connect(self.on_pushButtonLoad_clicked)
# importrow1
importrow1layout = QHBoxLayout()
importrow1layout.addWidget(inputfilebtn)
HeaderLayout = QVBoxLayout()
HeaderLayout.addLayout(importrow1layout)
HeaderBox.setLayout(HeaderLayout)
HeaderBox.setFlat(True)
return HeaderBox
def createHeader2a(self): #Filter
HeaderBox = QGroupBox("Filter Data")
rightlayout = QHBoxLayout()
# range slider bar to filter column data for plotting
label4 = QLabel(self)
label4.setText("Filter range:")
rightlayout.addWidget(label4)
self.slider1 = QLabeledRangeSlider(Qt.Horizontal)
self.slider1.setRange(5, 500)
self.slider1.setValue((150, 300))
rightlayout.addWidget(self.slider1)
HeaderBox.setLayout(rightlayout)
HeaderBox.setFlat(True) #
return HeaderBox
#import and return file
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)
global database
database = importedfile
def getslider1value(self):
return self.slider1.value
class FirstTab(QWidget):
def __init__(self, data):
super(FirstTab, self).__init__()
self.data = data
self.tabwidget = TabWidget(self.data)# issue here. Attempting to # access TabWidget class
# Grid layout of entire tab
layout = QGridLayout()
layout.addWidget(self.infrastructure(self.data), 3, 0)
layout.setRowStretch(4, 3)
layout.setColumnStretch(0, 1)
self.setLayout(layout)
def MRChart(self, importedfile): # pie chart
if self.radioButton1.isChecked():
fig = go.Pie(labels=importedfile[self.radioButton1.label])
elif self.radioButton2.isChecked():
fig = go.Pie(labels=importedfile[self.radioButton2.label])
layout = go.Layout(autosize=True, legend=dict(orientation="h", xanchor='center', x=0.5))
fig = go.Figure(data=fig, layout=layout)
fig.update_layout(margin=dict(t=0, b=0, l=0, r=0))
self.browser.setHtml(fig.to_html(include_plotlyjs='cdn'))
def infrastructure(self, importedfile):
groupBox = QGroupBox("Plot")
self.browser = QtWebEngineWidgets.QWebEngineView(self)
right = QVBoxLayout()
# Change/update plot (MRChart) depending on what Radio button is selected
self.radioButton1 = QRadioButton("Label 1")
self.radioButton1.label = "Column_label_1"
self.radioButton1.toggled.connect(lambda: self.MRChart(database))
right.addWidget(self.radioButton1)
self.radioButton2 = QRadioButton("Label 2")
self.radioButton2.setChecked(True)
self.radioButton2.label = "Column_label_2"
self.radioButton2.toggled.connect(lambda: self.MRChart(database))
right.addWidget(self.radioButton2)
middleright = QHBoxLayout()
middleright.addWidget(self.browser)
middleright.addLayout(right)
groupBox.setLayout(middleright)
groupBox.setFlat(True)
print(self.tabwidget.getslider1value())# attempting to print slider value here
return groupBox
if __name__ == "__main__":
app = QApplication(sys.argv)
tabwidget = TabWidget(data=None)
tabwidget.show()
app.exec()
Upvotes: 0
Views: 1218
Reputation: 48529
The recursion error is clear: TabWidget
tries to create FirstTab
, but there you're trying to create another TabWidget
, which will create a further FirstTab
and so on.
If you want to keep reference between objects, you must pass references, not create new instances (see the note below).
Also, since FirstTab
calls infrastructure
in the __init__
, at that point the slider in the parent widget has not been created yet.
You must move the creation of FirstTab
after the slider is created, and pass the reference in the constructor.
class TabWidget(QDialog):
def __init__(self, data):
super(TabWidget, self).__init__()
self.data = data
self.showMaximized()
# create Header
FilterLayout = QHBoxLayout()
FilterLayout.addWidget(self.createHeader1a(), 1)
FilterLayout.addWidget(self.createHeader2a(), 4)
self.firstTab = FirstTab(self) # <- pass the reference of the parent
# ...
class FirstTab(QWidget):
def __init__(self, tabwidget):
super(FirstTab, self).__init__()
self.tabwidget = tabwidget
self.data = tabwidget.data
# ...
Note that this is the same problem you had in your previous question. I strongly suggest you to review the basics of classes and instances and OOP in general, as knowledge and comprehension of those aspects cannot be ignored.
Upvotes: 1