Seite 1 von 2

Verfasst: Montag 3. Dezember 2007, 11:32
von BlackVivi
Wenn ich jedes lb mit'n self.lb ersetz und bei read natürlich noch das Argument self hinzukommt

Code: Alles auswählen

def read(self, event): 
    text = self.lb.get(lb.curselection()) 
    print text 
Jedoch gibts dann noch Probleme mit dem Eventbinding und außerdem benutzt du einen außerordentlich bösen Sternimport. Mit self globalisierst du auch nicht, sondern bindest die Variable an die Instanz der Klasse.

(Ich würd' dir ja jetzt'n funktionierendes Beispiel geben, aber von Tkinter hab ich recht wenig Ahnung)

Verfasst: Montag 3. Dezember 2007, 11:41
von sorgenlos
Was ist am Sternimport denn böse? :)

und deinen Lösungsansatz hatte ich auch schon eingeschlagen, aber:

Code: Alles auswählen

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Python25\lib\lib-tk\Tkinter.py", line 1403, in __call__
    return self.func(*args)
TypeError: read() takes exactly 2 arguments (1 given)

Verfasst: Montag 3. Dezember 2007, 12:04
von BlackVivi
Man überschreibt Schlüsselwörter, die Übersichtlichkeit geht flöten und der Quellcode wird unübersichtlicher. Hab'n bissel rumgespielt, ist sicherlich total schlechter tkinter Stil, jedoch funktioniert die Version...

(UM NOCHMAL DARAUF HINZUWEISEN!!! Ich bin kein Tkinter Programmierer. Der Quelltext stellt keine Referenz dar!)

Code: Alles auswählen

import Tkinter as tk

class test_GUI: 
    def __init__(self): 
        
        fenster = tk.Tk() 
        fenster.geometry("110x75") 
    
        #Die Listbox    
        self.lb = tk.Listbox(fenster, selectmode=tk.EXTENDED) 
        self.lb.pack() 
        self.lb.place(x=18, y=10, width=80, height=35) 
        self.lb.insert(tk.END, "Peter") 
        self.lb.insert(tk.END, "Hans") 
    
        #Der Button    
        test_button = tk.Button(fenster, text="test", command=self.read) 
        test_button.place(x=6, y=50, width=100, height=20) 

    #die Methode        
    def read(self): 
        for i in self.lb.curselection():
            text = self.lb.get(i) 
            print text 
        
__name__ == '__main__' 
dasFenster = test_GUI() 
tk.mainloop()

Verfasst: Montag 3. Dezember 2007, 12:08
von BlackJack
Vielleicht solltest Du Dich erst einmal nur mit Klassen, ohne GUI beschäftigen. Das erste Argument bei Methoden ist immer die Instanz auf der die Methode aufgerufen wird. Dein `event` ist also eigentlich `self` und beim Druck auf den den Button wird an die `command`-Funktion gar nichts übergeben.

Code: Alles auswählen

import Tkinter as tk

class TestGUI: 
    def __init__(self): 
        fenster = tk.Tk()
    
        self.listbox = tk.Listbox(fenster,
                                  selectmode=tk.EXTENDED,
                                  width=10,
                                  height=2)
        for name in ('Peter', 'Hans'):
            self.listbox.insert(tk.END, name)
        self.listbox.pack()
    
        test_button = tk.Button(fenster, text='test', command=self.read)
        test_button.pack()
    
    def read(self):
        print self.listbox.get(self.listbox.curselection())


if __name__ == '__main__':
    das_fenster = TestGUI()
    tk.mainloop()
Da sind so gut wie alle manuelle Grössenangaben herausgenommen, das kann der Layout-Manager im allgemeinen besser als der Programmierer, weil der ja gar nicht alle möglichen Schrifteinstellungen, Schriftgrössen und Windowmanager testen kann.

Die Grösse der `Listbox` sollte man auch dort beim Konstrukturaufruf angeben, weil die Höhe da z.B. in Zeilen/Einträgen angegeben wird. Das passt dann immer, im Gegensatz zu dem `place()` wo bei mir in der Anzeige der untere Rand vom zweiten Eintrag nicht mehr dargestellt wurde.

Verfasst: Montag 3. Dezember 2007, 14:53
von sorgenlos
Gut, das Globlisieren funktioniert jetzt einwandfrei :wink: vielen Dank nochmal an euch, das hat noch paar andere Fehler behoben.

Das einzige was jetzt noch fehlt ist der "Fokus" ich weiß nicht wie das sonst nennen soll :D Ich will einfach nur das die Auswahl in den Boxen bleibt und nicht verschwindet.

hier ein flash-Filmchen, damit ihr versteht was ich meine :lol: :

Klick mich zum Anschaun

ich find dazu auch nichts in keinem der offiziellen Tutorials :?

Verfasst: Montag 3. Dezember 2007, 16:41
von pyStyler
selectmode könnte die Lösung sein?

Code: Alles auswählen

tk.Listbox(hp, selectmode=tk.MULTIPLE)

Verfasst: Montag 3. Dezember 2007, 17:26
von sorgenlos
PROBLEM GELÖST

Selectmode bestimmt aber nur das Verhalten innerhalb einer Listbox.

Um zwei unabhängige Listboxen zu bekommen die sich nicht gegenseitig deselektiern nimmt man noch als zusatz:

Code: Alles auswählen

 tk.Listbox(hp, selectmode=tk.MULTIPLE, exportselection=0)

Verfasst: Sonntag 9. Dezember 2007, 18:29
von sorgenlos
Ich habe ein Problem, Beispiel:

Ich habe eine Listbox mit drei Einträgen (ja, nein, vlcht)
für jedes Objekt wurde vorher die auswahl für das Objekt in einer Liste gespeichtert (andere Informationen auch, spielt aber keine Rolle)

Wenn ich in der Liste nun hin und her switche zwichen den Objekten,

soll er die Auswahl in der Listbox aktualisieren um zu zeigen welche Auswahl für das Objekt in der Vergangenheit getätigt wurde.

Ich hab diverse Sachen schon ausprobiert wie zb. set.curseletion aber es funktioniert nicht.

Hat jemand von euch eine Idee wie ich das lösen könnte?

Verfasst: Montag 10. Dezember 2007, 13:15
von schlangenbeschwörer
könntest du dein problem etwas genauer formulieren? Vlt auch ein bisschen code oder so? Abstahieren hilft auch oft.

Verfasst: Dienstag 11. Dezember 2007, 01:36
von sorgenlos
hat sich von selbst gelöst das problem, lösung folgt morgen..

Aber ich hänge nun an folgendem Problem, ich will eine Listbox wieder deselektieren um veränderung vornehmen zu können.

Der Befehl funktionierte auch,

Code: Alles auswählen

self.listbox.selection_clear(self.listbox.curselection())
jedoch bekomme ich nun diesen Fehler:

Code: Alles auswählen

 File "C:gui.py", line 707, in neu
    self.listbox.selection_clear(self.listbox.curselection())
  File "C:\Python25\lib\lib-tk\Tkinter.py", line 2530, in selection_clear
    'selection', 'clear', first, last)
TclError: bad listbox index "": must be active, anchor, end, @x,y, or a number
EDIT

ich habs auch selbst geschafft :D

Code: Alles auswählen

self.listbox.selection_clear(0,x)
x = elemente in der liste -1

Verfasst: Samstag 14. Juni 2008, 15:58
von hsv_seiwert
Mein Vorschlag für eine Dropdown-box wäre folgender:

Code: Alles auswählen

global klick
klick=0
def ausgabe():
    global klick
    klick+=1
    if klick % 2 != 0:
        global textfenster
        textfenster= Text(fenster,width=29,height=10)
        textfenster.grid(row=1,columnspan=2)
    else:
        textfenster.grid_forget()
        
from Tkinter import*  
fenster = Tk()
entry=Entry(fenster)
entry.grid(row=0)
fenster.button = Button(fenster,text ="klick mich", command=ausgabe) 
fenster.button.grid(row=0,column=1) 
# Fenster anzeigen 
fenster.mainloop()

Verfasst: Sonntag 15. Juni 2008, 20:57
von numerix
Hallo, zunächst einmal: "Willkommen im Forum."

Wenn du dir dein Posting ansiehst, stellst du sicher fest, dass man den Code nicht besonders gut lesen kann. Das lässt sich verbessern, indem du ihn in Code-Tags setzt. Dazu gibt es in der Eingabemaske extra einen Button.

Das kannst du - via edit - auch nachträglich noch machen. Solltest du mal tun, dann gibt es vielleicht auch Reaktionen auf deine "Lösung".

Re: Dropdown Box mit Tkinter // Listbox Problem

Verfasst: Sonntag 17. März 2013, 14:41
von Nobuddy
Hallo zusammen

Ich habe das Beispiel von BlackJack verwendet und es soweit abgeändert, daß der Button überflüssig ist.

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# For Python3.x

import tkinter as tk

class TestGUI:
    def __init__(self):
        fenster = tk.Tk()

        self.mylist = {0 : 'Hans', 1 : 'Peter', 2 : 'Thomas'}

        self.listbox = tk.Listbox(fenster,
                                  selectmode=tk.EXTENDED,
                                  width=10,
                                  height=len(self.mylist))
        for name in sorted(self.mylist):
            self.listbox.insert(tk.END, self.mylist[name])
            self.listbox.bind('<<ListboxSelect>>', self.check_select)
        self.listbox.pack()

    def check_select(self, event):
        """Überprüfe das Ereignis und führe den Auftrag aus"""
        indices = list(map(int, self.listbox.curselection()))
        result = ''.join([self.mylist[row]
            for row in sorted(self.mylist) if row == indices[0]])
        print(result)
        return result


if __name__ == '__main__':
    das_fenster = TestGUI()
    tk.mainloop()
Und in einem weiteren Beispiel, wird die Auswahl an das Entry-Feld übergeben.

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# For Python3.x

import tkinter as tk

class TestGUI:
    def __init__(self):
        fenster = tk.Tk()
        self.entry=tk.Entry(fenster)
        self.entry.pack()

        self.mylist = {0 : 'Hans', 1 : 'Peter', 2 : 'Thomas'}

        self.listbox = tk.Listbox(fenster,
                                  selectmode=tk.EXTENDED,
                                  width=10,
                                  height=len(self.mylist))
        for name in sorted(self.mylist):
            self.listbox.insert(tk.END, self.mylist[name])
            self.listbox.bind('<<ListboxSelect>>', self.check_select)
        self.listbox.pack()

    def check_select(self, event):
        """Überprüfe das Ereignis und führe den Auftrag aus"""
        indices = list(map(int, self.listbox.curselection()))
        result = ''.join([self.mylist[row]
            for row in sorted(self.mylist) if row == indices[0]])
        self.entry.delete(0, tk.END)
        return self.entry.insert(tk.END, result)


if __name__ == '__main__':
    das_fenster = TestGUI()
    tk.mainloop()

Re: Dropdown Box mit Tkinter // Listbox Problem

Verfasst: Sonntag 31. März 2013, 17:25
von muffin
sorgenlos hat geschrieben:Hallo Leute, ich such schon seit einiger Zeit die Möglichkeit mit Tkinter eine Dropdownbox zu erstellen, in etwa so:
... und warum versuchst du es nicht mit einer ttk.combobox?