0

I want to use Qt to provide a graphical interface to a collection of user defined objects. For example I may have the following python class

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

and a linked list of instances

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

I now want to use Qt to present a browsable list of the elements in people. Perhaps I want to allow certain information to be displayed in various text boxes when the user clicks on the names of people in this list.

The Qt documentation contains the example of an address book which is pretty good match to my own case, but there are two crucial things missing from this tutorial

  1. In the address book tutorial the actual data (which in this case are the addresses of various persons) is stored in a QMap. Each name and address is represented as a QString. The QMap maps names to addresses. This is fine for that simple example, but I want to wrap a Qt interface around my own data. How is this done?
  2. The address book does not show how to display a list of existing address book entries.

I think the notion of the model/view architecture is relevant to this so I have read the model/view documentation. This documentation seems to strongly emphasize the use of Qt built-in container classes. This is fine but in the end I want to wrap this around my own data structures and I have not found a an explanation of how to do this.

QUESTIONS:

  1. How do I write code to expose my own pre-existing data through a Qt list or other graphical interface?
  2. The documentation on the model/view system is really confusing. How does Qt expect the data and associated viewable classes to be organized?

I am dedicated to understanding this and improving the documentation for others. If this thread attracts attention and useful information I will attempt to have it properly archived on the Qt webpage.

Thank you

4

2 回答 2

1

我从未使用过 Python,但我认为该端口保留了 Qt 执行 MVC 的基本方式。在这种情况下,我不确定 Qt 的文档有什么需要改进的地方,尤其是这里QListView 文档中。在 Qt 的 MVC 中,您可以随意使用任何您想要的作为保存数据的底层数据结构。您提供的——这是关键——是基本功能(纯虚拟 in QAbstractListModel),它告诉 QListView 如何访问以及在需要时修改您的数据。您还需要实现一个基本功能rowCount,这是不言自明的。

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

于 2013-04-22T16:28:12.507 回答
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()
于 2013-04-29T19:33:07.600 回答