Kalenderapplikation wie programmieren, dass beim Anlegen eines Termins nicht jedes Mal neu gestartet wird?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
AFX
User
Beiträge: 51
Registriert: Samstag 4. September 2021, 08:40

Ich habe eine Kalenderapplikation geschrieben, die Übersicht über die Termine wird auf einer QMessageBox dargestellt. Hier ist der Quellcode:

https://drive.google.com/file/d/18Eb9fZ ... sp=sharing

Nach dem Anlegen eines Termins wird die Applikation quasi neu gestartet und alle bereits angelegten Termine werden neu aus der DB ausgelesen - ich denke, dies ist schlecht.

Welche Wege gibt es, um die Applikation derart zu gestalten, damit das Fenster, in dem die Termine dargestellt werden, nicht jedes Mal neu geladen (neu gestartet) wird?
Benutzeravatar
sparrow
User
Beiträge: 4195
Registriert: Freitag 17. April 2009, 10:28

Meine Motivation, mir ein Archiv herunterzuladen, das zu entpacken und mich durch Quellcode zu wühlen hält sich in Grenzen.
Bitte zeig doch ein möglichst kurzes, lauffähiges Beispiel, welches das Problem verdeutlicht.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ohne den Quellcode angeschaut zu haben (aehnliche Gruende wie sparrow), kann man dazu trotzdem 1-2 Dinge sagen:

1) es ist nicht per se schlecht. Was heisst also du denkst, das es das ist? Ist es langsam, kommt es zu glitches? Oder ist das nur eine Geschmacksfrage? Denn der grosse Vorteil von alles neu: nichts ist alt, sprich man korrigiert automatisch auch irgendwelchen roedeligen Altzustand.
2) Wenn es wirklich schlecht ist, dann ist die Loesung einfach, nur den neuen Datensatz in das bestehende Datenmodell einzupflegen.
AFX
User
Beiträge: 51
Registriert: Samstag 4. September 2021, 08:40

Ok, danke für die Rückmeldungen. Ich werde dann versuchen, das dynamische Nachladen der Datensätze in Angriff zu nehmen.
Benutzeravatar
__blackjack__
User
Beiträge: 13119
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@AFX: Anmerkungen zum Quelltext: Da ist eine `__init__.py` die das `src`-Verzeichnis zu einem Package macht. Ein Package sollte nicht `src` heissen. Und durch das Package funktionieren Importe wie ``import filereader`` nicht. Da die anscheinend bei Dir doch funktionieren, muss der Modulpfad so gesetzt sein, dass das `src`-Verzeichnis, also ein Pfad *in* ein Package, auch im Modulpfad liegt, es also mehr als einen voll qualifizierten Namen pro Modul in dem Package gibt, was nicht sein darf. Damit kann man sich schwer auffindbare Fehler einhandeln.

Sternchen-Importe sind Böse™. Da holt man sich beispielsweise bei `tkinter` fast 140 Namen ins Modul von denen nur ein kleiner Bruchteil verwendet wird. Auch Namen die gar nicht in `tkinter` definiert werden, sondern ihrerseits von woanders importiert werden. Das macht Programme unnötig unübersichtlicher und fehleranfälliger und es besteht die Gefahr von Namenskollisionen.

Man sollte auch nicht zwei GUI-Rahmenwerke mischen. Das kann funktionieren, muss es aber nicht. Auch in Qt gibt es Dateidialoge.

Es gibt eine Anzahl von `move()` und `resize()`-Aufrufen wo absolute Pixelgrössen- und positionen gesetzt werden, wo Layouts hätten verwendet werden müssen.

Die Klassenvariable `MainWindow.singleton` ist falsch. Die Typannotation stimmt offensichtlich nicht, aber auch inhaltlich stimmt der Name nur sofern man auch tatsächlich dafür sorgt, dass vor dem Aufruf von `restart()` ein eventuell vorher vorhandenes Hauptfenster geschlossen wurde. Es wird auch nirgends auf dieses Klassenattribut lesend zugegriffen, womit das auch noch überflüssig ist.

Die Klasse ist mit fast 1.100 Zeilen und 31 Methoden zu umfangreich. Das riecht nach einer Gott-Klasse.

Es werden ganz schrecklich falsche Dinge mit Zeichenketten angestellt in denen Pfade sein sollen. Das funktioniert so beispielsweise nicht unter Linux oder MacOS. Für den unfallfreie(re)n und plattformunabhängigen Umgang mit Pfaden gibt es das `pathlib`-Modul

Für CSV-Dateien gibt es das `csv`-Modul in der Standardbibliothek. Das kommt beispielsweise auch damit klar wenn das Trennzeichen *in* den Daten vorkommt.

Grunddatentypen haben nichts in Namen zu suchen. Den Typ ändert man im Laufe der Entwicklung gelegentlich und dann hat man entweder falsche, irreführende Namen im Quelltext, oder man muss alle betroffenen Namen suchen und anpassen.

Es werden auch ab und zu Namen von eingebauten Datentypen oder Funktionen für etwas anderes verwendet. `dict` und `ascii()` beispielsweise.

Es gibt in dem Code eine Repräsentation der Daten für/aus der GUI und eine für/aus der Datenbank, aber keine sinnvolle Repräsentation der Daten an sich, was dazu führt, dass da viel undurchsichtiger Code steht der, auf unnötigen Listen und mit magischen Indexwerten und Zeichenkettenoperationen und Umwandlungen von Teilwerten, wo eigentlich einfacherer Code stehen sollte der unabhängig von GUI und Datenbank verständlich sein sollte. Datumsangaben/Zeitpunkte sollten beispielsweise durch Typen aus `datetime` repräsentiert werden, und nicht durch Zeichenketten. Anderes Beispiel: Wenn man von der Datenhaltungsschicht einen Pfad abfragt, sollte man ein `Path`-Objekt bekommen, und keine Liste mit genau einem Tupel mit genau einem Element was die Zeichenkette mit der Pfadangabe ist, weil das zufällig so aus einer relationalen Datenbank geliefert wird. Weder die Programmlogik noch die GUI sollten so etwas wissen müssen.

Die Datenbankabfragen sind teilweise extrem unsinnig umständlich. Für `printAppointments()` werden zum Beispiel die Informationen in zwei Abfragen über alle Termine in zwei separate Wörterbücher abgefragt, die jeweils den Startzeitpunkt auf *einen* anderen Wert abbilden um dann *in* der Schleife noch mal eine Abfrage von einem weiteren Wert pro Datensatz abzusetzen.

Das `dbaccess`-Modul besteht aus viel Code der kopiert und leicht angepasst aussieht. Ich würde mich da gar nicht erst mit hangeschriebenem SQL aufhalten sondern gleich SQLAlchemy verwenden. Muss ja nicht zwingend das ORM sein, obwohl da auch nichts gegen spricht.

Die Tabellen sehen komisch bis falsch aus. *Alles* ist CHAR, aber mindestens mal Zeitstempel und Datumsangaben sind keine einfachen Zeichenketten. Keine Tabelle hat einen Primärschlüssel. Keine UNIQUE-Constraints auf Spalten wo man am Code sehen kann, dass das nicht funktioniert wenn das nicht eingehalten wird. Und der potentielle Primärschlüssel für die Termine ist das Startdatum. Bei der CRES-Tabelle ist es der Name‽ Da beides veränderbar sein dürfte, eignet sich beides nicht als Fremdschlüssel in einer anderen Tabelle, und damit auch nicht wirklich als Primärschlüssel. Es gibt im Grunde nur recht wenige ”natürliche” Primärschlüssel, in der Regel haben Tabellen eine künstliche ID als Primärschlüssel.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten