1
\$\begingroup\$

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)

        self.tabwidget.addTab(self.tab1, 'tab1')
        self.tabwidget.addTab(self.tab2, 'tab2')

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()
        layout_1.addWidget(self.but)
        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.

\$\endgroup\$
0

1 Answer 1

0
\$\begingroup\$

Basically your code works.

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)
        layout.addWidget(self.but)

    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)
        layout.addWidget(self.path_widget) 
       

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

        self.tabwidget.addTab(self.tab1, 'Tab 1')
        self.tabwidget.addTab(self.tab2, 'Tab 2')
        
    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()

enter image description here

\$\endgroup\$
2
  • \$\begingroup\$ Thanks for your answer. Your suggestion is exactly what I was looking for! \$\endgroup\$
    – roPe
    Jul 4, 2021 at 13:58
  • \$\begingroup\$ @roPe you are welcome \$\endgroup\$
    – S. Nick
    Jul 4, 2021 at 14:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.