我有一个简单的PyQt4
程序,每当我点击OK按钮并将其保存为二进制文件时,它会接收3个详细信息(姓名,性别和地址)(3个细节在程序中被硬编码用于测试目的)。然后,稍后将加载该信息并将其显示在QTableWidget
。
这是我的程序布局:
它有2个脚本: DContainer.py 和 Data_Main.py
Dcontainer.py
import bisect
from PyQt4 import QtCore
class Person(object):
def __init__(self, Name = None, Gender = None , Address = None ):
self.Name = Name
self.Gender = Gender
self.Address = Address
class PersonContainer(object):
def __init__(self):
self.__fname = QtCore.QString("mydatabase.mqb")
self.__persons = []
self.__personFromId = {}
def __iter__(self):
for pair in iter(self.__persons):
yield pair[1]
def __len__(self):
return len(self.__persons)
def Clear(self):
self.__persons = []
self.__personFromId ={}
def add(self,person):
if id(person)in self.__personFromId:
return False
key = person.Name
bisect.insort_left(self.__persons, [key,person])
self.__personFromId[id(person)] = person
return True
def save(self):
fh = QtCore.QFile(self.__fname)
if not fh.open(QtCore.QIODevice.WriteOnly):
raise IOError , unicode(fh.errorString())
stream = QtCore.QDataStream(fh)
for key, person in self.__persons:
stream << person.Name << person.Gender << person.Address
def load(self):
fh = QtCore.QFile(self.__fname)
if not fh.open(QtCore.QIODevice.ReadOnly):
raise IOError , unicode(fh.errorString())
stream = QtCore.QDataStream(fh)
while not stream.atEnd():
Name = QtCore.QString()
Gender = QtCore.QString()
Address = QtCore.QString()
stream >> Name >> Gender >> Address
self.add(Person(Name,Gender,Address))
Data_Main.py
import sys
from PyQt4 import QtCore,QtGui
import DContainer
class MainDialog(QtGui.QDialog):
def __init__(self, parent = None):
super(MainDialog,self).__init__(parent)
self.InitGui()
self.persons = DContainer.PersonContainer()
self.Update()
def InitGui(self):
buttonbox = QtGui.QDialogButtonBox(QtGui.QDialogButtonBox.Ok|QtGui.QDialogButtonBox.Cancel)
self.table = QtGui.QTableWidget()
layout = QtGui.QVBoxLayout()
layout.addWidget(self.table)
layout.addWidget(buttonbox)
self.setLayout(layout)
self.connect(buttonbox.button(buttonbox.Ok), QtCore.SIGNAL("clicked()"),self.OK)
def OK(self):
NewPerson = DContainer.Person(QtCore.QString('This is another test'),QtCore.QString('Male'),QtCore.QString('Strand Road'))
self.persons.add(NewPerson)
self.persons.save()
self.Update()
def Update(self):
self.table.clear()
self.persons.load()
self.table.setRowCount(len(self.persons))
self.table.setColumnCount(3)
for row,person in enumerate(self.persons):
item = QtGui.QTableWidgetItem(person.Name)
self.table.setItem(row,0,item)
def Main():
app = QtGui.QApplication(sys.argv)
dialog = MainDialog()
dialog.show()
app.exec_()
if __name__ == "__main__":
Main()
我的问题是每当我点击确定按钮时,它会创建多个表条目
第二次点击后
它不应该像我使用
那样创建多个表条目if id(person)in self.__personFromId:
return False
在Dcontainer.py中的Add方法中。
理所当然,它应该只显示表中的一个项目,除非我给新的person对象赋予不同的名称。
导致问题的原因是什么?
答案 0 :(得分:1)
单击“确定”按钮时,将调用PersonContainer.add
方法两次:
MainDialog.OK
方法MainDialog.Update
方法,self.persons.load()
您可以为Update
方法添加可选参数,以触发对load
的调用:
def Update(self, load=False):
self.table.clear()
if load:
self.persons.load()
并在load
方法中将True
设置为__init__
并调用此方法:
def __init__(self, parent = None):
super(MainDialog,self).__init__(parent)
self.InitGui()
self.persons = DContainer.PersonContainer()
self.Update(True)
顺便说一句,PyQt5不再支持旧式信号/插槽。这是如何写新风格:
buttonbox.accepted.connect(self.OK)
buttonbox.rejected.connect(self.reject)