Seite 2 von 3

Re: Datenübergabe mit Listbox und grid

Verfasst: Freitag 26. Oktober 2012, 19:45
von wuf
Nobuddy hier habe ich dir noch ein Snippet in welchem das Tkinter-Steuervariable-Object (StringVar()) verwendet wird:

Code: Alles auswählen

import tkinter as tk

def entry_output():
    print(entry_var.get())

app_win = tk.Tk()

entry_var = tk.StringVar()
tk.Entry(app_win, textvariable=entry_var, bg='white').pack(padx=10, pady=10)
entry_var.set("Meine Eingabe")

tk.Button(app_win, text="Ausgabe", command=entry_output).pack(pady=10)

app_win.mainloop()
Du kannst natürlich auf eine Steuervariable verzichten und mit dem Entry-Object arbeiten:

Code: Alles auswählen

entry.delete(0, END)
entry.insert(0, String)
entry.get()
OK. Wünsche dir noch ein schönes Wochenende.

Gruß wuf :wink:

Re: Datenübergabe mit Listbox und grid

Verfasst: Samstag 27. Oktober 2012, 11:24
von Nobuddy
Hallo wuf,
Das mit StringVar() wurde ja im aktuellen Code so umgesetzt, wie im Snippet.
Das Snippet verdeutlicht aber nochmals die Wirkungsweise in einem einfachen Beispiel.
Werde mir dies verinnerlichen, Danke für Deine Info. :wink:

Bei noch mehr Entryś in meinem Fenster, benötige ich ja eine Scrollbar.
Da werde ich dann auch nochmals die Labels anderst konfigurieren müssen, daß die Benennungsspalte und die Eingabespalte in einem Label zusammen sind.
Sind da dann weitere Umbaumaßnahmen erforderlich?

Wünsche Dir auch ein schönes Wochenende ... bei uns hat es schon mit Schnee angefangen. :D
Grüße Nobuddy

Re: Datenübergabe mit Listbox und grid

Verfasst: Samstag 27. Oktober 2012, 14:42
von yipyip
Mann, seit ihr fix, da kommt man mit der Krittelei ja gar nicht hinterher.

Das Layout ist bruechig, verwendet man eine andere Fontgroesse z.B. 11 statt 14, dann passt es schon nicht mehr. Das liegt an all den magischen Zahlen, die in Abhaengigkeit von der Fontgroesse stehen. Also ein Grid mit (Label, Entry) fuer jede Zeile nehmen.

Man hat nicht mehrere Models sondern nur eines. Die Model-Klasse stellt sozusagen ein Interface zwischen Controller und Kundendaten her. (In Ermangelung von Daten und um ein minimales Beispiel zu bringen, habe ich einfach die Listbox-Items als Kundendaten missbraucht.)

Sind die Listbox-Items statisch? Dann koennen sie eventuell auch in die Gui-Konfigration.
Aendern sich die Name-Items in Abhaengigkeit von der Listbox Auswahl? Dann vielleicht doch eine Methode im Model, die die passenden Labels bereitstellt.

In der Anfangsphase mehr auf die Programmstruktur achten und das Ganze mit so wenigen Items wie moeglich austesten. Das Layout verbessern und weitere Items hinzufuegen kann man dann nach und nach.

Bald ist dann aber auch ein Github Repository faellig.
:wink:
yipyip

Re: Datenübergabe mit Listbox und grid

Verfasst: Samstag 27. Oktober 2012, 16:45
von Nobuddy
Hallo yipyip,
Ja ... sollte bis Weihnachten fertig werden ... :lol:

Habe das Layout etwas optimiert, unter anderem habe ich Benennungs- und Entry-Feld jetzt innerhalb eines Label gebunden.

Zum brüchigen Layout. Bei mir stelle ich keinen Unterschied fest, wenn ich die Fontgröße von 14 auf 11 ändere. Klar, die Schrift ist kleiner aber sonst. Oder meinst du etwas anderes damit?

Habe mir schon grid angeschaut und ein bischen getestet, kann mich da aber noch nicht so damit anfreunden.
Zumal es ja heißt, daß man grid und pack nicht mischen soll. Wäre das für die Verwundung einer Scrollbar notwendig?

Verstehe ich Dich richtig, daß man nur eine Item-Liste an Model übergeben darf(sollte), das wäre ja schade.
In wie weit beeinflusst es den Ablauf, wenn wie bei mir zwei Model-Klassen erstellt sind?

Die Listbox-Items sind statisch, Änderungen sind aber möglich.
Bei der Listbox-Auswahl, steht ein Namens-Item zur Abhängigkeit.

Gerade bei den Items für die Entryś, wäre es gut wenn ich noch ein paar mehr verwenden könnte, aber das sprengt mein Fenster und ich komme an die unteren Entryś und Buttons nicht ran. Da wäre eine Scrollbar notwendig.

Hier mal das Github: https://gist.github.com/3965121

Grüße Nobuddy

Re: Datenübergabe mit Listbox und grid

Verfasst: Samstag 27. Oktober 2012, 17:06
von yipyip
Bis Weihnachten? Das wird aber knapp... :wink:
Beziehe mich auf die letzte Demo von wuf, bei denen davor sollte es auch nicht anders sein:
Label und Entry liegen nicht mehr auf einer Linie bei Fontgroessen von z.B. 11, 21.
(Jedenfalls bei mir)

Du kannst doch einem Model auch mehrere Dinge uebergeben.
Wie man das mit entsprechenden Methoden organisiert, das steht alles noch aus.

Eine Scrollbar sollte auch kein Problem sein. Hier sollten zig online Snippets herumfliegen,der
Rest liegt im Paste-Pocoo Nirvana.

:wink:
yipyip

Re: Datenübergabe mit Listbox und grid

Verfasst: Samstag 27. Oktober 2012, 17:21
von yipyip
Sorry, sind bei dir doch auf einer Linie (in der Gisthub Demo).

Re: Datenübergabe mit Listbox und grid

Verfasst: Sonntag 28. Oktober 2012, 15:13
von Nobuddy
Was Scrollbar angeht, gibt es schon eine Menge Input beim Googeln.
Leider komme ich über eine bestimmte Stelle nicht hinaus.
Ich sehe zwar meine Scrollbar schön an dem Platz den ich mir ausgesucht habe.
Da die Listbox, sowie die Buttons unten fest bleiben sollen, habe ich mir den Label ausgesucht in dem dann die Entry-Felder platziert werden.
Hier mal der Code-Ausschnitt:

Code: Alles auswählen

        self.place_maker = tk.Label(self.frame,
            bg=conf['back_ground'], height=(box_length + 9),
            width=left_width, bd=0, highlightthickness=0)
        self.yscrollbar = tk.Scrollbar(self.place_maker, width=12,
            troughcolor='gray')
        self.yscrollbar.pack(side='right', fill='y')
        self.place_maker.pack(fill='both', expand=False)

        self.yscrollbar.config(command=self.place_maker.yview)
        self.place_maker.config(yscrollcommand=self.yscrollbar.set)
Ich bekomme aber immer die Fehlermeldung:
Traceback (most recent call last):
File "gui_KundenNeu.py", line 152, in <module>
main()
File "gui_KundenNeu.py", line 149, in main
Controller().run()
File "gui_KundenNeu.py", line 122, in __init__
CONFIG)
File "gui_KundenNeu.py", line 66, in __init__
self.yscrollbar.config(command=self.place_maker.yview)
AttributeError: 'Label' object has no attribute 'yview'
Ich denke, daß da ein Eintrag im Model fehlt, bin aber bisher nicht drauf gekommen.

Re: Datenübergabe mit Listbox und grid

Verfasst: Sonntag 28. Oktober 2012, 15:50
von wuf
Hi Nobuddy

Wie du aus der Fehlermeldung siehst:
AttributeError: 'Label' object has no attribute 'yview'
fehlt beim Label-Widget offenbar die Methode 'yview'.

Soviel ich weiss sind folgende Widget mit der Scrollbar beeinflussbar. Es sind:
a) Canvas (horizontal/vertikal)
b) Listbox (horizontal/vertikal)
c) Text (horizontal/vertikal)
d) Entry (nur horizontal)

Also mit dem Label-Widget wie in deinem Fall geht es nicht. Ich schlage vor du solltest an Stelle vom Label ein Canvas-Widget nehmen.

Gruß wuf :wink:

Re: Datenübergabe mit Listbox und grid

Verfasst: Sonntag 28. Oktober 2012, 15:57
von Nobuddy
Hallo wuf,
Danke für die Info, werde mich darüber informieren!

Grüße Nobuddy

Re: Datenübergabe mit Listbox und grid

Verfasst: Sonntag 28. Oktober 2012, 16:32
von Nobuddy
Mit Canvas sieht das schon anderst aus.
Kann den Balken jetzt schon mal nach unten ziehen, aber das Fenster scrollt nicht mit.
Noch ein kleiner Konfigurationsfehler?

Code: Alles auswählen

self.place_maker = tk.Canvas(self.frame, scrollregion=(0,0,300,1500),
            bg=conf['back_ground'], height=(box_length + 9),
            width=left_width, bd=0, highlightthickness=0)
        self.yscrollbar = tk.Scrollbar(self.place_maker, width=12,
            troughcolor='gray')
        self.yscrollbar.config(command=self.place_maker.yview)
        self.place_maker.config(yscrollcommand=self.yscrollbar.set)
        self.place_maker.pack(fill='both', expand=False)
        self.yscrollbar.pack(side='right', fill='y')

Re: Datenübergabe mit Listbox und grid

Verfasst: Sonntag 28. Oktober 2012, 17:17
von yipyip
Vergleiche es mal mit meinem Code:
http://www.python-forum.de/pastebin.php?mode=view&s=307

:wink:
yipyip

Re: Datenübergabe mit Listbox und grid

Verfasst: Sonntag 28. Oktober 2012, 18:14
von wuf
OK Nobuddy

Habe dein Skrip ein wenig bereinigt und ausfürbar gemacht. Als nächstes muss du ein Frame welches die Eingabezeilen (Entries) enthält auf die Canvas bringen. Ein Tip ist:

Code: Alles auswählen

 canvas.create_window(0, 0, window=entry_frame, anchor='nw')
Hier noch die scrollable Canvas Skript:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
try:
    #~~ For Python 2.x
    import Tkinter as tk
except ImportError:
    #~~ For Python 3.x
    import tkinter as tk

CONFIG = {
    'back_ground' : 'orange',
    'canvas_width' : 300,
    'canvas_height' : 300,
    }
    
class SrollableCanvas(tk.Canvas):

    def __init__(self, parent, conf):
        self.parent = parent
        self.conf = conf
 
        tk.Canvas.__init__(self, self.parent,
            scrollregion=(0, 0, 300, 1500),
            bg=self.conf['back_ground'],
            width=self.conf['canvas_width'],
            height=self.conf['canvas_height'],
            bd=0,
            highlightthickness=0)
        self.grid(column=0, row=0)
            
        self.yscrollbar = tk.Scrollbar(self.parent, width=12,
            troughcolor='gray')

        self.yscrollbar.grid(column=1, row=0, sticky='ns')
        self.yscrollbar.config(command=self.yview)
        
        self.config(yscrollcommand=self.yscrollbar.set)
        
        
        self.create_line(0, 0, 300, 1500, width=4, fill='red')    
   
app_win = tk.Tk()
app_win.title('Scrollable canvas')
app_win.geometry('+20+20')

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

SrollableCanvas(main_frame, CONFIG)
        
app_win.mainloop()
Gruß wuf :wink:

Re: Datenübergabe mit Listbox und grid

Verfasst: Montag 29. Oktober 2012, 10:28
von Nobuddy
Hallo zusammen :wink:

Als erstes habe ich die Variante von yipyip in den bestehenden Code integriert.
yipyip, Danke dafür! :wink:
Dabei habe ich noch in einem Thread von wuf, das ermitteln des Fullscreen entdeckt, was ich auch eingebaut habe.
Das ist sinnvoll, wenn die Fenstergrößen ein Maximum benötigen und der Benutzer nicht die Fenstergröße seines Fullscreen kennt.
Manchmal wird die Größe des Fullscreen auch nicht benötigt, da wäre es dann geschickt die Größe des aktuellen Bedarfs zu verwenden. Nur wie man das auf die Reihe bekommt, beide Optionen miteinander zu vereinen, da bin ich noch nichts dahinter gekommen.
Ist so etwas möglich?

Hier jetzt mal yipyipś Variante: https://gist.github.com/3972548

wuf, als nächstes werde ich mich mit Deiner Variante beschäftigen.
Melde mich dann wieder! :wink:

Grüße Nobuddy

Nachtrag:
Habe in der Ausgabe von gist.gihub in CONFIG, ''width' : 100' entfernt und dafür in der self.conf ein Update durchgeführt.

Code: Alles auswählen

CONFIG = {'title' : "Anlage Neukunden",
        'font': ('NimbusSansL', 14, 'bold'),
        'font_color': 'black',
        'back_ground' : 'orange',
        'select_mode': 'single'}

DEFAULT_LABELS = ['Kundenkreis', 'Namen', 'Zusatz', 'Straße, Nr.', 'PLZ', 
        'Ort', 'USt-Ident-Nr.', 'Ansprechpartner', 'Telefon', 'Handy',
        'Fax', 'Mail','Internetseite']

LISTBOX_ITEMS = {'0' : 'Privatkunde',
        '1' : 'Kleinbetrieb, bis 1000 € Jahresumsatz',
        '2' : 'Mittelständischer Betrieb, bis 10.000 € Jahresumsatz',
        '3' : 'Großbetrieb, bis 25.000 € Jahresumsatz',
        '4' : 'Konzern, ab 25.000 € Jahresumsatz',
        '5' : 'Komunaler Träger'}

class ListGui(object):

    def __init__(self, controller, items, conf):
 
        self.root = tk.Tk()
        xpos = 0
        ypos = 0
        screenx = self.root.winfo_screenwidth()
        screeny =  self.root.winfo_screenheight()
        self.root.geometry("%dx%d+%d+%d" % (screenx, screeny, xpos, ypos))
        self.root.title(conf['title'])
        self.controller = controller
        self.conf = conf
        self.conf.update({'width' : screenx})

Re: Datenübergabe mit Listbox und grid

Verfasst: Montag 29. Oktober 2012, 12:39
von yipyip
Moeglich ist bei der Konfiguration (fast) alles. :wink:
Simple Logik: Sind in der Konfiguration gueltige Werte, werde diese genommen, ansonsten Fullscreen.
Beispiel: Steht in der Config z.B. width=0, dann wird auf Fullscreen gesetzt, stehen
dort Werte > 0 fuer width und height, werden diese uebernommen.
:wink:
yipyip

Re: Datenübergabe mit Listbox und grid

Verfasst: Montag 29. Oktober 2012, 19:30
von Nobuddy
Danke für die Info yipyip!
Habe im Bereich der Fensterhöhe, das Ganze noch etwas optimiert.

https://gist.github.com/3975466

Hoffe, daß es von der Umsetzung so ok ist.

An dieser Stelle, einen Herzlichen Dank an wuf und yipyip! :wink:

Grüße Nobuddy

Re: Datenübergabe mit Listbox und grid

Verfasst: Montag 29. Oktober 2012, 20:20
von yipyip
geo_check: Der Controller sollte nichts ueber die Innereien von Tkinter wissen. Mach die ganzen geo-Sachen im View, also in der ListGui Klasse. (Eventuell gesteuert von den Config Daten)
Das mit dem 'global geoxy' gehoert besser geloest. (also ohne global)
Statt:

Code: Alles auswählen

return (sum([i for i in geoxy]))
reicht auch ein

Code: Alles auswählen

return sum(geoxy)
:wink:
yipyip

Re: Datenübergabe mit Listbox und grid

Verfasst: Dienstag 30. Oktober 2012, 10:40
von Nobuddy
Hast ja völlig Recht, das geht wirklich wesentlich einfacher.
Habe alles bereinigt, auch in der Class Controller.

Hier die aktuelle gist.github: https://gist.github.com/3979267

Danke für die Info! :wink:

Grüße Nobuddy

Re: Datenübergabe mit Listbox und grid

Verfasst: Mittwoch 31. Oktober 2012, 16:40
von Nobuddy
Eine Frage hätte ich doch noch. :wink:

Gibt es eine Möglichkeit, daß man mit der Maus den Scrollbalken bewegt, den auch mit dem Scrollrad der Maus bedienen kann?
Wenn ja, wo muß ich da ansetzen?

Grüße Nobuddy

Re: Datenübergabe mit Listbox und grid

Verfasst: Mittwoch 31. Oktober 2012, 19:20
von wuf
Hi Nobuddy

No problem. Du musst folgende Ergänzungen durchführen:

Code: Alles auswählen

        canvas.config(yscrollcommand=yscroll.set)
        scroll_frame.grid_rowconfigure(0, weight=1)
        # Hier neu hinzufügen
        self.canvas = canvas
        self.bind_scroll(yscroll, self.y_scroll)
Diese Methoden nach der Methode 'run' in Klasse 'ListGui' einfügen:

Code: Alles auswählen

    def bind_scroll(self, widget, mode):
        #~~ Windows
        widget.bind("<MouseWheel>", mode)
        #~~ Linux       
        widget.bind("<Button-4>", mode)
        widget.bind("<Button-5>", mode)

    def y_scroll(self, event):
        if event.num == 5 or event.delta < 0:
            self.canvas.yview_scroll(1, "unit")
        elif event.num == 4 or event.delta > 0:
            self.canvas.yview_scroll(-1, "unit")
Probier es einmal aus. Vielleicht funktioniert es.

Gruß wuf :wink:

Re: Datenübergabe mit Listbox und grid

Verfasst: Donnerstag 1. November 2012, 10:16
von Nobuddy
Hallo wuf,

Danke für Deinen Tip, funktioniert prima! :wink:

Werde mir das genau anschauen, daß ich zukünftig das auch umsetzen kann.

Grüße Nobuddy