Gruppieren und Wiederherstellen einzelner To-Do-Einträge

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
Kaan38.png
User
Beiträge: 9
Registriert: Samstag 20. Februar 2021, 15:56

Hallo, weiß zufällig einer, wie ich Gruppieren und Wiederherstellen einzelner To-Do-Einträge ermöglichen kann oder hätte eine Idee?

(Der Code funktioniert gerade Problemlos.)

Code: Alles auswählen

from tkinter import *
import sqlite3

root = Tk()
root.title('Projektarbeit')
root.geometry("750x400")

conn = sqlite3.connect("Projektarbeit.db")
cur = conn.cursor()

cur.execute("CREATE TABLE IF NOT EXISTS Tasks (aufgabe TEXT , beschreibung TEXT , kategorie TEXT)")

def delete():
    conn = sqlite3.connect("Projektarbeit.db")
    cur = conn.cursor()

    cur.execute("DELETE from Tasks WHERE oid= " + loeschen_box.get())

    conn.commit()
    conn.close()


def update():
    # database connect
    conn = sqlite3.connect("Projektarbeit.db")
    cur = conn.cursor()

    record_id = loeschen_box.get()

    cur.execute("""UPDATE Tasks SET
        aufgabe = :aufgabe,
        beschreibung = :beschreibung,
        kategorie = :kategorie
        WHERE oid= :oid""",
        {
        'aufgabe':aufgabe_editor.get(),
        'beschreibung' :beschreibung_editor.get(),
        'kategorie' :kategorie_editor.get(),
        'oid' :record_id
        })

    conn.commit()
    conn.close()

    editor.destroy()

    #CREATE EDIT
def edit():
    global editor
    editor = Tk()
    editor.title('Projektarbeit (Task Edits)')
    editor.geometry("450x200")

    #database connect
    conn = sqlite3.connect("Projektarbeit.db")
    cur = conn.cursor()

    record_id = loeschen_box.get()
    cur.execute("SELECT * FROM Tasks WHERE oid = " + record_id)
    records = cur.fetchall()

    conn.commit()
    conn.close()

    #GLOBAL TEXT BOX NAMES
    global aufgabe_editor
    global beschreibung_editor
    global kategorie_editor


    # TEXT BOX LABEL
    aufgabe_label = Label(editor, text="Aufgabe")
    aufgabe_label.grid(row=2, column=0)
    beschreibung_label = Label(editor, text="Beschreibung")
    beschreibung_label.grid(row=3, column=0)
    kategorie_label = Label(editor, text="Kategorie")
    kategorie_label.grid(row=4, column=0)

    # TEXT BOX
    aufgabe_editor = Entry(editor, width=30)
    aufgabe_editor.grid(row=2, column=1, padx=20)
    beschreibung_editor = Entry(editor, width=30)
    beschreibung_editor.grid(row=3, column=1, padx=20)
    kategorie_editor = Entry(editor, width=30)
    kategorie_editor.grid(row=4, column=1, padx=20)

# loop results
    for record in records:
        aufgabe_editor.insert(0, record[0])
        beschreibung_editor.insert(0, record[1])
        kategorie_editor.insert(0, record[2])

    # Edit Save
    edit_btn = Button(editor, text="Speichern", command=update)
    edit_btn.grid(pady=2, ipady=2, ipadx=14, column=1, columnspan=1)


# CREATE SUBMIT FUNC FOR DB
def submit():
    conn=sqlite3.connect("Projektarbeit.db")
    cur = conn.cursor()

    #INSERT INTO TABLE
    cur.execute("INSERT INTO Tasks VALUES(:aufgabe, :beschreibung, :kategorie)",
     {
    'aufgabe': aufgabe.get(),
    'beschreibung': beschreibung.get(),
    'kategorie': kategorie.get()
    })

    conn.commit()
    conn.close()

    #clear text boxes
    aufgabe.delete(0,END)
    beschreibung.delete(0,END)
    kategorie.delete(0,END)


#QUERY FUNKTION
def query():
    global show
    show = Tk()
    show.title('Projektarbeit (Task)')
    show.geometry("450x200")
    conn = sqlite3.connect("Projektarbeit.db")
    cur = conn.cursor()

    #Query database
    cur.execute("SELECT * , oid FROM Tasks")
    records = cur.fetchall()
    # print(records)

    #Loop results
    print_records =''
    for record in records:
        print_records += str(record[0]) +"    " + str(record[1]) + "    " + str(record[2]) + "    " + str(record[3]) + "\n"


    query_label = Label(show, text=print_records)
    query_label.grid(row=1)

    conn.commit()
    conn.close()

#TEXT BOX LABEL
aufgabe_label = Label(root, text="Aufgabe")
aufgabe_label.grid(row=2, column=0)
beschreibung_label = Label(root, text="Beschreibung")
beschreibung_label.grid(row=3, column=0)
kategorie_label = Label(root, text="Kategorie")
kategorie_label.grid(row=4, column=0)


#TEXT BOX
aufgabe=Entry(root, width=30)
aufgabe.grid(row=2, column=1, padx=20)
beschreibung=Entry(root, width=30)
beschreibung.grid(row=3, column=1, padx=20)
kategorie = Entry(root, width=30)
kategorie.grid(row=4, column=1, padx=20)


#CREATE SUBMIT BUTTON
submit_btn = Button(root, text="Hinzufügen", command=submit)
submit_btn.grid(pady=8, padx=1, ipady=1, ipadx=11, column=1, columnspan=1)

#QUERY BUTTON
query_btn = Button(root, text="Zeige Tasks", command=query)
query_btn.grid(pady=5, padx=1, ipady=1, ipadx=8,column=1, columnspan=1)


#Delete Tasks
loeschen_box_label = Label(root, text="Auswählen (ID Nummer)")
loeschen_box_label.grid(row=2, column=5, columnspan=1,pady=5)

loeschen_box = Entry(root, width=30)
loeschen_box.grid(row=3, column=5)

delete_btn = Button(root, text="Löschen", command=delete)
delete_btn.grid(row=4, ipadx=20,column=5)

#Edit
edit_btn = Button(root, text="Bearbeiten", command=edit)
edit_btn.grid(row=5, ipadx=14, column=5, columnspan=1)


conn.commit()
conn.close()


root.mainloop()
Benutzeravatar
__blackjack__
User
Beiträge: 13006
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Kaan38.png: Der Code funktioniert nicht problemlos. Es darf nur ein Tk-Objekt geben. Das ist *das* Hauptfenster, und da hängt der komplette Tk/Tcl-Interpeter dran, von dem es nur einen geben darf, sonst ist undefiniert was passiert. Und auf die Anmerkungen das man keine Sternchenimporte macht, welcher Code *nicht* auf Modulebene stehen sollte, und das man keine globalen Variablen verwendet, bist Du auch immer noch nicht eingegangen.

Du hast in dem Code nicht eine einzige Funktion. Du missbrauchst ``def`` um Codeabschnitten Namen zu geben, quasi als Sprungmarken wie in alten BASIC-Dialekten oder Assembler. Python ist aber eine moderne, objektorientierte Hochsprache und da sollte man auch tatsächlich in Python programmieren und nicht veraltetes BASIC als Python verkleidet. Objektorientierte Programmierung (OOP) braucht man auch für jede nicht-triviale GUI. Da ist dieser Quelltext noch ein bisschen von entfernt. Da muss der aber hin.

Was vielleicht noch nicht in den anderen Themen angesprochen wurde: Anscheinend wird die implizite OID von SQLite3 verwendet. Das ist nicht portabel und die ID kann auch nicht wie ein tatsächlicher Primärschlüssel verwendet werden, da solltest Du explizit einen eigenen Primärschlüssel für Deine Tabellen deklarieren, statt dieses Implementierungsdetail zu missbrauchen.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Kaan38.png
User
Beiträge: 9
Registriert: Samstag 20. Februar 2021, 15:56

Also ich habe jetzt alles bearbeitet und auch dafür die neue Datenbank app.db benutzt. So wäre es doch richtig, wenn ich es verstanden habe.
Falls ja wie würde ich nun Gruppieren und Wiederherstellen einzelner To-Do-Einträge ermöglichen?
Tut mir leid, wenn ich euch das Leben schwer mache aber von Zuhause aus lernen kann ich garnicht😅.

Code: Alles auswählen

from functools import partial
import tkinter as tk
import sqlite3


def initalize_database():
    conn = sqlite3.connect("app.db")
    cur = conn.cursor()
    cur.execute("CREATE TABLE IF NOT EXISTS Tasks (aufgabe TEXT , beschreibung TEXT , kategorie TEXT)")
    conn.commit()
    conn.close()


def delete(loeschen_box):
    conn = sqlite3.connect("app.db")
    cur = conn.cursor()
    cur.execute("DELETE from Tasks WHERE oid= ?", [loeschen_box.get()])
    conn.commit()
    conn.close()


def update(editor, record_id, aufgabe_editor, beschreibung_editor, kategorie_editor):
    conn = sqlite3.connect("app.db")
    cur = conn.cursor()
    cur.execute("""UPDATE Tasks SET
        aufgabe = ?, beschreibung = ?, kategorie = ?
        WHERE oid = ?""",
        [aufgabe_editor.get(), beschreibung_editor.get(), kategorie_editor.get(), record_id])
    conn.commit()
    conn.close()
    editor.destroy()


def edit(loeschen_box):
    editor = tk.Toplevel()
    editor.title('Projektarbeit (Task Edits)')
    record_id = loeschen_box.get()

    conn = sqlite3.connect("app.db")
    cur = conn.cursor()
    cur.execute("SELECT aufgabe, beschreibung, kategorie FROM Tasks WHERE oid = ?", [record_id])
    record = cur.fetchone()
    conn.commit()
    conn.close()

    tk.Label(editor, text="Aufgabe").grid(row=2, column=0)
    aufgabe_editor = tk.Entry(editor, width=30)
    aufgabe_editor.grid(row=2, column=1, padx=20)

    tk.Label(editor, text="Beschreibung").grid(row=3, column=0)
    beschreibung_editor = tk.Entry(editor, width=30)
    beschreibung_editor.grid(row=3, column=1, padx=20)

    tk.Label(editor, text="Kategorie").grid(row=4, column=0)
    kategorie_editor = tk.Entry(editor, width=30)
    kategorie_editor.grid(row=4, column=1, padx=20)

    aufgabe, beschreibung, kategorie = record
    aufgabe_editor.insert(0, aufgabe)
    beschreibung_editor.insert(0, beschreibung)
    kategorie_editor.insert(0, kategorie)

    tk.Button(editor, text="Speichern",
        command=partial(update, editor, record_id, aufgabe_editor, beschreibung_editor, kategorie_editor)
    ).grid(pady=2, ipady=2, ipadx=14, column=1, columnspan=1)


def submit(aufgabe, beschreibung, kategorie):
    conn=sqlite3.connect("app.db")
    cur = conn.cursor()
    cur.execute("INSERT INTO Tasks VALUES(?, ?, ?)",
        [aufgabe.get(), beschreibung.get(), kategorie.get()])
    conn.commit()
    conn.close()

    #clear text boxes
    aufgabe.delete(0, tk.END)
    beschreibung.delete(0, tk.END)
    kategorie.delete(0, tk.END)


def query(query_label):
    conn = sqlite3.connect("app.db")
    cur = conn.cursor()

    #Query database
    cur.execute("SELECT aufgabe, beschreibung, kategorie, oid FROM Tasks")

    records = []
    for aufgabe, beschreibung, kategorie, oid in cur:
        records.append(f"{aufgabe}  {beschreibung}  {kategorie}    {oid}")
    query_label['text'] = '\n'.join(records)
    conn.commit()
    conn.close()


def main():
    initalize_database()

    root = tk.Tk()
    root.title('Projektarbeit')

    tk.Label(root, text="Aufgabe").grid(row=2, column=0)
    aufgabe = tk.Entry(root, width=30)
    aufgabe.grid(row=2, column=1, padx=20)

    tk.Label(root, text="Beschreibung").grid(row=3, column=0)
    beschreibung = tk.Entry(root, width=30)
    beschreibung.grid(row=3, column=1, padx=20)

    tk.Label(root, text="Kategorie").grid(row=4, column=0)
    kategorie = tk.Entry(root, width=30)
    kategorie.grid(row=4, column=1, padx=20)


    tk.Button(root, text="Hinzufügen",
        command=partial(submit, aufgabe, beschreibung, kategorie)
    ).grid(pady=8, padx=1, ipady=2, ipadx=11, column=1, columnspan=1)

    query_label = tk.Label(root, text="")
    query_label.grid(row=12, column=1)
    tk.Button(root, text="Zeige Einträge",
        command=partial(query, query_label)
    ).grid(pady=5, padx=10, ipady=2, ipadx=2,column=1, columnspan=1)

    tk.Label(root, text="Auswählen (ID Nummer)").grid(row=14, column=1, columnspan=1,pady=5)

    loeschen_box = tk.Entry(root, width=30)
    loeschen_box.grid(row=15, column=1)

    tk.Button(root, text="Löschen",
        command=partial(delete, loeschen_box),
    ).grid(pady=2, padx=1, ipady=2, ipadx=20,column=1, columnspan=1)

    tk.Button(root, text="Bearbeiten",
        command=partial(edit, loeschen_box)
    ).grid(pady=2, ipady=2, ipadx=14, column=1, columnspan=1)

    root.mainloop()

if __name__ == "__main__":
    main()
Sirius3
User
Beiträge: 17712
Registriert: Sonntag 21. Oktober 2012, 17:20

Kaan38.png hat geschrieben: Donnerstag 25. Februar 2021, 14:27Also ich habe jetzt alles bearbeitet
Ich würde eher sagen, Du hast jetzt meinen Code ohne Änderungen kopiert.

Zur Frage: welche zusätzliche Information benötigst Du denn für jeden ToDo-Eintrag, um sie gruppieren zu können?
Kaan38.png
User
Beiträge: 9
Registriert: Samstag 20. Februar 2021, 15:56

Sirius3 hat geschrieben: Donnerstag 25. Februar 2021, 14:56
Kaan38.png hat geschrieben: Donnerstag 25. Februar 2021, 14:27Also ich habe jetzt alles bearbeitet
Ich würde eher sagen, Du hast jetzt meinen Code ohne Änderungen kopiert.

Zur Frage: welche zusätzliche Information benötigst Du denn für jeden ToDo-Eintrag, um sie gruppieren zu können?
Ja, ich hab meinen veralteten Code gelöscht und deinen benutzt, habe nur eine andere Datenbank genommen und jz statt untereinander das Löschen und bearbeiten etc. neben dem hinzufügen gemacht. Ist ja auch nicht viel Arbeit gewesen dank dir😅

Also ich habe die Frage nicht ganz verstanden aber würde auch gerne per ID gruppieren, da die immer eindeutig ist, dann wäre halt die Kategorie oder so die Überschrift bisschen (kompliziert ausgedrückt aber hoffe ihr versteht das)
Sirius3
User
Beiträge: 17712
Registriert: Sonntag 21. Oktober 2012, 17:20

Solange Du nicht genau definieren kannst, was Du unter "Gruppierung" meinst, wird es für Dich auch schwierig, das zu programmieren.
Benutzeravatar
__blackjack__
User
Beiträge: 13006
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Wobei die (O)ID zwar immer eindeutig ist, aber nicht immer die gleiche bleiben muss. Das ist eines der Probleme die man sich mit der nicht-standard-oid einhandelt. Falls da irgendwelche Tasks über eine weitere Tabelle zusammengefasst/gruppiert werden sollen, dann geht das nicht mit der OID als Fremdschlüssel, weil sich Schlüssel nicht ändern dürfen.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Kaan38.png
User
Beiträge: 9
Registriert: Samstag 20. Februar 2021, 15:56

__blackjack__ hat geschrieben: Freitag 26. Februar 2021, 05:51 Wobei die (O)ID zwar immer eindeutig ist, aber nicht immer die gleiche bleiben muss. Das ist eines der Probleme die man sich mit der nicht-standard-oid einhandelt. Falls da irgendwelche Tasks über eine weitere Tabelle zusammengefasst/gruppiert werden sollen, dann geht das nicht mit der OID als Fremdschlüssel, weil sich Schlüssel nicht ändern dürfen.
Hmm also müsste ich einen anderen Tag als den Fremdschlüssel setzen.

Wie würde ich denn die Einträge in der Datenbank ausblenden und wieder einblenden statt die komplett zu löschen? Damit, wenn ich eine Task ausversehen gelöscht hätte.
Sirius3
User
Beiträge: 17712
Registriert: Sonntag 21. Oktober 2012, 17:20

Du mußt halt die Information, ob gelöscht oder nicht, in der Datenbank speichern.
Kaan38.png
User
Beiträge: 9
Registriert: Samstag 20. Februar 2021, 15:56

Sirius3 hat geschrieben: Freitag 26. Februar 2021, 20:21 Du mußt halt die Information, ob gelöscht oder nicht, in der Datenbank speichern.
Ja, das ist zwar klar aber gibts nicht eine Möglichkeit indem ich sage die Einträge will ich nicht löschen sondern Ausblenden, weil ich online nur das Löschen gefunden habe.
Benutzeravatar
sparrow
User
Beiträge: 4165
Registriert: Freitag 17. April 2009, 10:28

@Kaan38.png: Es gibt keine magische Funktion, die das für dich tut. _Du_ musst diese Information ind er Datenbank speichern. Zum Beispiel in einem Feld "Status".
Antworten