QTreeView: Daten richtig zählen

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Benutzeravatar
Sophus
User
Beiträge: 949
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

QTreeView: Daten richtig zählen

Beitragvon Sophus » Montag 17. Juli 2017, 13:51

Hallo Leute,

im nachfolgenden, ausführbaren Quelltext seht ihr sehr schnell was ich vorhabe. Ich habe euch auch ein kleines Bild mitgebracht, um das ganze zu verdeutlichen. Das Bild mit der Aufschrift "Original" zeigt das an, was bei dem derzeitigen Quelltext rauskommt, wenn das Programm ausgeführt wird. Das Bild mit der Aufschrift "Erwartet" zeigt, wie ich es gerne hätte. Und da sind wir auch schon beim Thema. Mein Anliegen ist es, dass sowohl bei Child-Einträgen (was ja offensichtlich funktioniert) als auch bei Parent-Einträgen die fortlaufende Zählung in der zweiten Spalte angezeigt wird. Derzeit sieht es so aus, dass die Zahlen 0, 4 und 8 nicht neben den Parent-Einträgen in der zweiten Spalte zu finden ist, sondern drunter. Ich stecke jetzt gedanklich irgendwie fest.

  1. #!/usr/bin/env python
  2. #-*- coding:utf-8 -*-
  3.  
  4. from sys import argv
  5.  
  6. from PyQt4.QtGui import QTreeView, QApplication, QAbstractItemView, \
  7.                         QStandardItemModel, QStandardItem
  8.  
  9. class TreeModelTester(QTreeView):
  10.     def __init__(self):
  11.  
  12.         QTreeView.__init__(self)
  13.  
  14.         # create attributes
  15.         self.count = 0
  16.  
  17.         self.setSelectionBehavior(QAbstractItemView.SelectRows)
  18.  
  19.         # create model
  20.         self.model = QStandardItemModel()
  21.  
  22.         # set header for model
  23.         self.model.setHorizontalHeaderLabels(['Column 1', 'Column 2'])
  24.         self.setModel(self.model)
  25.         self.setUniformRowHeights(True)
  26.  
  27.         self.populate_data()
  28.  
  29.     def populate_data(self):
  30.  
  31.         for i in range(3):
  32.             count_item = QStandardItem('{}'.format(self.count))
  33.             parent1 = QStandardItem('Parent' )
  34.             parent1.appendRow([count_item])
  35.  
  36.             self.count += 1
  37.            
  38.             for j in range(3):
  39.                 count_item = QStandardItem('{}'.format(self.count))
  40.                 child1 = QStandardItem('Child {}'.format(i*3+j))
  41.                 parent1.appendRow([child1, count_item])
  42.  
  43.                 self.count += 1
  44.                
  45.             self.model.appendRow(parent1)      
  46.  
  47. if __name__ == '__main__':
  48.     app = QApplication(argv)
  49.     tester = TreeModelTester()
  50.     tester.show()
  51.     app.exec_()


Bild
Benutzeravatar
BlackJack
Moderator
Beiträge: 32710
Registriert: Dienstag 25. Januar 2005, 23:29
Wohnort: Berlin
Kontaktdaten:

Re: QTreeView: Daten richtig zählen

Beitragvon BlackJack » Montag 17. Juli 2017, 14:56

@Sophus: Du hängst da als erstes eine Zeile an `parent` mit der Zahl an, deswegen ist das auch als erstes Kind von `parent` im Ergebnis. Du musst die Zahl zusammen mit `parent` an das ”parent” von `parent` hängen, genau wie Du das bei `child` ja auch machst: Zusammen mit der Nummer an das ”parent” von dem `child`:

  1.     def populate_data(self):
  2.  
  3.         for i in range(3):
  4.             count_item = QStandardItem('{}'.format(self.count))
  5.             parent = QStandardItem('Parent')
  6.             self.model().appendRow([parent, count_item])      
  7.  
  8.             self.count += 1
  9.            
  10.             for j in range(3):
  11.                 count_item = QStandardItem('{}'.format(self.count))
  12.                 child = QStandardItem('Child {}'.format(i*3+j))
  13.                 parent.appendRow([child, count_item])
  14.  
  15.                 self.count += 1

Edit: Du verdeckst mit dem `model`-Attribut übrigens die `model()`-Methode von `QTreeView`, was eventuell keine gute Idee ist.
“XML combines all the inefficiency of text-based formats with most of the unreadability of binary formats :-)” — Oren Tirosh, c.l.p, 2002
Benutzeravatar
Sophus
User
Beiträge: 949
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Re: QTreeView: Daten richtig zählen

Beitragvon Sophus » Montag 17. Juli 2017, 15:07

@BlackJack: Besten Dank. Bei Child hatte ich keinerlei Denk-Probleme, da es ja einen Parent gib, denen die Childs ja untergeordnet sind. Aber ich konnte in meinen Gedanken den Parent nicht soweit unterordnen, dass die Zahlen auch neben dem Parent erscheinen. Das war mein Denk-Problem. Aber wir haben ein weiteres Problem. Wenn ich deine Variante benutze, dann werden leere Einträge erstellt. Was ich meine? Dazu habe ich den aktuellen (mit deiner Version) Quelltext und ein weiteres Bild hochgeladen.

UPDATE
Damit die model()-Methode der QTreeView()-Klasse nicht verdeckt wird, habe ich das Attribut self.model in self.standard_item_model umbenannt. Aber das Problem mit den leeren Child-Einträgen bleibt weiterhin bestehen.
  1. #!/usr/bin/env python
  2. #-*- coding:utf-8 -*-
  3.  
  4. from sys import argv
  5.  
  6. from PyQt4.QtGui import QTreeView, QApplication, QAbstractItemView, \
  7.                         QStandardItemModel, QStandardItem
  8.  
  9. class TreeModelTester(QTreeView):
  10.     def __init__(self):
  11.  
  12.         QTreeView.__init__(self)
  13.  
  14.         # create attributes
  15.         self.count = 0
  16.  
  17.         self.setSelectionBehavior(QAbstractItemView.SelectRows)
  18.  
  19.         # create model
  20.         self.standard_item_model = QStandardItemModel()
  21.  
  22.         # set header for model
  23.         self.standard_item_model.setHorizontalHeaderLabels(['Column 1', 'Column 2'])
  24.         self.setModel(self.standard_item_model)
  25.         self.setUniformRowHeights(True)
  26.  
  27.         self.populate_data()
  28.  
  29.     def populate_data(self):
  30.  
  31.         for i in range(3):
  32.             count_item = QStandardItem('{}'.format(self.count))
  33.             parent = QStandardItem('Parent')
  34.             self.model().appendRow([parent, count_item])
  35.  
  36.             self.count += 1
  37.            
  38.             for j in range(3):
  39.                 count_item = QStandardItem('{}'.format(self.count))
  40.                 child = QStandardItem('Child {}'.format(i*3+j))
  41.                 parent.appendRow([child, count_item])
  42.  
  43.                 self.count += 1
  44.                
  45.             self.standard_item_model.appendRow(parent)      
  46.  
  47. if __name__ == '__main__':
  48.     app = QApplication(argv)
  49.     tester = TreeModelTester()
  50.     tester.show()
  51.     app.exec_()


Bild
Zuletzt geändert von Sophus am Montag 17. Juli 2017, 15:30, insgesamt 1-mal geändert.
Benutzeravatar
BlackJack
Moderator
Beiträge: 32710
Registriert: Dienstag 25. Januar 2005, 23:29
Wohnort: Berlin
Kontaktdaten:

Re: QTreeView: Daten richtig zählen

Beitragvon BlackJack » Montag 17. Juli 2017, 15:29

@Sophus: Nee, bei meiner Variante passiert das nicht. Ich habe die Zeile nicht kopiert und verändert sondern nach oben verschoben und verändert. :-)
“XML combines all the inefficiency of text-based formats with most of the unreadability of binary formats :-)” — Oren Tirosh, c.l.p, 2002
Benutzeravatar
Sophus
User
Beiträge: 949
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Re: QTreeView: Daten richtig zählen

Beitragvon Sophus » Montag 17. Juli 2017, 15:33

@BlackJack: Stimmt. In meinem letzten Beispiel musste ich einfach Zeile 45 löschen. Hatte einfach deine Variante kopiert, und so soweit eingefügt, dass die Zeile 45 noch bestehen blieb. Wenn die 45. Zeile gelöscht wird, dann klappt dein Beispiel wunderbar. Danke :)
Benutzeravatar
Sophus
User
Beiträge: 949
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Re: QTreeView: Daten richtig zählen

Beitragvon Sophus » Montag 17. Juli 2017, 16:01

Beinahe hätte ich es vergessen. Ich habe eine weitere, allgemeine Frage. Im nachfolgenden ausführbaren Programm sehen wir, dass ich mehrere, unterschiedliche Einträge habe. Im Beispiel Sind Name, Location und Money die Parents und der Rest ist Child. Nun, wenn ich meine TreeView weiter ausbauen will, müsste ich mehrere solche Schleifen basteln. Im Grunde funktioniert die Ansicht gut. Jedoch bläht sich die Funktion mächtig auf und obendrein befürchte ich, dass ich hier eine Redundanz erzeuge. Im Grunde werden mehrere gleiche Aufgaben erledigt. Nun frage ich mich, wie man die Parenst und Childs am besten verwaltet und diese dann nur durch die eine Schleife jagt?

  1. #!/usr/bin/env python
  2. #-*- coding:utf-8 -*-
  3.  
  4. from sys import argv
  5.  
  6. from PyQt4.QtGui import QTreeView, QApplication, QAbstractItemView, \
  7.                         QStandardItemModel, QStandardItem
  8.  
  9. class TreeModelTester(QTreeView):
  10.     def __init__(self):
  11.  
  12.         QTreeView.__init__(self)
  13.  
  14.         # create attributes
  15.         self.count = 0
  16.  
  17.         self.setSelectionBehavior(QAbstractItemView.SelectRows)
  18.  
  19.         # create model
  20.         self.standard_item_model = QStandardItemModel()
  21.  
  22.         # set header for model
  23.         self.standard_item_model.setHorizontalHeaderLabels(['Column 1', 'Column 2'])
  24.         self.setModel(self.standard_item_model)
  25.         self.setUniformRowHeights(True)
  26.  
  27.         self.populate_data()
  28.        
  29.     def populate_data(self):
  30.  
  31.         for i in ["Name"]:
  32.             count_item = QStandardItem('{}'.format(self.count))
  33.             parent = QStandardItem('{}'.format(i))
  34.             self.model().appendRow([parent, count_item])      
  35.  
  36.             self.count += 1
  37.            
  38.             for j in ["Hans", "Peter", "Sophus"]:
  39.                 count_item = QStandardItem('{}'.format(self.count))
  40.                 child = QStandardItem('{}'.format(j))
  41.                 parent.appendRow([child, count_item])
  42.  
  43.                 self.count += 1
  44.  
  45.         for i in ["Location"]:
  46.             count_item = QStandardItem('{}'.format(self.count))
  47.             parent = QStandardItem('{}'.format(i))
  48.             self.model().appendRow([parent, count_item])      
  49.  
  50.             self.count += 1
  51.            
  52.             for j in ["Tokio", "USA", "German"]:
  53.                 count_item = QStandardItem('{}'.format(self.count))
  54.                 child = QStandardItem('{}'.format(j))
  55.                 parent.appendRow([child, count_item])
  56.  
  57.                 self.count += 1
  58.  
  59.         for i in ["Money"]:
  60.             count_item = QStandardItem('{}'.format(self.count))
  61.             parent = QStandardItem('{}'.format(i))
  62.             self.model().appendRow([parent, count_item])      
  63.  
  64.             self.count += 1
  65.            
  66.             for j in ["Dollar", "Euro", "Zlotti"]:
  67.                 count_item = QStandardItem('{}'.format(self.count))
  68.                 child = QStandardItem('{}'.format(j))
  69.                 parent.appendRow([child, count_item])
  70.  
  71.                 self.count += 1
  72.  
  73. if __name__ == '__main__':
  74.     app = QApplication(argv)
  75.     tester = TreeModelTester()
  76.     tester.show()
  77.     app.exec_()
Benutzeravatar
Sophus
User
Beiträge: 949
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Re: QTreeView: Daten richtig zählen

Beitragvon Sophus » Montag 17. Juli 2017, 16:26

Meine vorübergehende Lösung wäre eine rekursive Verwendung der Funktion. Ich habe dann die Parents und Childs in Form einer Liste, bestehend aus Tuples gespeichert. Wahrscheinlich gibt es eine elegantere Lösung mit einem Wörterbuch und sieht womöglich dann auch besser aus. Mir gefällt dieser Ansatz auch nicht so ganz 100%.

  1. #!/usr/bin/env python
  2. #-*- coding:utf-8 -*-
  3.  
  4. from sys import argv
  5.  
  6. from PyQt4.QtGui import QTreeView, QApplication, QAbstractItemView, \
  7.                         QStandardItemModel, QStandardItem
  8.  
  9. DATA = [
  10.     ("Name", [
  11.         ("Hans", []),
  12.         ("Peter", []),
  13.         ("Sophus", [])
  14.         ]),
  15.     ("Location", [
  16.         ("Tokio", []),
  17.         ("USA", []),
  18.         ("German", []),
  19.         ]),
  20.     ("Money", [
  21.         ("Dollar", []),
  22.         ("Euro", []),
  23.         ("Zlotti", []),
  24.         ])
  25.     ]
  26.  
  27. class TreeModelTester(QTreeView):
  28.     def __init__(self):
  29.  
  30.         QTreeView.__init__(self)
  31.  
  32.         # create attributes
  33.         self.count = 0
  34.  
  35.         self.setSelectionBehavior(QAbstractItemView.SelectRows)
  36.  
  37.         # create model
  38.         self.standard_item_model = QStandardItemModel()
  39.  
  40.         # set header for model
  41.         self.standard_item_model.setHorizontalHeaderLabels(['Column 1', 'Column 2'])
  42.         self.setModel(self.standard_item_model)
  43.         self.setUniformRowHeights(True)
  44.  
  45.         self.populate_data(model_obj=self.standard_item_model, data=DATA)
  46.        
  47.     def populate_data(self, model_obj=None, data=None):
  48.  
  49.         for text, children in data:
  50.             count_item = QStandardItem('{}'.format(self.count))
  51.             item = QStandardItem(text)
  52.             model_obj.appendRow([item, count_item])
  53.             self.count += 1
  54.            
  55.             if children:
  56.                 self.populate_data(item, children)
  57.  
  58. if __name__ == '__main__':
  59.     app = QApplication(argv)
  60.     tester = TreeModelTester()
  61.     tester.show()
  62.     app.exec_()

Zurück zu „Qt/KDE“

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder