user1921942
user1921942

Reputation: 121

Using an instance of one class in another

It is a simple stack display program with a GUI using PyQt5 and Python3.3. Gui Program error areas highlighted in between ###Error####

#Modules
import sys
from PyQt5 import QtGui, QtCore, QtWidgets
import stacks_queues

#Classes
class MainWindow(QtWidgets.QMainWindow):
    '''Main Window'''

    #Constructor
    def __init__(self):
        super(MainWindow,self).__init__()
        self.createUI()   

    #Methods

###Error###
    def createUI(self):
        self.stack = stacks_queues.Stack()
        #Title
        self.setWindowTitle('Section 2.4: Stacks and queues')
        #Window Components
        self.mainViewWidget = QtWidgets.QWidget()
        #Layouts
        self.mainViewWidget.setLayout(self.mainGrid(self.stack))
        self.setCentralWidget(self.mainViewWidget)
###Error###

    def mainGrid(self,stack):
        #Layout components
        self.mainLayout = QtWidgets.QVBoxLayout()
        self.addRemoveLayout = QtWidgets.QGridLayout()
        self.pushButtonLayout = QtWidgets.QHBoxLayout()
        #Create components
        #Labels
        self.titleLabel = QtWidgets.QLabel('Implementation of a Stack', self)
        self.counterLabel = QtWidgets.QLabel('Number of items in stack: 0', self)
        self.contentsLabel = QtWidgets.QLabel('Contents of stack', self)
        self.addWordLabel = QtWidgets.QLabel('Word to add:', self)
        self.removeWordLabel = QtWidgets.QLabel('Word being removed', self)
        #Buttons
        self.pushButton = QtWidgets.QPushButton('Push', self)
        self.popButton = QtWidgets.QPushButton('Pop', self)
        #Line Edit
        self.addWordLineEdit = QtWidgets.QLineEdit('', self)
        self.removeWordLineEdit = QtWidgets.QLineEdit('Test', self)
        self.removeWordLineEdit.isReadOnly()
        #Text Edit
        self.stackTextEdit = QtWidgets.QTextEdit('', self)
        self.stackTextEdit.isReadOnly()
        #Add Widgets
        self.mainLayout.addWidget(self.titleLabel)
        self.addRemoveLayout.addWidget(self.addWordLabel, 0,0)
        self.addRemoveLayout.addWidget(self.removeWordLabel, 1,0)
        self.addRemoveLayout.addWidget(self.addWordLineEdit, 0,1)
        self.addRemoveLayout.addWidget(self.removeWordLineEdit, 1,1)
        self.mainLayout.addLayout(self.addRemoveLayout)
        self.mainLayout.addWidget(self.contentsLabel)
        self.mainLayout.addWidget(self.stackTextEdit)
        self.mainLayout.addWidget(self.counterLabel)
        self.pushButtonLayout.addWidget(self.pushButton)
        self.pushButtonLayout.addWidget(self.popButton)
        self.mainLayout.addLayout(self.pushButtonLayout)
        #Connections
        self.pushButton.clicked.connect(self.pushStack(self.stack))
        self.popButton.clicked.connect(self.popStack)
        return self.mainLayout

###Error###
    def pushStack(self,stack):
        item = self.addWordLineEdit.text()
        self.stack.push(item)
        #Re-draw Window
        self.mainViewWidget = QtWidgets.QWidget()
        self.mainViewWidget.setLayout(self.mainGrid(self.stack))
        self.setCentralWidget(self.mainViewWidget)
###Error###

    def popStack(self):
        #Not finished yet
        pass


#Functions
def Main():
    '''Main Program'''
    #Creates new application
    application = QtWidgets.QApplication(sys.argv)
    #Creates new instance of MainWindow
    mainWindow = MainWindow()
    #Display MainWindow
    mainWindow.show()
    #Keep MainWindow on top
    mainWindow.raise_()
    #Monitor for events
    application.exec_()
#Run Main
Main()

Imported program

class Stack():
    '''Stack data'''
    #Attributes
    items = []
    maxsize = 0

    #Methods
    def push(self,item):
        self.items.append(item)

    def pop(self,item):
        self.items.pop()

    def isEmpty(self):
        if self.items:
            return False
        else:
            return True

    def size(self):
        self.maxsize = len(self.items)

The error is 1993 lines long so I will only show the main errors that keep repeating.

Traceback (most recent call last):
  File "C:\Users\Luke\Documents\A-Level-Work\A2\Computing\COMP 3\stack_queues_gui.py", line 92, in <module>
    Main()
  File "C:\Users\Luke\Documents\A-Level-Work\A2\Computing\COMP 3\stack_queues_gui.py",     line 84, in Main
    mainWindow = MainWindow()
  File "C:\Users\Luke\Documents\A-Level-Work\A2\Computing\COMP 3\stack_queues_gui.py",     line 13, in __init__
    self.createUI()
  File "C:\Users\Luke\Documents\A-Level-Work\A2\Computing\COMP 3\stack_queues_gui.py", line 23, in createUI
    self.mainViewWidget.setLayout(self.mainGrid(self.stack))
  File "C:\Users\Luke\Documents\A-Level-Work\A2\Computing\COMP 3\stack_queues_gui.py",     line 62, in mainGrid
    self.pushButton.clicked.connect(self.pushStack(self.stack))
  File "C:\Users\Luke\Documents\A-Level-Work\A2\Computing\COMP 3\stack_queues_gui.py",         line 71, in pushStack

The error keeps repeating with lines 62 and 71 only until python exceeds its maximum recursion depth.

The massive error only occurred once I had added pushStack so I have no idea how to fix this as I only have A2-level python knowledge. The program was fine with Stack being called into MainWindow and being used in mainGrid.

Upvotes: 1

Views: 117

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1121914

You created an infinite recursion:

 def mainGrid(self,stack):
     # ...
    self.pushButton.clicked.connect(self.pushStack(self.stack))

calls

def pushStack(self,stack):
    # ...
    self.mainViewWidget.setLayout(self.mainGrid(self.stack))

See the self.mainGrid() there? But self.mainGrid() calls self.pushStack(), and nowhere in your code do you break out of that loop.

You need to remove one or the other call here, or determine what the recursive call is supposed to achieve and create conditions where one of the two methods does not call the other.

Most likely you don't have to recreate the self.mainViewWidget from scratch each time you push something on the stack. Also, if you meant self.pushStack to be called when the pushButton is clicked (and not when you connect up the action to the button), you need to not call it directly:

self.pushButton.clicked.connect(self.pushStack)

Note that now the self.pushStack method is connected, not the return value.

There is no reason to pass self.stack to self.pushStack() here; that method can access self.stack without the stack argument too

def pushStack(self):
    # ...
    self.stack.push(item)

Upvotes: 2

Related Questions