在PyQt中清空QWidget布局

1 投票
2 回答
1672 浏览
提问于 2025-04-18 10:21

我正在尝试用PYQT创建一个图形用户界面(GUI),这个界面上会显示几张图片和一些按钮。每当用户点击“下一步”时,我希望能显示新的图片。不过,当我尝试这样做时,出现了一个错误,提示:

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

我该如何从QWidget中删除布局呢?

这是我的代码:

#!/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()

2 个回答

1

这里的问题是,每次调用 next() 时,你都在重新初始化整个用户界面,这样每次都会创建一个新的布局,然后试图用 self.setLayout(hbox) 把它赋值给你的控件。

其实你真正想做的只是改变标签中显示的图片。如果你把 initUI 函数中的标签改成 Example 类的成员,那么 next 函数可以像下面这样写:

def next(self):
  self.pageNumber += 1
  pixmap = QtGui.QPixmap(self.CTlist[self.pageNumber])
  self.lbl1.setPixmap(pixmap)
  self.lbl2.setPixmap(pixmap)
0

根据文档的说明:

这个方法是用来为这个小部件设置布局管理器的。

如果这个小部件上已经有了一个布局管理器,你就不能再给它安装一个新的。你必须先删除现有的布局管理器(可以通过调用layout()来获取),然后才能使用setLayout()来设置新的布局。

如果你想设置的布局管理器是在另一个小部件上的,setLayout()会把这个布局转移过来,并将其设置为当前小部件的布局管理器。

所以,你可以简单地把布局转移到一个临时的小部件上(链接):

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()

撰写回答