好的,所以我认为展示我正在尝试完成的事情的最佳方式是视觉化,所以我创建了一个可重复的示例来说明我正在尝试做的事情,而且奇怪的是......它工作得非常好。这里是
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))
如果我遗漏了什么或者我没有正确沟通,请告诉我,对不起,我没有把所有的东西都放在首位!