multiscroll-listboxes select and delete from Database

Fragen zu Tkinter.
Antworten
Count
User
Beiträge: 28
Registriert: Donnerstag 28. November 2019, 12:56

Schönen guten Morgen.
Ich hab da mal wieder ein Problem, was für euch bestimmt ganz einfach zu lösen ist. :D

Beschreibung:
ich lasse mir in 3 Listboxen Sachen aus einer Datenbank ausgeben.
Wenn diese Listboxen 'voll' sind, dann kann man scrollen und es bleibt immer alles in einer Zeile was zusammen gehört.

Problem:
Nun möchte ich ab und an auch mal was daraus löschen und bekomme es nicht hin. (wer hätte es gedacht?)

Ich denke, dass das Problem ist, dass ich nur eine der Listboxen auswählen "kann" und die Anderen beiden nicht in der selben Zeile
mit ausgewählt werden und dass ein paar Argumente fehlen.
Kann natürlich auch an was ganz anderem liegen.

Freue mich auf kreative Lösungsansätze oder Lösungen
Wenn noch irgendwas komisch ist, dann sagt ruhig bescheid, bin noch am lernen.


"Extraaufgabe"
Die Einträge nach Datum sortieren (Datumsformat soll in der Schreibweise bleiben)


Danke im Voraus und schön mal schönes Wochenende

hier mein Code wie ich es mir gedacht habe:

Code: Alles auswählen

from tkinter import *
import sqlite3
import os
DB='test_db.db'

if not os.path.isfile(DB):
    conn = sqlite3.connect(DB)
    c = conn.cursor()
    c.execute('''CREATE TABLE test (
                                    id 	INTEGER  PRIMARY KEY    AUTOINCREMENT,
                                    name	INTEGER NOT NULL,
                                    action INTEGER NOT NULL,
                                    result	VARCHAR,
                                    date VARCHAR)''')
    c.execute('''INSERT INTO test VALUES 
                                        (NULL,
                                        'Klaus',
                                        'rennen',
                                        'gefallen',
                                        '09.07.2020') ''')
    conn.commit()
    conn.close()

class MultipleScrollingListbox(Tk):

    def __init__(self):
        Tk.__init__(self)

        self.scrollbar = Scrollbar(self)
        self.scrollbar.config(command=self.yview)
        self.scrollbar.pack(side='right', fill='y')

        self.list1 = Listbox(self, yscrollcommand=self.yscroll1)
        self.list1.pack(fill='y', side='left')

        self.list2 = Listbox(self, yscrollcommand=self.yscroll2)
        self.list2.pack(expand=1, fill='both', side='left')

        self.list3 = Listbox(self, yscrollcommand=self.yscroll3)
        self.list3.pack(expand=1, fill='both', side='left')

        self.btn = Button(self, text='löschen', command=self.loeschen)
        self.btn.pack(fill='both', side='top')

        conn = sqlite3.connect(DB)
        c = conn.cursor()
        c.execute('''SELECT
                            date,
                            action,
                            result
                    FROM
                            test''')            
        records=c.fetchall()
        for record in records:
            self.list1.insert(END,record[0])
            self.list2.insert(END,record[1])
            self.list3.insert(END,record[2])

    def loeschen(self):
        if  self.list1.curselection() and self.list2.curselection() and self.list3.curselection():        
            conn = sqlite3.connect(DB)
            c = conn.cursor()
            c.execute('''DELETE FROM
                                    test
                                WHERE
                                    and name = 'klaus'
                                    and action = :action
                                    and result = :result                                                                                                  
                                    and date = :date
                                    ''',
                    {
                                'action' : self.list2.curselection(),                                                                             
                                'result' : self.list3.curselection(),
                                'date'  :  self.list1.curselection()
                    })

            conn = sqlite3.connect(DB)
            c = conn.cursor()
            c.execute('''SELECT
                                date,
                                action,
                                result
                        FROM
                                test''')            
            records=c.fetchall()
            for record in records:
                self.list1.insert(END,record[0])
                self.list2.insert(END,record[1])
                self.list3.insert(END,record[2])
        
    def yscroll1(self, *args):
        if self.list2.yview() != self.list1.yview():
            self.list2.yview_moveto(args[0])
        self.scrollbar.set(*args)
        if self.list3.yview() != self.list1.yview():
            self.list3.yview_moveto(args[0])
        self.scrollbar.set(*args)

    def yscroll2(self, *args):
        if self.list1.yview() != self.list2.yview():
            self.list1.yview_moveto(args[0])
        self.scrollbar.set(*args)

    def yscroll3(self, *args):
        if self.list1.yview() != self.list3.yview():
            self.list1.yview_moveto(args[0])
        self.scrollbar.set(*args)

    def yview(self, *args):
        self.list1.yview(*args)
        self.list2.yview(*args)
        self.list3.yview(*args)

if __name__ == "__main__":
    test= MultipleScrollingListbox()
    test.mainloop()
Benutzeravatar
peterpy
User
Beiträge: 188
Registriert: Donnerstag 7. März 2013, 11:35

Hallo Count,

Code: Alles auswählen

if  self.list1.curselection() and self.list2.curselection() and self.list3.curselection():
Du willst alle drei Listboxen auf einmal markieren? Wie soll das gehen?
Willst Du nicht eine Oder Verknüpfung?

Zum Sortieren:
ein kurzer Suchauftrag an eine Suchmaschine ergibt folgendes:

Code: Alles auswählen

SELECT * FROM tabellen_name ORDER BY spalten_name ASC|DESC
Oder Du sortierst in einer Liste.

Gruss
Peter
Sirius3
User
Beiträge: 18216
Registriert: Sonntag 21. Oktober 2012, 17:20

Was passiert denn konkret? Gibt es eine Fehlermeldung? Stürzt die Garage ein?

Wenn drei Daten zusammen gehören, will man die eigentlich nicht in drei unterschiedlichen Listen haben. Da willst Du doch eher soetwas wie eine Tabelle haben?
Wenn man das doch irgendwie so lösen möchte, dann sollte man nicht alles dreimal schreiben, sondern Listen für die Listboxen verwenden.
Und man muß auch die Selektion irgendwie synchronisieren.

Benutze keine *-Importe und keine Abkürzungen. `list` für eine Listbox? btn -> loesch_button.
Das DELETE-Statement ist kaputt. Nicht nur der Syntaxfehler, aber angeblich ist Name ja eine Zahl, warum auch immer.
Count
User
Beiträge: 28
Registriert: Donnerstag 28. November 2019, 12:56

Hallo Peter,
peterpy hat geschrieben: Montag 13. Juli 2020, 11:00 Du willst alle drei Listboxen auf einmal markieren? Wie soll das gehen?
genau das war ja meine Frage, ob und wie es geht

Zum Sortieren:
ein kurzer Suchauftrag an eine Suchmaschine ergibt folgendes:

Code: Alles auswählen

SELECT * FROM tabellen_name ORDER BY spalten_name ASC|DESC
dieses Ordnen bringt mir in meinem Fall gar nichts.
da ASC von 0-9 sortiert, d.h. es würde den 12.06. nach den 01.07. einsortieren
und bei DESC von 9-0 sortiert, da wäre der 01.07. nach dem 02.07. dran
Count
User
Beiträge: 28
Registriert: Donnerstag 28. November 2019, 12:56

Sirius3 hat geschrieben: Montag 13. Juli 2020, 11:19 Was passiert denn konkret? Gibt es eine Fehlermeldung? Stürzt die Garage ein?
es passiert gar nichts, das ist das Prolem.
Bei einer Fehlermeldung könnte ich ja reagieren.

Wenn drei Daten zusammen gehören, will man die eigentlich nicht in drei unterschiedlichen Listen haben. Da willst Du doch eher soetwas wie eine Tabelle haben?
Das Problem war, dass es die 3 Dinge die ich haben wollte nicht hintereinander in eine Listbox gesteckt hat, daher kam ich auf die Idee mit den 3 Listboxen.
Ja so eine Art Tabelle wäre mir durchaus lieber, allerdings habe ich dazu nichts wirklich finden können.
Und man muß auch die Selektion irgendwie synchronisieren.
Das war auch mein Gedanke - bekam es nur nicht hin.

Das DELETE-Statement ist kaputt. Nicht nur der Syntaxfehler, aber angeblich ist Name ja eine Zahl, warum auch immer.
Ein Name sollte natürlich keine Zahl sein, da ist mir wohl beim einkürzen des Codes ein Fehler unterlaufen
Sirius3
User
Beiträge: 18216
Registriert: Sonntag 21. Oktober 2012, 17:20

Das Datumsformat ist falsch. sqlite hat keinen richtigen Datumstyp, daher muß man sich immer mit Behelfstypen behelfen; üblich ist das Format 2020-07-12, das läßt sich nämlich Alphabetisch sortieren. Die Sortierung sollte aber auch gar kein Problem sein, da Du ja immer komplette Datensätze abfragst und die gemeinsam in die Listen füllst.
Tabellen mit tkinter zu schreiben, ist halt viel Handarbeit, aber es gibt dazu schon einige Beispiele im Netz.
Count
User
Beiträge: 28
Registriert: Donnerstag 28. November 2019, 12:56

Das mit der Tabelle war echt n guter Tipp, vielen Dank dafür.
Ging recht fix nach dem ich was gefunden hatte und ist eigentlich gar nicht so aufwendig/schwer

mit dem Datum muss ich mir mal schauen, aber funktioniert bestimmt über Umwege auch
Antworten