-1

所以基本上我正在尝试使用其中的一些 QPushButtons 更新 QGroupBox,这是“更新”方法,它总是在列表更改后立即调用:

    def repaintList(self):    

        btn_ls = []

        for i in range(len(self.list)):
            btn_ls.append(buttons.QPushButton("t"))


        layout = QVBoxLayout()

        for i in range(len(btn_ls)):
            layout.addWidget(btn_ls[i])


这很简单,我有一个为我更新列表的方法,并且我已经使用 print(len(self.list)) 和 print(btn_ls) 测试了功能,足以知道列表更新有效,并且 btn_ls 是制作正确,但我不确定为什么它没有在实际屏幕上更新。

我已经制作了一个简化版本的示例,说明我正在尝试完成的工作:

import sys
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *


class TestWindow(QWidget):

    def __init__(self):

        super(TestWindow,self).__init__()

        self.list = []

        self.cont = TestContainer(self.list, "Test Box",  self)

        self.adder = AdderButton("Add one", self, self.list, self.cont)


        layout = QVBoxLayout()

        layout.addWidget(self.cont)


        self.setLayout(layout)
        self.setGeometry(200,200,200,200)



class TestContainer(QGroupBox):


    def __init__(self,ls,ttl,pare):

        super(TestContainer,self).__init__(ttl,pare)

        self.list = ls


        self.repaintButtons()




    def repaintButtons(self):

        btn_ls = []

        for i in range(len(self.list)):
            btn_ls.append(QPushButton(str(i),self))


        print(self.list)
        layout = QVBoxLayout()
        

        for i in range(len(btn_ls)):

            layout.addWidget(btn_ls[i])


        
        self.setLayout(layout)



class AdderButton(QPushButton):


    def __init__(self,txt,pare,ls,displ):
        super(AdderButton,self).__init__(txt,pare)

        self.disp = displ
        self.list = ls

        self.clicked.connect(self.addOne)


    def addOne(self):
        self.list.append(1)
        self.disp.repaintButtons()





    
def main():


    app = QApplication(sys.argv)

    tw = TestWindow()


    tw.show()

    app.exec()



if __name__ == "__main__":
    main()

期望的结果是,每次我按下按钮时,屏幕上都会出现一个新的 QPushButton ......

4

2 回答 2

1

在做了更多的研究之后,我发现了 update() 函数,它基本上重新绘制了 QGroupBox。它的工作原理是一次添加一个按钮,并在每次添加按钮时更新。

import sys
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *


class TestWindow(QWidget):

    def __init__(self):

        super(TestWindow,self).__init__()

        self.list = []

        self.cont = TestContainer(self.list, "Test Box",  self)

        self.adder = AdderButton("Add one", self, self.list, self.cont)


        layout = QVBoxLayout()

        layout.addWidget(self.cont)


        self.setLayout(layout)
        self.setGeometry(200,200,200,200)



class TestContainer(QGroupBox):


    def __init__(self,ls,ttl,pare):

        super(TestContainer,self).__init__(ttl,pare)

        self.list = ls
        self.layout = QVBoxLayout()


        self.setLayout(self.layout)


    def addButton(self):
        
        self.layout.addWidget(QPushButton("thing"))
        



class AdderButton(QPushButton):


    def __init__(self,txt,pare,ls,displ):
        super(AdderButton,self).__init__(txt,pare)

        self.disp = displ
        self.list = ls

        self.clicked.connect(self.addOne)


    def addOne(self):
        self.list.append(1)
        self.disp.addButton()
        self.disp.update()





    
def main():


    app = QApplication(sys.argv)

    tw = TestWindow()


    tw.show()

    app.exec()



if __name__ == "__main__":
    main()

于 2020-06-27T10:54:33.803 回答
0

我必须使用self.layout()而不是layout查看小部件。

def repaintButtons(self):

    btn_ls = []

    for i in range(len(self.list)):
        btn_ls.append(QPushButton(str(i),self))


    print(self.list)

    layout = QVBoxLayout()
    self.setLayout(layout)  # it has to be before `self.layout()`

    for i in range(len(btn_ls)):

        self.layout().addWidget(btn_ls[i])

顺便说一句:self.setLayout()必须在之前self.layout()


但还有其他问题。

再次使用

 layout = QVBoxLayout() 
 self.setLayout(layout)

不会layout删除以前的按钮,也不会删除以前的按钮,最后会再次将相同的按钮添加到布局中。

您只需要在布局中添加新按钮,而不是再次添加所有按钮。

或者您必须在再次添加之前从布局中删除小部件。


编辑:

添加新按钮而不删除先前按钮的代码

import sys
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *


class TestWindow(QWidget):

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

        self.list = []

        self.container = TestContainer("Test Box", self, self.list)

        self.adder = AdderButton("Add one", self, self.container)

        layout = QVBoxLayout()

        layout.addWidget(self.container)

        self.setLayout(layout)
        self.setGeometry(200,200,200,200)


class TestContainer(QGroupBox):

    def __init__(self, title, parent, lst):
        super(TestContainer,self).__init__(title, parent)

        self.list = lst

        layout = QVBoxLayout()
        self.setLayout(layout)

        # create buttons at start using `self.list`
        for item in self.list:
            self.layout().addWidget(QPushButton(str(item), self))

    def addButton(self, item):
        # add new item to `self.list` and create new button
        self.list.append(item)
        self.layout().addWidget(QPushButton(str(item), self))


class AdderButton(QPushButton):

    def __init__(self, text, parent, target):
        super(AdderButton,self).__init__(text, parent)

        self.target = target

        self.clicked.connect(self.addOne)

    def addOne(self):
        self.target.addButton(1)

    
def main():
    app = QApplication(sys.argv)
    tw = TestWindow()
    tw.show()
    app.exec()


if __name__ == "__main__":
    main()

有一些示例如何删除项目,但它们对我不起作用

于 2020-06-26T18:57:52.137 回答