mjaw10
mjaw10

Reputation: 11

PyQt4 QStackedLayout Switching Layout Error

I'm trying to get the buttons to work on a user interface I'm making with PyQt4. The windows change but the button only works once before I get the error NameError: name 'UI2Window' is not defined. I don't understand why I get this error as the code works fine the first time.

Help fixing this issue / finding a better way to switch layouts is appreciated.

A simplified version on my code is below.

Code from UI1.py:

import sys
from PyQt4.QtCore import*
from PyQt4.QtGui import *
from UI2 import *

class UI1Window(QMainWindow):
    def __init__(self):
        super().__init__()
        self.Widget = self.CreateMainLayout()
        self.StackedLayout = QStackedLayout()
        self.StackedLayout.addWidget(self.Widget)
        self.MainWidget = QWidget()
        self.MainWidget.setLayout(self.StackedLayout)
        self.setCentralWidget(self.MainWidget)

    def OnClicked(self):
        Window = UI2Window()
        self.StackedLayout.addWidget(Window)
        self.StackedLayout.setCurrentIndex(1)

    def CreateMainLayout(self):
        Widget = QWidget()
        self.VLayout = QVBoxLayout()
        self.Button = QPushButton("UI2")
        self.Button.clicked.connect(self.OnClicked)
        self.VLayout.addWidget(self.Button)     
        Widget.setLayout(self.VLayout)
        return Widget

def main():
    App = QApplication(sys.argv)
    ProgramWindow = UI1Window()
    ProgramWindow.show()
    App.exec_()

if __name__ == "__main__":
    main()

Code from UI".py:

import sys
from PyQt4.QtCore import*
from PyQt4.QtGui import *
from UI1 import *

class UI2Window(QMainWindow):
    def __init__(self):
        super().__init__()
        self.Widget = self.CreateMainLayout()
        self.StackedLayout = QStackedLayout()
        self.StackedLayout.addWidget(self.Widget)
        self.MainWidget = QWidget()
        self.MainWidget.setLayout(self.StackedLayout)
        self.setCentralWidget(self.MainWidget)

    def OnClicked(self):
        Window = UI1Window()
        self.StackedLayout.addWidget(Window)
        self.StackedLayout.setCurrentIndex(1)

    def CreateMainLayout(self):
        Widget = QWidget()
        self.VLayout = QVBoxLayout()
        self.Button = QPushButton("UI1")
        self.Button.clicked.connect(self.OnClicked)
        self.VLayout.addWidget(self.Button)     
        Widget.setLayout(self.VLayout)
        return Widget

def main():
    App = QApplication(sys.argv)
    ProgramWindow = UI2Window()
    ProgramWindow.show()
    App.exec_()

if __name__ == "__main__":
    main()

Upvotes: 0

Views: 575

Answers (2)

mjaw10
mjaw10

Reputation: 11

I got it working thanks to Controlix's help. The code is below if anyone else needs it.

Window Controller Code:

import sys
from PyQt4.QtCore import*
from PyQt4.QtGui import *
from UI1 import *
from UI2 import *

class Controller(QMainWindow):
    def __init__(self):
        super().__init__()
        self.ImportWindows()
        self.ConnectButtons()
        self.StackedLayout = QStackedLayout()
        self.StackedLayout.addWidget(self.Window1)
        self.StackedLayout.addWidget(self.Window2)
        self.MainWidget = QWidget()
        self.MainWidget.setLayout(self.StackedLayout)
        self.setCentralWidget(self.MainWidget)

    def OnClicked1(self):
        self.StackedLayout.setCurrentIndex(1)

    def OnClicked2(self):
        self.StackedLayout.setCurrentIndex(0)

    def ImportWindows(self):
        self.Window1 = UI1Window()
        self.Window2 = UI2Window()

    def ConnectButtons(self):
        self.Window1.Button.clicked.connect(self.OnClicked1)
        self.Window2.Button.clicked.connect(self.OnClicked2)

def main():
    App = QApplication(sys.argv)
    ProgramWindow = Controller()
    ProgramWindow.show()
    App.exec_()

if __name__ == "__main__":
    main()

Code For Windows:

import sys
from PyQt4.QtCore import*
from PyQt4.QtGui import *

class UI1Window(QMainWindow):
    def __init__(self):
        super().__init__()
        self.StackedLayout = QStackedLayout()
        self.StackedLayout.addWidget(self.CreateMainLayout())
        self.MainWidget = QWidget()
        self.MainWidget.setLayout(self.StackedLayout)
        self.setCentralWidget(self.MainWidget)

    def CreateMainLayout(self):
        Widget = QWidget()
        self.VLayout = QVBoxLayout()
        self.Button = QPushButton("UI2")
        self.VLayout.addWidget(self.Button)     
        Widget.setLayout(self.VLayout)
        return Widget

def main():
    App = QApplication(sys.argv)
    ProgramWindow = UI1Window()
    ProgramWindow.show()
    App.exec_()

if __name__ == "__main__":
    main()

Upvotes: 1

Controlix
Controlix

Reputation: 447

What is your goal? Can't you just create your two layouts add them to the QStackedLayout and then switch between index 0 and 1?

Something llike that to keep your code:

import sys
from PyQt4.QtCore import*
from PyQt4.QtGui import *
from UI2 import *

class UI1Window(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.StackedLayout = QStackedLayout()
        self.StackedLayout.addWidget(self.CreateMainLayout())
        self.StackedLayout.addWidget(self.CreateMainLayout2())
        self.MainWidget = QWidget()
        self.MainWidget.setLayout(self.StackedLayout)
        self.setCentralWidget(self.MainWidget)

    def OnClicked(self):
        self.StackedLayout.setCurrentIndex(1 if self.StackedLayout.currentIndex() == 0 else 0)

    def CreateMainLayout(self):
        Widget = QWidget()
        self.VLayout = QVBoxLayout()
        self.Button = QPushButton("UI2")
        self.Button.clicked.connect(self.OnClicked)
        self.VLayout.addWidget(self.Button)
        Widget.setLayout(self.VLayout)
        return Widget

    def CreateMainLayout2(self):
        Widget = QWidget()
        self.VLayout = QVBoxLayout()
        self.Button = QPushButton("UI1")
        self.Button.clicked.connect(self.OnClicked)
        self.VLayout.addWidget(self.Button)
        Widget.setLayout(self.VLayout)
        return Widget

def main():
    App = QApplication(sys.argv)
    ProgramWindow = UI1Window()
    ProgramWindow.show()
    App.exec_()

if __name__ == "__main__":
    main()

I assume you are new in python so please check naming convention here ;).

Upvotes: 2

Related Questions