2013-04-22 81 views
0

我想用Qt为用户定义对象集合提供一个图形界面。例如,我可能有以下Python类Qt:用户定义对象列表

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. 地址簿不显示如何显示现有地址簿条目的列表。

我认为模型/视图体系结构的概念与此相关,因此我已阅读model/view文档。这个文档似乎强调使用Qt内置的容器类。这很好,但最后我想把它包装在我自己的数据结构中,而且我还没有找到解释如何做到这一点。

问题:

  1. 我如何编写代码通过Qt的列表或其他图形界面来揭露我自己预先存在的数据?
  2. 有关模型/视图系统的文档非常混乱。 Qt如何期待数据和关联的可视类被组织?

我致力于理解并改进他人的文档。如果这个线程吸引注意力和有用的信息,我会尝试在Qt网页上正确存档。

谢谢

回答

0

下面的代码做我想要的。我使用Qt Designer来制作具有以下元素的UI:

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

而且现在的代码...

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() 
1

我从来没有使用Python,但我相信该端口保留了基本方式的Qt做MVC。在那种情况下,我不确定在Qt​​的文档上有很多改进,特别是hereQListViewdocumentation。在Qt的MVC中,你可以自由地使用任何你想要的作为保存你的数据的底层数据结构。你所提供的 - 这是关键 - 是基本功能(纯虚拟QAbstractListModel),它告诉QListView如何访问和如果需要修改你的数据。还有一个基本功能rowCount您需要执行,这是不言自明的。

当您在QAbstractListModel子类中实现了这些功能时,只需使用QListView::setModel即可为QListView设置模型,并且所有内容都应该正常工作。我已经给了你的是C++,但我希望你可以相当直接地将它翻译成Python-Qt。

+0

谢谢,这很有用。我想通过使用QAbstractListModel我可以弄明白。如果我得到了一些工作,我会在这里发布源代码。如果有人会用C++编写一个Qt页面的例子,那也是非常好的。 – 2013-04-22 18:34:19

+0

@MartinisGroup乐于助人。 – 2013-04-22 18:35:01