Qt:用户定义对象的列表

时间:2013-04-22 16:16:49

标签: python qt

我想使用Qt为用户定义对象的集合提供图形界面。例如,我可能有以下python类

class Person(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

和实例的链接列表

people = [Person('John', 60), Person('Laura', 33)]

我现在想使用Qt在people中显示可浏览的元素列表。也许我想在用户点击此列表中的人名时允许在各种文本框中显示某些信息。

Qt文档包含address book的示例,它与我自己的案例非常匹配,但本教程中缺少两个关键的东西

  1. 在地址簿教程中,实际数据(在本例中是各种人的地址)存储在QMap中。每个名称和地址都表示为QString。 QMap将名称映射到地址。这对于这个简单的例子来说很好,但我想在我的自己的数据周围包装一个Qt接口。这是怎么做到的?
  2. 地址簿未显示如何显示现有地址簿条目列表。
  3. 我认为模型/视图架构的概念与此相关,所以我阅读了model/view文档。该文档似乎强烈强调使用Qt内置容器类。这很好,但最后我想把它包装在我自己的数据结构中,我还没有找到解释如何做到这一点。

    问题:

    1. 如何编写代码以通过Qt列表或其他图形界面公开我自己的预先存在的数据?
    2. 模型/视图系统的文档确实令人困惑。 Qt如何期望组织数据和相关的可查看类?
    3. 我致力于理解这一点并改进其他人的文档。如果这个帖子吸引了关注和有用的信息,我将尝试在Qt网页上正确存档。

      谢谢

2 个答案:

答案 0 :(得分:1)

我从未使用过Python,但我认为该端口保留了Qt执行MVC的基本方式。在这种情况下,我不确定Qt的文档有多大改进,特别是hereQListView documentation。在Qt的MVC中,您可以随意使用任何您想要的作为保存数据的基础数据结构。你提供的 - 这是关键 - 是基本功能(QAbstractListModel中的纯虚拟),它告诉QListView如何访问,如果需要,修改你的数据。还有一个你需要实现的基本功能rowCount,这是自我解释的。

当您在QAbstractListModel子类中实现这些内容时,只需使用QListView::setModelQListView设置模型,一切都应该正常工作。同样我给你的是C ++,但我希望你可以相当直接地将它翻译成Python-Qt。

答案 1 :(得分:0)

以下代码可以满足我的需求。我使用Qt Designer用以下元素制作一个ui

  • firstNameLineEdit - QLineEdit:在此输入一个人的名字。
  • lastNameLineEdit - QLineEdit:在此输入一个人的姓氏。
  • addPersonButton - QPushButton:按此按钮添加新的Person对象。从行编辑中检索名字和姓氏。
  • displayButton - QPushButton:将所有现有Person实例的列表打印到控制台以进行调试
  • listView - QListView:显示Person对象名称的视图

现在代码......

import PyQt4.QtCore as QtCore
import PyQt4.QtGui as QtGui
import PyQt4.uic as uic
import sys

class Person(object):
    def __init__(self, firstName, lastName):
        self.firstName = firstName
        self.lastName = lastName

class MyWidget(QtGui.QMainWindow):
    def __init__(self, people):
        QtGui.QMainWindow.__init__(self)
        uic.loadUi('MyWidget.ui', self)
        self.people=people
        self.addPersonButton.clicked.connect(self.addPerson)
        self.displayButton.clicked.connect(self.display)

        self.model = simpleModel(self.people)
        self.listView.setModel(self.model)

        self.show()

    def display(self):
        for i,p in enumerate(self.people):
            print "Person %i: %s %s"%(i, p.firstName, p.lastName)

    def addPerson(self):
        firstName = str(self.firstNameLineEdit.text())
        lastName = str(self.lastNameLineEdit.text())
        p = Person(firstName, lastName)
        self.model.insertRow(p)

class simpleModel(QtCore.QAbstractListModel):
    def __init__(self, dataList, parent=None):
        super(simpleModel, self).__init__(parent)
        self.list = dataList

    def rowCount(self, parent=QtCore.QModelIndex()):
        return len(self.list)

    def insertRow(self, data, parent=QtCore.QModelIndex()):
        self.beginInsertRows(parent, self.rowCount(), self.rowCount())
        self.list.append(data)
        self.endInsertRows()

    def data(self, index, role):
        if role == QtCore.Qt.DisplayRole:
            person = self.list[index.row()]
            return QtCore.QVariant("%s %s"%(person.firstName,person.lastName))
        elif role == QtCore.Qt.UserRole:
            person = self.list[index.row()]
            return person
        return QtCore.QVariant()    

def main():
    people=[Person('John','Doe')]
    app = QtGui.QApplication(sys.argv)
    ex = MyWidget(people)
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()