geistmate
geistmate

Reputation: 555

Calling method from a second class to update QListView data

I have two tabs, Tab1, and Tab2. On Tab2, there is a button that when clicked, calls a method that updates the QListView data in the same tab. This works successfully.

When trying to call the same method from another class, it will not work. Below is a minimum reproducible example.

import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import (
    QDesktopWidget,
    QVBoxLayout,
    QHBoxLayout,
    QPushButton,
)
from PyQt5.QtCore import Qt


class App(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        self.setWindowTitle('App')
        self.resize(1200, 800)
        self.center()
        self.window = MainWindow(self)
        self.setCentralWidget(self.window)
        self.show()

    def center(self):
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())


class MainWindow(QtWidgets.QWidget):
    def __init__(self, parent):
        super(MainWindow, self).__init__(parent)

        layout = QVBoxLayout(self)

        # Initialize Tabs
        tab_holder = QtWidgets.QTabWidget()
        tab1 = Home()
        tab2 = SecondTab()

        tab_holder.addTab(tab1, "Tab1")
        tab_holder.addTab(tab2, 'Tab2')
        layout.addWidget(tab_holder)


class Home(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Home, self).__init__(parent)
        lay = QVBoxLayout(self)

        self.btn_login = QPushButton('Login')
        self.btn_login.clicked.connect(self.login)
        lay.addWidget(self.btn_login)

    @QtCore.pyqtSlot()
    def login(self):
        print('Hello')
        SecondTab.load_info()


class SecondTab(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(SecondTab, self).__init__(parent)
        lay = QVBoxLayout(self)

        # Choice Boxes
        layout_choice_boxes = QHBoxLayout()

        self.list_of_items = QtWidgets.QListView()
        self.model_dist = QtGui.QStandardItemModel(self.list_of_items)
        layout_choice_boxes.addWidget(self.list_of_items)

        # Load data button.
        self.loadData = QPushButton('Load Data')
        self.loadData.clicked.connect(self.load_info)

        # Add all components to main layout.
        lay.addLayout(layout_choice_boxes)
        lay.addWidget(self.loadData)

    @QtCore.pyqtSlot()
    def load_info(self):
        for member in ['Item 1', 'Item 2', 'Item 3']:
            item = QtGui.QStandardItem(member)
            item.setCheckable(True)
            item.setEditable(False)
            check = Qt.Unchecked
            item.setCheckState(check)
            self.model_dist.appendRow(item)

        self.list_of_items.setModel(self.model_dist)


# Press the green button in the gutter to run the script.
if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())

The error is on the line in the class Home() where I try to call the method from the SecondTab() class: SecondTab.load_info()

The load_info() method uses self in the SecondTab class, so I tried passing in the class directly like this: SecondTab.load_info(SecondTab()), however, it did not work.

Upvotes: 0

Views: 32

Answers (1)

eyllanesc
eyllanesc

Reputation: 243955

This is a problem about the basic OOP issues, you have to interact with the instances (the objects) and not the classes (the abstraction). So the solution is that the connection between the objects "tab1" and "tab2":

class MainWindow(QtWidgets.QWidget):
    def __init__(self, parent):
        super(MainWindow, self).__init__(parent)

        layout = QVBoxLayout(self)

        # Initialize Tabs
        tab_holder = QtWidgets.QTabWidget()
        tab1 = Home()
        tab2 = SecondTab()

        tab_holder.addTab(tab1, "Tab1")
        tab_holder.addTab(tab2, 'Tab2')
        layout.addWidget(tab_holder)

        tab1.btn_login.clicked.connect(tab2.load_info)


class Home(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Home, self).__init__(parent)
        lay = QVBoxLayout(self)

        self.btn_login = QPushButton('Login')
        lay.addWidget(self.btn_login)

Upvotes: 2

Related Questions