1

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.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
user1921942
  • 121
  • 1
  • 2
  • 9

1 Answers1

2

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)
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Thanks that had been driving me mad for ages! The reason it re-makes the screen is that when the program is finished it will update the text edit box to show all the data in the stack. Unless you meant that there is a way to refresh it with new data, which would make things a lot easier but i don't know how. – user1921942 Nov 07 '13 at 17:10
  • I am not too familiar with Qt, to be honest. Does [this question](http://stackoverflow.com/questions/10416582/replacing-layout-on-a-qwidget-with-another-layout) help? – Martijn Pieters Nov 07 '13 at 17:16
  • That is more to do with changing the layout than refreshing it with new data. – user1921942 Nov 07 '13 at 17:24