I'm using a QTabWidget for some postprocessing. Initially, the content of the tab is a button to open a txt file. Once this button is clicked, the content of the tab changes and a plot is made based on the data inside the txt file. In addition, there is a button to close the plot.
With QStackedWidget, the "openFileWidget" is a CentralWidget, which is replaced by the "newWindow" widget after opening the txt file. If I close the "newWindow" widget, I get back to the (empty) tab.
If I want to have the "openFileWidget" re-appear, what is the best way to do so? As the newWindow is closed, is it still necessary to use takeAt
?
import os, sys
from PySide import QtCore, QtGui
class MainStartTabWindow(QtGui.QWidget):
def __init__(self, parent=None):
super(MainStartTabWindow, self).__init__(parent)
tabWidget = QtGui.QTabWidget()
tabWidget.addTab(tab1Tab(), self.tr("tab 1"))
mainLayout = QtGui.QVBoxLayout()
mainLayout.addWidget(tabWidget)
self.setLayout(mainLayout)
class tab1Tab(QtGui.QMainWindow):
def __init__(self, parent=None):
super(tab1Tab, self).__init__(parent)
self.initTab1Content()
def initTab1Content(self):
self.centralOpenFile = QtGui.QStackedWidget()
self.setCentralWidget(self.centralOpenFile)
widgetOpenFile = openFileWidget(self)
widgetOpenFile.openFileButton.clicked.connect(self.setOpenFile)
widgetOpenFile.openFileButton.clicked.connect(self.FileOpened)
self.centralOpenFile.addWidget(widgetOpenFile)
def FileOpened(self):
FileOpened_widget = newWindow(self.path)
self.centralOpenFile.addWidget(FileOpened_widget)
self.centralOpenFile.setCurrentWidget(FileOpened_widget)
def setOpenFile(self):
options = QtGui.QFileDialog.Options()
fileChoice = "txt (*.txt)"
self.path, filtr = QtGui.QFileDialog.getOpenFileName(self, "Open file", "", fileChoice, "", options)
return self.path
class openFileWidget(QtGui.QWidget):
def __init__(self, parent=None):
super(openFileWidget, self).__init__(parent)
self.openFileButton = QtGui.QPushButton("click to open")
self.openFileButton.setFixedSize(150,150)
layoutNoFileYet = QtGui.QGridLayout()
layoutNoFileYet.addWidget(self.openFileButton, 1, 1)
self.setLayout(layoutNoFileYet)
class newWindow(QtGui.QMainWindow):
def __init__(self, PathToPlanFile, parent=None):
super(newWindow, self).__init__(parent)
self.createFrameUI()
def createFrameUI(self):
self.frameUI = QtGui.QWidget()
self.buttonClose = QtGui.QPushButton("close")
self.buttonClose.clicked.connect(self.close)
self.label = QtGui.QLabel("plot based on openend file")
layoutFileLoaded = QtGui.QGridLayout()
layoutFileLoaded.addWidget(self.buttonClose, 1, 1)
layoutFileLoaded.addWidget(self.label, 2, 1)
self.frameUI.setLayout(layoutFileLoaded)
self.setCentralWidget(self.frameUI)
def main():
app = QtGui.QApplication(sys.argv)
testPlot = MainStartTabWindow()
testPlot.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
I would change your approach entirely. You only want one QMainWindow. There is no need for the openFileWidget; it is just a button. The next thing I would do is simply create a custom QTabWidget editing the addTab to open a file.
import os, sys
from PySide import QtCore, QtGui
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.main_widget = QtGui.QTabWidget()
self.setCentralWidget(self.main_widget)
self.main_widget.addTab(Page1(), "Tab 1")
self.main_widget.addTab(Page2(), "Tab 2")
self.main_widget.addTab(Page3(), "Tab 3")
self.main_widget.addTab(Page4(), "Tab 4")
self.main_widget.setCurrentIndex(0)
# end Constructor
# end MainWindow
class Page1(QtGui.QWidget):
"""First page to display."""
def __init__(self):
super().__init__()
self.main_layout = QtGui.QVBoxLayout()
self.setLayout(self.main_layout)
# Widgets
self.hlayout = QtGui.QHBoxLayout()
self.hlayout.setContentsMargins(0, 0, 0, 0)
self.read_btn = QtGui.QPushButton("Open File")
self.clear_btn = QtGui.QPushButton("Clear Data")
self.hlayout.addWidget(self.read_btn)
self.hlayout.addWidget(self.clear_btn)
# Display data here
self.display = DisplayWidget("plot based on openend file")
# Properties
self.data = None
# Signals
self.read_btn.clicked.connect(self.read_file)
self.clear_btn.clicked.connect(self.display.clearData)
# Layout
self.main_layout.addLayout(self.hlayout)
self.main_layout.addWidget(self.display)
# end Constructor
def read_file(self, path=""):
"""Read file dialog."""
if path == "":
options = QtGui.QFileDialog.Options()
fileChoice = "txt (*.txt)"
path, _ = QtGui.QFileDialog.getOpenFileName(self, "Open file", "",
fileChoice, "", options)
# Cancel button was pressed
if path == "":
return
with open(path, "r") as file:
lines = file.readlines()
# close file
self.display.setData(lines)
# end read_file
def set_data(self, data=None):
"""Set the data to display here."""
# end set_data
# end class Page1
class DisplayWidget(QtGui.QWidget):
def __init__(self, text=""):
super().__init__()
# Layout
self.main_layout = QtGui.QVBoxLayout()
self.setLayout(self.main_layout)
# Widgets Have all of your display stuff here
self.label = QtGui.QLabel(text)
# Properties
self.data = None
# Add Layout
self.main_layout.addWidget(self.label)
# end Constructor
def setData(self, data):
"""Set the data to show the plot."""
self.data = data
# Plot stuff here
self.label.setText(str(data))
# end setValue
def clearData(self):
"""Clear the plot data."""
self.data = None
# Clear data here
self.label.setText("Open a file to display data")
# end clearData
# end class DisplayWidget
class Page2(QtGui.QWidget):
pass
# end class Page2
class Page3(QtGui.QWidget):
pass
# end class Page3
class Page4(QtGui.QWidget):
pass
# end class Page4
def main():
app = QtGui.QApplication(sys.argv)
testPlot = MainWindow()
testPlot.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
I would not let the user close the tab. Just have them be able to clear and reload the data if they wish. If you really want them to close then have the clear data button close the displaywidget and have the read file button create a new widget every time. I don't think you need to create a new widget every time. If you don't like the tabs you may want to look into the QToolBox.