2013-04-22 2 views
0

Я хочу использовать Qt для предоставления графического интерфейса для коллекции объектов, определенных пользователем. Например, я могу иметь следующий класс питона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. В адресной книге Tutorial фактические данные (которые в этот случай - адреса разных лиц) хранится в 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: Вид, чтобы отобразить имена объектов 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() 
1

Я никогда не использовал Python, но я полагаю, что порт сохраняет основной способ Qt делает MVC. В этом случае я не уверен, что многое можно улучшить по документации Qt, в частности here и в QListViewdocumentation. В MVC Qt вы можете использовать все, что хотите, в качестве базовой структуры данных, содержащей ваши данные. То, что вы предоставляете - это ключ, - это основные функции (чисто виртуальные в QAbstractListModel), которые сообщают QListView о том, как получить доступ и при необходимости изменить ваши данные. Существует также базовая функция rowCount, которую вам нужно реализовать, что самоочевидно.

Когда вы внедрили их в подкласс QAbstractListModel, просто используйте QListView::setModel, чтобы установить модель для QListView, и все должно работать. Снова то, что я вам дал, - это на C++, но я ожидаю, что вы можете перевести его на Python-Qt довольно прямолинейно.

+0

Спасибо, это полезно. Я думаю, работая с QAbstractListModel, я могу понять это. Если я получу что-то, я отправлю источник сюда. Если кто-то напишет пример на C++ для страниц Qt, который также будет очень приятным. –

+0

@MartinisGroup Счастливые помочь. –

Смежные вопросы