# Proper way to pass an infromation/variable across QTabWidgets?

EDIT: Changed title, few mistakes in code were resolved (now working properly)

The GUI I am trying to make will be a simple QTabWidget, leading a user straightforwardly towards the end tab by tab.

For now, I have three *.py files - main.py, tab1.py, tab2.py. In main.py is the main window of the app and function to run the app like this (simplified just to focus on my question):

import sys
import tab1
import tab2
import PyQt5.QtWidgets as qtw

def main():
app = qtw.QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())

class MainWindow(qtw.QmainWindow):
def __init__(self):
super().__init__()
self.tabwidget = qtw.QTabWidget()
self.setCentralWidget(self.tabwidget)

self.tab1 = tab1.Tab_1()
self.tab2 = tab2.Tab_2()

# This is how I now passing the information from tab1 to tab2
self.tab1.path_line.textChanged.connect(self.tab2.path_widget.setText)

if __name__ == '__main__':
main()


In the tab1.py is defined class for a tabwidget which will serve as an input data tab. There is a button to open filedialog, read filename, and write the path into QLineEdit widget:

import PyQt5.QtWidgets as qtw

class Tab_1(qtw.QWidget):
def __init__(self):
super().__init__()
self.path_line = qtw.QLineEdit()
self.but = qtw.QPushButton('Open')
self.but.clicked.connect(self.openfile)

layout_1 = qtw.QVBoxLayout()
self.setLayout(layout_1)

def openfile(self):
filename, _ = qtw.QFileDialog.getOpenFileName(self, 'Title', 'File types')
if filename:
self.path_line.setText(filename)
else:
self.path_line.setText('No file was selected!')


Now I want to in another file tab2.py use the path I got from qtw.OpenFileDialog. So the defined class Tab_2() looks like this:

import PyQt5.QtWidgets as qtw

class Tab_2(qtw.QWidget):
def __init__(self):
super().__init__()

# Retrieving the information by QLabel widget
self.path_widget = qtw.QLabel()
# Transform the information into string variable
self.path_string = self.path_widget.text()

layout_2 = qtw.QVBoxLayout()
layout_2.addWidget(self.path_widget) # The path from QFileDialog (Tab1) should appered on Tab2
self.setLayout(layout_2)


My question is, is this the proper way to do it? Should I use MainWindow class as a "getter" and "passer" of the information like that or should that be implemented in the tab classes themselves? It works but I do not want to learn to do something bad way and eventually get used to it. I understand classes and their inheritance to some point (a lot of examples of dog classes or employee classes that I understand how it works but in my case I am confused). In combination with GUI, it messing up my head. Also, I want to have each tab as a separate class in a separate *.py file to make it clear and easy to add another one in the future. I see, that it might not be the right way to uses classes but each tab will have a different layout.

To write the selected path, you use the QLineEdit widget of the Tab_1 class. You don't show the path_line widget itself anywhere, but use the textChanged signal.

It is not clear why there is a path_string object in the Tab_2 class that you are not using.

I would suggest you:

• object self.path_line = '' declare in the MainWindow class.

• use the currentChanged signal:

self.tabwidget.currentChanged.connect(self.current_changed)

• when creating instances of the Tab_1 and Tab_2 classes, pass self as an argument, which will allow you to have access to objects of the MainWindow class in these widgets, for example path_line.

• In the slot current_changed, you can write logic, which you will need when the index of the current page changes.

import sys
import PyQt5.QtWidgets as qtw

#from tab1 import Tab_1
class Tab_1(qtw.QWidget):
def __init__(self, parent=None):                                 # + parent
super().__init__()
self.parent = parent                                         # + parent

self.but = qtw.QPushButton('Open')
self.but.clicked.connect(self.open_file)

layout = qtw.QVBoxLayout(self)

def open_file(self):
filename, _ = qtw.QFileDialog.getOpenFileName(self, 'Title', 'File types')
if filename:
self.parent.path_line = filename                         # + parent
else:
self.parent.path_line = ''                               # + parent

#from tab2 import Tab_2
class Tab_2(qtw.QWidget):
def __init__(self, parent=None):
super().__init__()
self.parent = parent

self.path_widget = qtw.QLabel()

layout = qtw.QVBoxLayout(self)

class MainWindow(qtw.QMainWindow):
def __init__(self):
super().__init__()
self.path_line = ''                                          # + path_line

self.tabwidget = qtw.QTabWidget()
self.tabwidget.currentChanged.connect(self.current_changed)  # + currentChanged
self.setCentralWidget(self.tabwidget)

self.tab1 = Tab_1(self)                                      # + self
self.tab2 = Tab_2(self)                                      # + self

def current_changed(self, index):
if index == 0:
self.statusBar().showMessage('Message in statusbar. '
'Select the file to read.', 5000)
if index == 1:
self.tab2.path_widget.setText(self.path_line)
if not self.path_line:
self.statusBar().showMessage(
'Go to the first tab and select the file to read.', 5000)

def main():
app = qtw.QApplication(sys.argv)
window = MainWindow()
window.resize(400, 300)
window.show()
sys.exit(app.exec_())

if __name__ == '__main__':
main()