0

好的,所以我认为展示我正在尝试完成的事情的最佳方式是视觉化,所以我创建了一个可重复的示例来说明我正在尝试做的事情,而且奇怪的是......它工作得非常好。这里是

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

big_ar = ["1","2","3"]


class MyMainWindow(QWidget):

    def __init__(self):
        super(MyMainWindow,self).__init__()
        self.setGeometry(300,300,300,300)

        self.initUI()


    def initUI(self):
        self.lay = QVBoxLayout()

        self.window_opener = WindowOpenerButton("open window",self)
        self.group_box = UpdatingGroupBox(self)

        self.lay.addWidget(self.window_opener)
        self.lay.addWidget(self.group_box)

        self.setLayout(self.lay)
        


    def cust_update(self):

        self.group_box.addButton()
        self.group_box.update()
        



class WindowOpenerButton(QPushButton):

    def __init__(self,txt,par):
        super(WindowOpenerButton,self).__init__(txt,par)

        self.clicked.connect(self.openWin)


    def openWin(self):
        
        self.smallWindow = MySmallWindow(psp=self.parentWidget())
        
        self.smallWindow.show()




class MySmallWindow(QWidget):

    def __init__(self,psp=None,parent=None):
        
        super(MySmallWindow,self).__init__(parent)
        self.setGeometry(100,100,100,100)
        
        self.pseudo_parent = psp
        
        self.populate()


    

    def populate(self):
        self.layout = QVBoxLayout()

        self.line_edit = QLineEdit(self)
        
        self.done = DoneButton("done",self,self.line_edit)
        

        self.layout.addWidget(self.line_edit)
        self.layout.addWidget(self.done)

        self.setLayout(self.layout)
        

    def closeEvent(self,event):

        if self.pseudo_parent != None:
            self.pseudo_parent.cust_update()

            
class UpdatingGroupBox(QGroupBox):

    def __init__(self,par):

        super(UpdatingGroupBox,self).__init__(par)

        self.layout = QVBoxLayout()

        self.addPreexisting()
        self.setLayout(self.layout)

    def addPreexisting(self):
        global big_ar

        for i in range(len(big_ar)):
            self.layout.addWidget(QPushButton(big_ar[i],self))

    def addButton(self):
        global big_ar
        
        self.layout.addWidget(QPushButton(big_ar[ len(big_ar) - 1],self))
            

class DoneButton(QPushButton):

    def __init__(self,txt,par,src):

        super(DoneButton,self).__init__(txt,par)

        self.txt_source = src
        

        self.clicked.connect(self.addToArr)

    def addToArr(self):

        global big_ar

        big_ar.append(self.txt_source.text())
        self.parentWidget().close()
        print(big_ar)


def main():
    app = QApplication(sys.argv)
    app.setStyle("Fusion")


    x = MyMainWindow()

    x.show()


    app.exec()


if __name__ == "__main__":
    main()


现在这个例子概述了我正在尝试做的非常准确和简单的事情,它从小窗口的行编辑中获取字符串,并将其变成大窗口的 qgroupbox 中的按钮,然后立即更新。这个例子和我的代码之间的唯一区别是,我没有使用全局数组添加到 qgroupbox,而是使用了一个实例变量,看看。

    def cust_update(self):
        mem_f = open(self.file,"r")
        
        raw_file_ml = mem_f.read().split("{")[1]

        file_ml = raw_file_ml.split(";")


        self.list.append(Member(file_ml[len(file_ml) - 2]))


        mem_f.close()

   
        self.mb_gb.addButton()
        
        self.mb_gb.update()

这是我实际程序的 cust_update 方法(您可以忽略前几行),而 mb_gb 是一个 MemberList,它是这样的:

class MemberList(comps.MyButtonList): #list of memButtons derived from members.txt
    

    def __init__(self,ttl,labl_ls,par,**kwargs): 
        super(MemberList,self).__init__(ttl,labl_ls,par,**kwargs)

        
        self.layout = QVBoxLayout()

        self.addPrexisting()

        self.setLayout(self.layout)

        
    def addPrexisting(self):
        for i in range(len(self.list)):
            self.layout.addWidget(QPushButton(self.list[i].fullName()))
        
    def addButton(self):
        nb = QPushButton(self.list[len(self.list) - 1])
        
        self.layout.addWidget(nb)

self.list 表示成员列表,正如您在 cust_update 方法中看到的那样,该列表已更新。MemberList 然后获取列表的最后一个元素并将其制成一个按钮,然后将其添加到其布局中。

它与第一个示例的 ugb 非常相似,但是由于某种原因,当调用 cust_event 时,即使它将按钮添加到布局中,它也没有被绘制(通过打印调试发现)并且我已经尝试使用 repaint()

编辑:

我现在看到了对 Member 和 MyButtonList 是什么的困惑,我一开始没有解释它们的原因是因为我发现没有必要,因为代码的这些部分正在工作(我的错!)。这是成员类:

class Member:

    def __init__(self,info_str):
        info_ar = info_str.split(",")
        self.first_name = info_ar[0]
        self.last_name = info_ar[1]
        self.idnum = info_ar[2]
        self.grade_when_joined = info_ar[3]
        self.gender = info_ar[4]
        self.position = info_ar[5]
        self.date_joined = info_ar[6][0:len(info_ar[6])]

        
        
    def fullName(self):
        
        return self.first_name.capitalize() + " " + self.last_name.capitalize()

    def __str__(self):
        return (self.fullName() + ": " + self.id() + " " + self.gender + " " + self.getPosition()  + " " + str(self.date_joined))
    

    def id(self):
        lln = self.last_name.lower()
        return lln + str(self.idnum)

    def dateJoined(self):
        y = int(self.date_joined[0:4])
        m = int(self.date_joined[5:7])
        d = int(self.date_joined[8:10])

        return dt.date(y,m,d)


    def sex(self):

        s = "Other"

        if self.gender == 'm':
            s  = "Male"
        elif self.gender == 'f':
            s = "Female"

        return s


    def getPosition(self):

        pos = "Member"

        if self.position == "o":
            pos = "Officer"
        elif self.position == "v":
            pos = "Vice President"
        elif self.position == "p":
            pos = "President"


        return pos


    def idInt(self):
        return int(self.idnum)

在closeEvent之前,根据用户输入在txt文件中添加一行,格式如下

名字,姓氏,ID#,年级,性别,职位,Date_When_Joined

当 close 事件发生时,cust_update 方法读取文件,并通过“;”将其拆分为单个成员 并取最后一个(刚刚添加的成员)并将其制成带有名字的 qpushbutton。

MyButtonList 类与 MemberList 类几乎相同,唯一的区别在于按钮上的内容,所以它看起来像这样:

class MyButtonList(MyGroupBox):

    def __init__(self,ttl,lab_ls,par,**kwargs):
        super(MyButtonList,self).__init__(title=ttl,pare=par,**kwargs)
        self.setUpdatesEnabled(True)

        self.label_ls = lab_ls

        self.list = self.parentWidget().list

        self.layout = QVBoxLayout()

        self.addPrexisting()

        self.setLayout(self.layout)


    def addPrexisting(self):
        for i in range(len(self.list)):
            self.layout.addWidget(QPushButton(str(i),self))
        

    def addButton(self):
        self.layout.addWidget(QPushButton("added",self))

如果我遗漏了什么或者我没有正确沟通,请告诉我,对不起,我没有把所有的东西都放在首位!

4

0 回答 0