Seite 1 von 1

Fram+Listbox: height < 3, Auswahl anzeigen mit curselecti

Verfasst: Samstag 27. Juni 2009, 13:11
von py-mule
Hallo,

1.
gibt es die Möglichkeit dieses Fenster (mit Listbox) kleiner als height = 3, also height = 2 zu erzeugen. Leider hat dieses, auch wenn ich height = 2 einstelle als kleinste Realisierung height = 3. Das passt leider nicht in mein Raster mit den anderen Labels, Buttons und Entrys.

2.
Der Abschnitt def pol(): für Verarbeitung von int oder Zeilen-Nummern ausgelegt, weiß ich noch nicht genau. Wie muß ich diesen Abschnitt verändern, damit beim Anklicken einer Zeile der Listbox mit der Maus der tatsächliche Ihnhalt ausgegeben wird?

Code: Alles auswählen

import Tkinter
import os

frame_listbox = Tkinter.Frame()
s = Tkinter.Scrollbar(frame_listbox)

L = Tkinter.Listbox(frame_listbox, width = 60, height = 2)
s.pack(side=Tkinter.RIGHT, fill=Tkinter.Y)
L.pack(side=Tkinter.LEFT, fill=Tkinter.Y)
  

s['command'] = L.yview
L['yscrollcommand'] = s.set
 
#for i in range(30):                    Ursprünglicher Eintag
       #L.insert(Tkinter.END, str(i))

# meine Modifikation

liste = ['Name1', 'Name2', 'Name3']

str_ing = ''
for  str_ing in liste:
        L.insert(Tkinter.END, str(str_ing))


frame_listbox.pack(side=Tkinter.TOP)
frame_listbox.pack

F2 = Tkinter.Frame()
lab = Tkinter.Label(F2)

def poll():
        lab.after(200, poll)
        sel = L.curselection()
        lab.config(text=str(sel))

lab.pack()
F2.pack(side=Tkinter.TOP)
 
poll()
Gruß
py-mule

Verfasst: Samstag 27. Juni 2009, 19:43
von py-mule
Das mit String auslesen habe ich nun hinbekommen und zwar so:

Code: Alles auswählen

def poll():
        lab.after(200, poll)
        #sel = L.curselection()
        sel = L.get(L.curselection()[0])
        lab.config(text=str(sel))
Allerdings bekomme ich die Fehlermeldung:

tuple index out of range

Ok. in

Code: Alles auswählen

sel = L.get(L.curselection()[0])
stimmt noch irgendetwas nicht,
aber was?

Verfasst: Samstag 27. Juni 2009, 19:57
von Leonidas
Vielleicht bekommst du ja ein leeres Tupel. Lass dir halt den Wert mal anzeigen.

Verfasst: Samstag 27. Juni 2009, 20:11
von py-mule
Ich weiß nicht, ob ich es sauber hinbekommen habe, aber so funktioniert es ohne Fehlermeldung:

Code: Alles auswählen

def poll():
        
        lab.after(200, poll)
        for i in L.curselection():

                sel = L.get(i)
                lab.config(text=sel)
Jetzt habe ich den String in sel. Das str() in lab.config(text=str(sel)) war übrigens auch überflüssig, da sel ja schon ein str ist.

Bleibt nur noch das Problem mit der Fenstergröße.

Gruß
py-mule

Verfasst: Samstag 27. Juni 2009, 21:12
von yipyip
Also bei mir funktionierts:

Code: Alles auswählen

import Tkinter as tk

class Gui(object):
  
  def __init__(self, root, width, height):

    self.root = root
    self.frame = tk.Frame(self.root)
    self.svar = tk.StringVar()
    
    self.lbox = tk.Listbox(self.frame, width=width, height=height,
                           listvariable=self.svar,
                           selectmode=tk.EXTENDED,
                           selectbackground='red')
    self.lbox.pack(side=tk.LEFT, fill=tk.Y, expand=True, fill=tk.BOTH )
                      
    self.yscroll = tk.Scrollbar(self.frame, orient='vertical')
    self.lbox.config(yscrollcommand=self.yscroll.set)
    self.yscroll.config(command=self.lbox.yview)
    self.yscroll.pack(side=tk.LEFT, fill=tk.Y)

    self.svar.set(' '.join(chr(i) for i in range(65, 91)))
    self.frame.pack(expand=True, fill=tk.BOTH)
    self.lbox.bind('<ButtonRelease-1>', self.show)
    
    self.labvar=tk.StringVar()
    self.lab = tk.Label(self.root, textvariable=self.labvar)
    self.lab.pack()
    
    self.lbox.insert(tk.END, "huhu")


  def show(self, ev):

    text = ' '.join(self.lbox.get(i) for i in self.lbox.curselection())
    self.labvar.set(text)

                       
if __name__ == '__main__':
    
  root = tk.Tk()
  Gui(root, 60, 2)
  root.mainloop()
Betrueblicherweise ist die wichtigste Seite des Internets, der Effbot, nicht erreichbar...
:(
yipyip

Verfasst: Freitag 3. Juli 2009, 11:28
von py-mule
Gibt es eine Möglichkeit den Timer

Code: Alles auswählen

lab.after(200, poll)
anzuhalten?

Verfasst: Freitag 3. Juli 2009, 11:50
von BlackJack
@py-mule: Ja, gibt es:

Code: Alles auswählen

In [23]: tk.Widget.after?
Type:           instancemethod
Base Class:     <type 'instancemethod'>
String Form:    <unbound method Widget.after>
Namespace:      Interactive
File:           /home/bj/lib-tk/Tkinter.py
Definition:     tk.Widget.after(self, ms, func=None, *args)
Docstring:
    Call function once after given time.

    MS specifies the time in milliseconds. FUNC gives the
    function which shall be called. Additional parameters
    are given as parameters to the function call.  Return
    identifier to cancel scheduling with after_cancel.

Verfasst: Freitag 3. Juli 2009, 12:09
von wuf
Hallo py-mule

Hier noch ein Code-Snippet zum ausprobieren:

Code: Alles auswählen

import Tkinter as tk

def flash_led():
    """Blink-Taktgeber"""

    if led['bg'] == 'brown':
        led.config(bg='red')
    else:
        led.config(bg='brown')

    app_win.flash_timer_obj = led.after(500, flash_led)

def flash_control():
    """Timer-Steuerung"""

    if button['text'] == "Stopp-Flashing":
        led.config(bg='brown')
        button.config(text="Start-Flashing")
        led.after_cancel(app_win.flash_timer_obj)
    else:
        button.config(text="Stopp-Flashing")
        flash_led()

app_win = tk.Tk()

app_win.flash_timer_obj = None

led_frame = tk.Frame(app_win)
led_frame.pack()

button_frame = tk.Frame(app_win)
button_frame.pack()

led = tk.Canvas(led_frame, bg='brown', width= 150, height=50)
led.pack(fill='x', padx=2, pady=2)

button = tk.Button(button_frame, text="Stopp-Flashing", command=flash_control)
button.pack(padx=2, pady=2)

flash_led()

app_win.mainloop()
Gruss wuf :wink:

Verfasst: Freitag 3. Juli 2009, 21:28
von py-mule
Ja, das ist es.

Ich habe auch noch eine Erklärung dazu gefunden:
w.after ( delay_ms, callback=None, *args )

Requests Tkinter to call function callback with arguments args after a delay of at least delay_ms milliseconds. There is no upper limit to how long it will actually take, but your callback won't be called sooner than you request, and it will be called only once.

This method returns an integer “after identifier” that can be passed to the .after_cancel() method if you want to cancel the callback.

If you do not pass a callback argument, this method waits delay_ms milliseconds, as in the .sleep() function of the standard Python time module7.


w.after_cancel ( id )

Cancels a request for callback set up earlier .after(). The id argument is the result returned by
the original .after() call.
Vielen Dank
py-mule