Model-View-Architektur - QListView

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
Kohonick
User
Beiträge: 7
Registriert: Sonntag 27. Oktober 2013, 17:52
Wohnort: Düsseldorf

Guten Morgen,

steht derzeit vor einem etwas größerem Problem (bin Azubi im 1. Jahr AE). Hoffe Ihr könnt mir helfen.
***********
Ich habe schon ein großen Teil meiner GUI fertig.
Nun möchte ich gerne das ListViewObjekt (Model-Based) einbinden und eine *.csv laden und ggfs. editieren. Habe mich schon durch etliche Dokus gekämpft aber nicht gefunden.

Mittel Qt Desinger habe ich das Item eingebunden.

Code: Alles auswählen

        self.tab_3.setObjectName(_fromUtf8("tab_3"))
        self.verticalLayout_3 = QtGui.QVBoxLayout(self.tab_3)
        self.verticalLayout_3.setObjectName(_fromUtf8("verticalLayout_3"))
        self.listView_2 = QtGui.QListView(self.tab_3)
        self.listView_2.setObjectName(_fromUtf8("listView_2"))
        self.verticalLayout_3.addWidget(self.listView_2)
        self.tabWidget.addTab(self.tab_3, _fromUtf8(""))
        self.tab_4 = QtGui.QWidget()
Mein "Hauptprogram" schaut so aus:

Code: Alles auswählen

'''
Created on 02.04.2014

@author: RoderigoTDA
'''
import sys
from PyQt4 import QtGui, QtCore
from gui.hauptdialog import Ui_Hauptfenster as Dlg
from cm4payroll import *

class Fenster(QtGui.QDialog, Dlg):
    def __init__(self):
        QtGui.QDialog.__init__(self)
        self.setupUi(self)

        self.connect(self.button_ok,
                QtCore.SIGNAL("clicked()"), self.start_export)
        self.connect(self.button_abbrechen,
                QtCore.SIGNAL("clicked()"), self.onAbbrechen)


    def start_export(self):

        mandant = str(self.mandant.text())
        modus = str(self.export_modus.currentText())
        jahr = int(self.jahr.text())
        impvar = "../import/data_"+mandant+"/impVar.95"
        impubr = "../import/data_"+mandant+"/imp_ubr.95"
        if self.fehlzeit.checkState():
            ImpUbr(impubr,mandant).add_impubr_2db()
        if self.zuschlag.checkState():
            ImpVar(impvar,mandant).add_impvar_2db()
        if self.urlaub.checkState():
            Purlz(jahr, mandant).add_purlz_2db()
        if self.sollstunde.checkState():
            pass
        if modus == "SAGE":
            Pkopf(mandant).add_pkopf_2db()
            Sage().write_bruttolohn()

        self.close()


    def onAbbrechen(self):
        self.close()

app = QtGui.QApplication(sys.argv)
dialog = Fenster()
dialog.show()
sys.exit(app.exec_())

Wie kann ich nun mein Item vernünftig ansprechen und mit Daten füllen?
Ich komme hier wirklich kein Stück mehr weiter.

Schon ein mal vielen Dank im Voraus.

Grüße
Kohonick
~Choose a job you love and you will never work a day in your live!~
Benutzeravatar
Madmartigan
User
Beiträge: 200
Registriert: Donnerstag 18. Juli 2013, 07:59
Wohnort: Berlin

Hallo und willkommen.
Dem von dir gezeigten Code kann ich nicht wirklich entnehmen, was du da machen willst bzw. warum du uns eine Export-Funktion zeigst, aber nicht den Code, der die CSV einliest.

Wo liest du das File denn ein? In welcher Form liegen die eingelesenen Daten dann vor, als Liste, als Dictionary, als String?

Wenn du QListView füllen willst, brauchst du ein Model (beispielsweise QStandardItemModel). Dem kannst du dann deine Daten übergeben. In diesem Beispiel würdest du für jeden Datensatz aus der CSV ein QStandardItem erstellen und dem Model zuweisen (setItem(row, column, item))

Nicht vergessen, du musst deinem QListView natürlich sagen, dass dieses Widget das Model verwenden soll. (setModel())

Vielleicht hilft dir das weiter.
Ein Hinweis: Es ist zwar nicht falsch, aber sehr unkonventionell, deutsche Sprache im Code zu verwenden. Ich empfehle dir, englische Bezeichnungen zu verwenden.
BlackJack

@Kohonick: Anmerkungen zum Quelltext:

Statt Quelltext aus den *.ui-Dateien zu generieren kann man diese Dateien zur Laufzeit mit dem `uic`-Modul laden. Damit spart man sich einen unnötigen Zwischenschritt den man jedes mal ausführen muss wenn man etwas an der GUI ändert oder wenn man das Projekt neu ausgecheckt oder geklont hat.

Es gibt schon seit langer Zeit eine bessere Schreibweise um Signale mit Slots zu verbinden, und zwar mit der `connect()`-Methode auf den Signal-Objekten:

Code: Alles auswählen

        # 
        # Anstatt:
        # 
        self.connect(self.button_ok,
                QtCore.SIGNAL("clicked()"), self.start_export)
        # 
        # Besser:
        # 
        self.button_ok.clicked().connect(self.start_export)
Das ist nicht nur kürzer, sondern auch sicherer, denn es führt an *der* Stelle schon zu einer Ausnahme falls man versucht Signale zu verbinden die es gar nicht gibt.

Sternchen-Importe sollte man vermeiden, weil man sonst irgendwann nicht mehr nachvollziehen kann wo eigentlich welcher Name herkommt oder gar Probleme mit Namenskollisionen bekommt.

Abkürzungen in Namen sollte man vermeiden solange sie nicht allgemein bekannt sind. Ein Name soll dem Leser vermitteln was der Wert dahinter bedeutet, und nicht Rätsel aufgeben. Also so etwas wie `Purlz` klingt zwar lustig, hilft aber nicht beim Verständnis.

Das Muster ``ImpIrgendwas(impirgendwas, mandant).add_impirgendwas_2db()`` sieht mir nach einem „code smell” aus. Eigentlich sogar nach mehreren. Zuerst der `Imp*`-Präfix, der in anderen Programmiersprachen verwendet wird im die Implementierung vom Interface unterscheiden zu können. Da Python keine Interfaces als Sprachkonstrukt kennt, stellt sich hier die Frage was diese Vorsilbe dann für eine Bedeutung haben soll?

Dann sind Objekte die erstellt werden, nur um *eine* Methode darauf aufzurufen und das Objekt gleich danach zu verwerfen oft ein Hinweis das eine Klasse hier vielleicht nicht die richtige Wahl ist, sondern eine Funktion völlig ausgereicht hätte.

Und zuletzt: Warum wird der Datentypname im Namen der aufgerufenen Methode wiederholt? Das liefert keine zusätzliche Information, verhindert aber das man Polymorphie verwenden kann. Zum Beispiel eine Schleife über die Unterschiede der ``if``-Anweisungen über einen Schleifenkörper der die Gemeinsamkeiten enthält.

Zur `ListView`-Frage: Was hast Du denn schon versucht? Wie sieht Deine Model-Klasse aus?
Benutzeravatar
Madmartigan
User
Beiträge: 200
Registriert: Donnerstag 18. Juli 2013, 07:59
Wohnort: Berlin

BlackJack hat geschrieben:

Code: Alles auswählen

        # 
        # Anstatt:
        # 
        self.connect(self.button_ok,
                QtCore.SIGNAL("clicked()"), self.start_export)
        # 
        # Besser:
        # 
        self.button_ok.clicked().connect(self.start_export)
Sicher nur übersehen, aber Letzeres bekommt keine ().

Code: Alles auswählen

self.button_ok.clicked.connect(self.start_export)
BlackJack

@Madmartigan: Ich brauche wohl noch einen Kaffee. :-)
Hellstorm
User
Beiträge: 231
Registriert: Samstag 22. Juni 2013, 15:01

BlackJack hat geschrieben:@Madmartigan: Ich brauche wohl noch einen Kaffee. :-)
Wäre vielleicht gut, wenn du das im obigen Beitrag direkt editieren würdest :D Ich habe mich gerade gefragt, wieso ich in meinem Programm keine () genutzt habe, bis ich den Beitrag von Madmartigan gesehen habe :D
Antworten