Pyqt小部件在被删除后徘徊不前

时间:2016-11-14 12:27:25

标签: python user-interface layout pyqt

我有一个QVBox布局,包含QVBox布局和QHBox布局。我使用其他QVBox布局来保存动态创建的GUI对象和QHBox布局来保存添加/删除这些对象的按钮。如果我将QHBox定位在QVBox的顶部,一切都能正常工作,但是当我尝试将QHBox定位在QVBox下面时,对象没有被正确删除但是留在那里"挥之不去"在QHBox之上。我将上传图片以证明问题。第一张图片是在采取行动之前,第二张是在创建新对象之后,第三张图片是在删除对象之后

Before action

After creating new component

After deleting the component

以下是创建和删除新对象的代码

    def addClient(self):
            if (len(self.clients) < 5):
                    client = clientComponent(self)
                    self.clients.append(client)
                    index = len(self.clients)-1
                    self.vLayout3.addWidget(self.clients[index])

                    client.setIndex(index)

                    self.clients[index].startButton.clicked.connect(partial(self.threadcontrol, '2', client.getIndex()))
                    self.clients[index].stopButton.clicked.connect(partial(self.clientstop, '0', client.getIndex()))

    def deleteClient(self):
            if (len(self.clients) > 1):
                    self.vLayout3.removeWidget(self.clients.pop())

这是我完成布局的地方

    def initializeUi(self):

            self.mainWidget = QWidget(self)
            self.setCentralWidget(self.mainWidget)

            self.mainLayout = QVBoxLayout(self.mainWidget)
            self.hLayout1 = QHBoxLayout()
            self.hLayout2 = QHBoxLayout()
            self.vLayout1 = QVBoxLayout()
            self.vLayout2 = QVBoxLayout()
            self.vLayout3 = QVBoxLayout()

            self.addServer()
            self.addClient()

            self.serverBox = QGroupBox('Server')
            self.clientBox = QGroupBox('Client')

            self.traffic1 = QLabel('0.0Mb/s', self)
            self.traffic1.setAlignment(Qt.AlignRight)
            self.traffic2 = QLabel('0.0Mb/s', self)
            self.traffic2.setAlignment(Qt.AlignCenter)
            self.traffic3 = QLabel('0.0Mb/s', self)
            self.traffic3.setAlignment(Qt.AlignLeft)

            self.newClientButton = QPushButton('+', self)
            self.deleteClientButton = QPushButton('-', self)

            self.hLayout1.addWidget(self.traffic1)
            self.hLayout1.addWidget(self.traffic2)
            self.hLayout1.addWidget(self.traffic3)
            self.hLayout2.addWidget(self.newClientButton)
            self.hLayout2.addWidget(self.deleteClientButton)
            self.vLayout2.addLayout(self.vLayout3)
            self.vLayout2.addLayout(self.hLayout2)

            self.mainLayout.addWidget(self.plot)
            self.mainLayout.addLayout(self.hLayout1)
            self.serverBox.setLayout(self.vLayout1)
            self.mainLayout.addWidget(self.serverBox)
            self.clientBox.setLayout(self.vLayout2)
            self.mainLayout.addWidget(self.clientBox)

2 个答案:

答案 0 :(得分:1)

当您从布局中删除窗口小部件时,它仍然保留在父窗口小部件中 object tree,因此它会显示在任何布局之外。 要从对象树中删除小部件,请调用widget.setParent(None)widget.deleteLater()也有效 这是我的MCVE(Qt4,Py2.7):

from PyQt4.QtGui import (QApplication, QWidget, QPushButton,
                         QVBoxLayout, QHBoxLayout)

app=QApplication([])

self = QWidget()
main_layout = QVBoxLayout(self)

clients = []
l2 = QHBoxLayout()
main_layout.addLayout(l2)

b_add = QPushButton('add', self)
l2.addWidget(b_add)

def addClient():
    b = QPushButton(str(len(clients)), self)
    clients.append(b)
    main_layout.addWidget(b)
b_add.clicked.connect(addClient)

b_rm = QPushButton('rm', self)
l2.addWidget(b_rm)

def deleteClient():
    b = clients.pop()
    main_layout.removeWidget(b)
    # comment out two following lines to get the behavior you observe
    b.setParent(None)
    self.adjustSize()
b_rm.clicked.connect(deleteClient)


self.show()
app.exec_()

在我的系统上,我还必须在删除后调用self.adjustSize()以调整主窗口的大小

答案 1 :(得分:1)

发生这种情况是因为从布局中删除主窗口后,主窗口仍然是客户端窗口小部件的父窗口。如果您将窗口小部件指定为父窗口小部件而不将其添加到任何布局,则会看到类似的行为。

删除父级应该可以解决问题。

def deleteClient(self):
    if (len(self.clients) > 1):
        client = self.clients.pop()
        self.vLayout3.removeWidget(client)
        client.setParent(None)

您可能还需要拨打adjustSize来调整窗口大小以适应剩余的小部件