Listbox auswahl als Int

Fragen zu Tkinter.
Code_Bender
User
Beiträge: 21
Registriert: Sonntag 6. Januar 2019, 12:32

Hallo ich möchte ein Löschsystem machen indem ich Listboxen benutze.
Wenn man einen slot Auswählt soll er gelöscht werden z.B.:

Code: Alles auswählen

from tkinter import *
Win = Tk()
file_row = open("Liste.txt", "r+")
file = file_row.read().splitlines()

listbox = Listbox(Win, height=5)
listbox.pack()
for i in file:
	listbox.insert("end", i)

def DEL():
	sel = listbox.curselection()
	del file[sel]
	file_row.write(file)

minus = Button(Win, text="-", command = DEL)
minus.pack()

aber er sagt mir:

Exception in Tkinter callback
del file[sel]
TypeError: list indices must be integers or slices, not tuple

und wenn ich das Curseselction ausprinten lasse dann zeigt er mit sowas an : z.B.: (1,0)

Es währe nätt wenn ihr mit helfen könnt.
Code_Bender
__deets__
User
Beiträge: 14539
Registriert: Mittwoch 14. Oktober 2015, 14:29

Da ist viel im argen.

Das faengt damit an, dass du Code einfach auf die Modul-Ebene packst. Da gehoert der nicht hin, sondern in Funktionen und Klassen, und in eine vernuenftige main-Funktion.

Dann definiert du einen Namen "file" selbst, womit du den eingebauten Namen "file" der den Dateityp beinhaltet ueberschreibst. Denk dir also einen besseren Namen aus.

Du oeffnest eine Datei, aber schliesst sie nie. Benutze das with-Statment.

Die Zeilen so zu erzeugen ist ungewoehnlich kompliziert. Warum nicht gleich readlines()?

Und zu guter Letzt dein eigentliches Problem: was ist denn "file" in deinem Code? Ist darauf der Index-Zugriff ueberhaupt definiert? Was waere denn eine geeignete Datenstruktur fuer deine Liste an Zeilen (Zaunpfahl...) um darauf zu arbeiten?
Code_Bender
User
Beiträge: 21
Registriert: Sonntag 6. Januar 2019, 12:32

Also den code den ich da geschrieben habe war nur ein Beispiel hier der eigentliche Code:

Code: Alles auswählen

from tkinter import *
from tkinter.scrolledtext import ScrolledText
from tkinter.ttk import Progressbar
from tkinter.ttk import Combobox
from tkinter import messagebox
from tkinter import filedialog
from time import *
import webbrowser as web
import os
import sys

FONT = ["Bahnschrift", 14 , "bold"]
FONT2 = ["Bahnschrift", 12 , "bold"]

def n1(event=None):
    def OPEN(event=None):
        filename = filedialog.askdirectory()
        Wider_zu.insert("end", filename)
    def BACK(event=None):
        var = -600
        var2  = 0
        for i in range(100):
            var = var + 6
            var2 = var2 + 6
            main.place(x=var, y=0)
            Wider.place(x=var2, y=0)
            sleep(0)
            root.update()
        Wider.destroy()
    def WIDERHER(event=None):
        e = Wider_zu.get()
        prolb["text"] = "Suche Dateien"
        Wider_zu.config(state="disabled")
        Widerher.config(state="disabled")
        for i in range(20):
            pro["value"] = i
            sleep(0.000025)
            root.update()
        if e == "":
            Wider_zu.config(state="normal")
            Widerher.config(state="normal")
            prolb["text"] = "Ein fehler ist Aufgetreten"
        prolb["text"] = "Dateien lokatisiert"
        try:
            d1r = open(scroll.get("active"), "r")
            d1 = d1r.read()
            d2 = open(Wider_zu.get()+"/"+scroll.get("active"), "w")
            d2.write(d1)
            prolb["text"] = "Dateien Ungeschrieben"
            for i in range(560):
                i = i + 20
                pro["value"] = i
                sleep(0)
                root.update()
            root.update()
            sleep(0.5)
            prolb["text"] = "Warten..."
            for i in range(20):
                i = i + 580
                pro["value"] = i
                sleep(0.25)
                root.update()
                pro.update()
            d1.close()
            d2.close()
        except:
            Wider_zu.config(state="normal")
            Widerher.config(state="normal")
            prolb["text"] = "Ein fehler ist Aufgetreten"
    Wider = Frame(root, height=300, width=600, bg="#FFFFFF")
    Wider.place(x=600, y=0)
    sc = Scrollbar(Wider)
    sc.place(x=300, y=80)
    scroll = Listbox(Wider, height=10, width=50, selectmode="extended")
    scroll.place(x=0, y=80)
    scroll.selection_set(0)
    scroll["yscrollcommand"] = sc.set
    sc["command"] = scroll.yview
    filer = open("C:/Users/Gabriel/Documents/1 Projeckte/Abteil B/Datei Liste.data", "r")
    file = filer.read().splitlines()
    filer.close()
    for i in file:
        scroll.insert("end", i)
    DatOpen = Button(Wider, text="Order Öffnen", bg="#FFFFFF", relief="raised", bd=1,
                     font=FONT, command = OPEN)
    DatOpen.place(x=477, y=0)
    Back = Button(Wider, text="< Zurück", bg="#FFFFFF", relief="raised", bd=1,
                  font=FONT, command = BACK)
    Back.place(x=0, y=0)
    Wider_zulb = Label(Wider, text="Widerherstellen zu:", bg="#FFFFFF", font=FONT2)
    Wider_zulb.place(x=0, y=50)
    Wider_zu = Entry(Wider, width=40, bg="#FFFFFF", font=FONT2)
    Wider_zu.place(x=150, y=52)
    Widerher = Button(Wider, text="Widerherstellen", bg="#FFFFFF", font=FONT2,
                      relief="raised", bd=1, width=13, command = WIDERHER)
    Widerher.place(x=474, y=245)
    pro = Progressbar(Wider, length=600, maximum=600, value=0)
    pro.place(x=0, y=278)
    prolb = Label(Wider, text="", bg="#FFFFFF", font=FONT2)
    prolb.place(x=230, y=250)
    var = 0
    var2 = 600
    for i in range(100):
        var = var - 6
        var2 = var2 - 6
        Wider.place(x=var2, y=0)
        main.place(x=var, y=0)
        sleep(0)
        root.update()
def n2(event=None):
    def BACK(event=None):
        var = -600
        var2  = 0
        for i in range(100):
            var = var + 6
            var2 = var2 + 6
            main.place(x=var, y=0)
            Hinzu.place(x=var2, y=0)
            sleep(0)
            root.update()
        Hinzu.destroy()
    def M(event=None):
        sel = listbox.
        del file[sel]
        print(file)
        #listbox.delete(0, END)
        #for i in file:
            #listbox.insert("end", i)
    Hinzu = Frame(root, height=300, width=600, bg="#FFFFFF")
    Hinzu.place(x=600, y=0)
    Back = Button(Hinzu, text="< Zurück", bg="#FFFFFF", relief="raised", bd=1,
                  font=FONT, command = BACK)
    Back.place(x=0, y=0)
    listbox = Listbox(Hinzu, height=10, width=40)
    listbox.place(x=0, y=40)
    filer = open("C:/Users/Gabriel/Documents/1 Projeckte/Abteil B/Datei Liste.data", "r+")
    file = filer.read().splitlines()
    filer.close()
    for i in file:
        listbox.insert("end", i)
    plus = Button(Hinzu, text="+", width=2, bg="#FFFFFF", relief="raised", bd=1)
    plus.place(x=0, y=210)
    minus = Button(Hinzu, text="-", width=2, bg="#FFFFFF", relief="raised", bd=1, command =M)
    minus.place(x=23, y=210)
    var = 0
    var2 = 600
    for i in range(100):
        var = var - 6
        var2 = var2 - 6
        Hinzu.place(x=var2, y=0)
        main.place(x=var, y=0)
        sleep(0)
        root.update()

root = Tk()
root.title("Datei Manager v.1.1")
root.resizable(0, 0)
root.geometry("600x300+330+100")
root.config(bg="#FFFFFF")
root.iconbitmap(r"Datei Icon.ico")
root.attributes("-topmost", False)

try:
    import winsound as sound
except:
    messagebox.showerror \
                         ("!Error!", "Das Modul 'Winsound'\nKonnte nicht gefunden werden!")

main = Frame(root, height=300, width=600, bg="#FFFFFF")
main.place(x=0, y=0)

D_Widerherstellen = Button(main, text="Dateien Widerherstellen >", width=20, bg="#FFFFFF",
                           relief="raised", bd=1, font="Bahnschrift 14 bold", command = n1, justify="left")
D_Widerherstellen.place(x=0, y=80)

D_Hinzufuegen = Button(main, text="Dateien Verwalten >", width=20, bg="#FFFFFF",
                           relief="raised", bd=1, font="Bahnschrift 14 bold", command = n2, justify="left")
D_Hinzufuegen.place(x=0, y=120)

root.mainloop()

Benutzeravatar
__blackjack__
User
Beiträge: 13103
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Code_Bender: Und da ist noch viel mehr im Argen…

Sternchen-Importe, `sleep()` und `update()`, Namensgebung, lokale Funktionen, Pfade als Zeichenketten manipulieren statt mit den Funktionen aus `os.path()` oder `pathlib`, `place()`, nackte ``except``\s ohne konkrete Ausnahmen die erwartet werden, …
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

Funktionsnamen schreibt man klein_mit_unterstrich. KOMPLETT_GROSS ist für Konstanten reserviert. Verschachtelte Funktionen sollte man nicht benutzten, so dass man gleich zum nächsten Problem kommt, dass jedes nicht-triviale GUI-Programm zwingend Klassendefinitionen braucht. `update` und lang laufende Schleifen sollte es in GUIs nicht geben. sleep hat da auch nichts verloren. So funktioniert ereignisbasierte Programmierung, wie sie bei GUIs benutzt wird, nicht.
Die Variablennamen sind oft kryptische Abkürzungen, die nicht verständlich sind, oder sind zu generisch (var) oder gar durchnummeriert. Dateien, die man öffnet, sollte man auch wieder schließen, Strings haben aber keine close-Methode. Der Filemode `r+` ist nie sinnvoll, weil Textdateien nicht so veränderbar sind.
Code_Bender
User
Beiträge: 21
Registriert: Sonntag 6. Januar 2019, 12:32

Es geht ja nicht um den Code sondern um Die Listbox deren auswahl ich als Int variable haben will.
__deets__
User
Beiträge: 14539
Registriert: Mittwoch 14. Oktober 2015, 14:29

Was ist die Auswahl denn? Hast du dir das mal einfach ausgegeben?
Code_Bender
User
Beiträge: 21
Registriert: Sonntag 6. Januar 2019, 12:32

Ich habe eine liste und wenn ich einen Listbox solt anklicke soll er mir die slotzahl angeben
__deets__
User
Beiträge: 14539
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das beantwortet nicht meine Frage. Was gibt dir curselection zurück?
Benutzeravatar
__blackjack__
User
Beiträge: 13103
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Das kann man übrigens auch in der Tkinter-Referenz nachlesen: https://infohost.nmt.edu/tcc/help/pubs/ ... index.html
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Code_Bender
User
Beiträge: 21
Registriert: Sonntag 6. Januar 2019, 12:32

Es gibt mit ein in klammer gesetzen float zurück
Benutzeravatar
__blackjack__
User
Beiträge: 13103
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Code_Bender: Nein, tut es nicht. Schau mal mit `type()` nach oder eben in der Referenzdokumentation.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Code_Bender
User
Beiträge: 21
Registriert: Sonntag 6. Januar 2019, 12:32

wenn ich z.B.:
print(listbox.curselection())
dann kommt :
(0,0)
__deets__
User
Beiträge: 14539
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ja. Und was ist das deiner Meinung nach? Wenn die Floating-Point Zahl 0.0 ausgibst, kommen da auch Klammern und ploetzlich nen Komma? Oder koennte das ggf. etwas anderes sein? Und was koennte es dann mit deiner Fehlermeldung "TypeError: list indices must be integers or slices, not tuple" zu tun haben? Man beachte den Teil nach dem Komma.

Und wenn du einen Text markierst, mitten in deinem Eingabefeld, wie wuerdest du das wohl beschreiben wenn du willst, das dein Kumpel genau den gleichen Abschnitt markiert? Was macht da Sinn? Eine Fliesskommazahl? Oder ggf. doch zwei andere Sachen?
Benutzeravatar
__blackjack__
User
Beiträge: 13103
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Code_Bender: Genau. Und wenn Du davon den `type()` ausgibst wird das sicher nicht `float` sein. Wobei jetzt speziell dieser Werte eigentlich nicht sein kann und den hast Du auch nicht kopiert sondern ”abgetippt”.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Code_Bender
User
Beiträge: 21
Registriert: Sonntag 6. Januar 2019, 12:32

aber Listbox hat keinen attribut namens "type"
Code_Bender
User
Beiträge: 21
Registriert: Sonntag 6. Januar 2019, 12:32

kannst du mal ein beispiel geben, denn bei mir gibts keinen Listbox attribut namens "type()"
Benutzeravatar
__blackjack__
User
Beiträge: 13103
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Code_Bender: `type()` ist eine eingebaute Funktion die den Typ des Arguments ermittelt. Und den kannst Du dann ausgeben.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Code_Bender
User
Beiträge: 21
Registriert: Sonntag 6. Januar 2019, 12:32

wenn ich selection = type(listbox.get("active")) und dann print(selection) mache dann kommt "<class 'str'>" raus
Benutzeravatar
__blackjack__
User
Beiträge: 13103
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Code_Bender: Deckt sich mit der Dokumentation zu der Methode.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten