1

我有一个简单的PyQt4程序,每当我单击“确定”按钮并将其保存为二进制文件时,它都会包含 3 个详细信息(姓名、性别和地址)(出于测试目的,3 个详细信息在程序中被硬编码)。然后稍后将加载该信息并将其显示在QTableWidget.

这是我的程序的布局:

它有 2 个脚本:DContainer.pyData_Main.py

在此处输入图像描述

容器.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))

数据_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 方法中。

正确地,它应该只在表格中显示一项,除非我给新的人对象以不同的名称。

是什么导致了问题?

4

1 回答 1

1

PersonContainer.add单击“确定”按钮时,该方法被调用两次:

  1. 直接从MainDialog.OK方法
  2. 间接地从MainDialog.Update方法,用self.persons.load()

您可以向该方法添加一个可选参数以Update触发对 的调用load

def Update(self, load=False):
    self.table.clear()
    if load:
        self.persons.load()

并在方法中使用loadset to调用此方法: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)
于 2013-09-25T21:36:08.623 回答