2013-04-22 77 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