1

I am trying to create a gui using PYQT that displays a couple of pictures and buttons. Every time the user clicks next, I want new pictures to appear. However, when I try to do this, I get an error saying:

Attempting to set QLayout "" on Example "", which already has a layout

how can I delete the layout from the QWidget?

Here is my code:

#!/usr/bin/env.python

import sys
from PyQt4 import QtGui, QtCore


class Example(QtGui.QWidget):

  def __init__(self):
    super(Example, self).__init__()

    self.pageNumber = 1
    self.CTlist = ('ct.png', 'ct2.png', 'ct3.png')
    self.initUI(self.pageNumber)

  def initUI(self,page):    
    lbl1 = QtGui.QLabel(self)
    button1 = QtGui.QRadioButton('Picture 1')

    lbl2 = QtGui.QLabel(self)
    button2 = QtGui.QRadioButton('Picture 2')

    button3 = QtGui.QPushButton('Next')
    button3.clicked.connect(self.next)

    pixmap = QtGui.QPixmap(self.CTlist[page])
    lbl1.setPixmap(pixmap)
    lbl2.setPixmap(pixmap)

    vbox1 = QtGui.QVBoxLayout()
    vbox1.addWidget(lbl1)
    vbox1.addWidget(button1)

    vbox2 = QtGui.QVBoxLayout()
    vbox2.addWidget(lbl2)
    vbox2.addWidget(button2)

    vbox3 = QtGui.QVBoxLayout()
    vbox3.addWidget(button3)

    hbox = QtGui.QHBoxLayout()
    hbox.addLayout(vbox1)
    hbox.addLayout(vbox2)
    hbox.addLayout(vbox3)

    self.setLayout(hbox)

    self.move(300,200)
    self.setWindowTitle('Choose which picture you like more')
    self.show()    

  def next(self):
      self.pageNumber += 1
      self.initUI(self.pageNumber)


def main():
  app = QtGui.QApplication(sys.argv)
  ex = Example()
  sys.exit(app.exec_())

if __name__== '__main__':
  main()
mechapman
  • 25
  • 6

2 Answers2

1

The problem here is that you are reinitialising your entire UI every time next() is called, which is creating a new layout every time and trying to assign that to your widget with self.setLayout(hbox).

What you really want to do is just change the pixmap being displayed inside your labels. If you change your initUI function to make the labels members of your Example class, then the next function can look something like this

def next(self):
  self.pageNumber += 1
  pixmap = QtGui.QPixmap(self.CTlist[self.pageNumber])
  self.lbl1.setPixmap(pixmap)
  self.lbl2.setPixmap(pixmap)
user3419537
  • 4,740
  • 2
  • 24
  • 42
  • The only problem is that there aren't a set number of pictures to be displayed on a page, in this example I had just made one page. However, I think this might be the cleaner solution if there were the same number of pictures per page. Right now I have a for-loop making labels based on how many pictures are on a certain page, and I can't figure out how to use this method. – mechapman Jun 23 '14 at 06:52
  • You still do not need to recreate the entire UI every time. You could, for example, create another widget to contain the pictures and add this to the layout of your main widget – user3419537 Jun 23 '14 at 11:14
0

According the docs:

Sets the layout manager for this widget to layout.

If there already is a layout manager installed on this widget, QWidget won't let you install another. You must first delete the existing layout manager (returned by layout()) before you can call setLayout() with the new layout.

If layout is the layout manger on a different widget, setLayout() will reparent the layout and make it the layout manager for this widget.

So, you can simply reparent the layout to a temporary widget (link):

def initUI(self,page):

    if self.layout():
        QtGui.QWidget().setLayout(self.layout())

    lbl1 = QtGui.QLabel(self)
    button1 = QtGui.QRadioButton('Picture 1')

    lbl2 = QtGui.QLabel(self)
    button2 = QtGui.QRadioButton('Picture 2')

    button3 = QtGui.QPushButton('Next')
    button3.clicked.connect(self.next)

    pixmap = QtGui.QPixmap(self.CTlist[page])
    lbl1.setPixmap(pixmap)
    lbl2.setPixmap(pixmap)

    vbox1 = QtGui.QVBoxLayout()
    vbox1.addWidget(lbl1)
    vbox1.addWidget(button1)

    vbox2 = QtGui.QVBoxLayout()
    vbox2.addWidget(lbl2)
    vbox2.addWidget(button2)

    vbox3 = QtGui.QVBoxLayout()
    vbox3.addWidget(button3)

    hbox = QtGui.QHBoxLayout()
    hbox.addLayout(vbox1)
    hbox.addLayout(vbox2)
    hbox.addLayout(vbox3)

    self.setLayout(hbox)

    self.move(300,200)
    self.setWindowTitle('Choose which picture you like more')
    self.show()
Community
  • 1
  • 1
NorthCat
  • 9,643
  • 16
  • 47
  • 50