Datenübergabe mit Listbox und grid

Fragen zu Tkinter.
Nobuddy
User
Beiträge: 1019
Registriert: Montag 30. Januar 2012, 16:38

Hallo zusammen :wink:

Habe eine kleine Änderung im bestehenden Code vorgenommen.
Ich habe die LISTBOX_ITEMS oben heraus genommen und übergebe dies nun von einem anderen Modul aus.

Code: Alles auswählen

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'}
from gui_KundenNeu import Controller
Controller(LISTBOX_ITEMS)
Die Class Controller, habe ich so entsprechend angepasst:

Code: Alles auswählen

class Controller(object):

    def __init__(self, LISTBOX_ITEMS):
        self.model = Model(LISTBOX_ITEMS)
        self.view = ListGui(self, self.model.items, CONFIG)

    def process(self, listbox_item):
        self.view.entry_vars[0].set(listbox_item)
        print(listbox_item)

    def collect_entries(self):
        entry_data = dict()
        for index, entry_var in enumerate(self.view.entry_vars):
            print("{} : {}".format(self.model.items[index],
                entry_var.get()))
            entry_data[self.model.items[index]] = entry_var.get()
        print()
        print(entry_data)

    def run(self):
        self.view.run()


class Model(object):

    def __init__(self, items):
        self.items = items


def main():
    Controller(LISTBOX_ITEMS).run()
Wenn ich nun aus der Listbox eine Zeile auswähle, wird diese nicht in der Scrollliste ausgegeben.

Hier der komplette Code: https://gist.github.com/4030749

Ich hoffe, Ihr könnt mir da weiter helfen, warum dies nicht funktioniert?

Grüße Nobuddy
Nobuddy
User
Beiträge: 1019
Registriert: Montag 30. Januar 2012, 16:38

Ich habe weitere Änderungen vorgenommen, so daß alles funktionieren sollte (was aber nicht der Fall ist).
Die Auswahl an der Listbox wird an die Entry-Liste übergeben.
In der Entry-Liste selbst ist aber kein Eintrag.

Das komische ist, daß wenn ich den Button 'Übernahme' betätige, wird die Auswahl von der Listbox in der Ausgabe der Entry_Liste mit ausgegeben. Die Eingabe, die ich in der Entry-Liste vorgenommen haben, fehlen aber!

Hier der aktuelle Code: https://gist.github.com/4033430
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hi Nobuddy

Für deine letzten Modifikation nehme ich Bezug auf:
https://gist.github.com/4033430
Ich bezeichne diese als Moduldatei (deine Namengebung 'gui_KundenNeu.py') In dieser Datei befinden sich die Kofigurationliste CONFIG, und die folgenden Klassen:
ListGui
Controller
Model

Hier würde ich die Methode process in Klasse Controller wie folgt abändern:

Code: Alles auswählen

    def process(self, listbox_item):
        self.view.entry_vars[0].set(listbox_item)
        print(self.view.entry_vars[0])
Meine Frage. Warum schreibst du in der folgenden Zeile die Parameternamen in Grossbuchstaben (wie Konstanten)?:

Code: Alles auswählen

def __init__(self, LISTBOX_ITEMS, DEFAULT_LABELS, MAIN_TITLE, SUB_TITLE):
Ich nehme an die Datei (Name noch unbekannt) in welcher du die Moduldatei gui_KundenNeu importierst sieht in der Zwischenzeit wie folgt aus:

Code: Alles auswählen

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

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'}

DEFAULT_LABELS = ['Kundenkreis', 'Namen', 'Zusatz', 'Straße, Nr.', 'PLZ',
        'Ort', 'USt-Ident-Nr.', 'Ansprechpartner', 'Telefon', 'Handy',
        'Fax', 'Mail','Internetseite']
        
import gui_KundenNeu as app
app.Controller(LISTBOX_ITEMS, DEFAULT_LABELS, "Haupttitel", "Untertitel").run()
Habe die Zeilen deines vorletzten Post von:

Code: Alles auswählen

from gui_KundenNeu import Controller
Controller(LISTBOX_ITEMS)
auf

Code: Alles auswählen

import gui_KundenNeu as app
app.Controller(LISTBOX_ITEMS, DEFAULT_LABELS, "Haupttitel", "Untertitel").run()
abgeändert. Kannst du das Ganze einmal ausprobieren? Bei mir funktioniert die Ausgabe die mittels Schaltfläche Übernehmen ausgelöst wird.

Gruß wuf :wink:
Take it easy Mates!
Nobuddy
User
Beiträge: 1019
Registriert: Montag 30. Januar 2012, 16:38

Hallo wuf, Danke für Deine Unterstützung!

Bei Deiner ersten Änderung in der Methode process in Klasse Controller, ist ja nur die Printausgabe geändert, was ja an der Ausführung nichts ändert.

Die Parameternamen, habe ich in Kleinbuchstaben abgeändert.

Die Parameter, habe ich in einer eigenen Modul abgelegt, da es viele verschiedener Datendefinitionen gibt.
Die kann ich dann von dem betreffenden Steuerungsmodul aus abrufen.
Auszug:

Code: Alles auswählen

def kunden():
    main_title = 'Anlage Neukunden'

    sub_title = 'Auswahl Kundenkreis'

    # Kundendefinition
    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'}

    # Kundenspalten
    default_labels = ['Kundenkreis', 'Namen', 'Zusatz', 'Straße, Nr.',
        'PLZ', 'Ort', 'USt-Ident-Nr.', 'Ansprechpartner', 'Telefon',
        'Handy', 'Fax', 'Mail','Internetseite']
    return main_title, sub_title, kundendefintion, kundenspalten
Das habe ich übernommen:

Code: Alles auswählen

import gui_KundenNeu as app
app.Controller(listbox_items, default_labels, main_title, sub_title).run()
Ich habe es mit Deinen Änderungen versucht, das Ergebnis ist unverändert.
Bei mir hat die Ausgabe die mittels Schaltfläche Übernehmen ausgelöst wird, auch vorher schon funktioniert.

Das Problem ist, daß die Auswahl der Listbox nicht auf dem Entry-Feld erscheint also leer bleibt, während mittels Schaltfläche Übernehmen die Auswahl der Listbox mit ausgegeben wird.
Wenn ich in den Entry-Feldern (default_labels) Eingaben mache, werden diese NICHT mittels Schaltfläche Übernehmen ausgegeben.

Grüße Nobuddy
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

OK Nobuddy

Als Referenzscript für die Moduldatei gui_KundenNeu.py gilt für mich immer noch:
https://gist.github.com/4033430
Nobuddy hat geschrieben:Bei Deiner ersten Änderung in der Methode process in Klasse Controller, ist ja nur die Printausgabe geändert, was ja an der Ausführung nichts ändert.
Stimmt diese Änderung hat keinen Einfluss auf das Funktionieren des Skriptes. Habe ich übrigens auch noch falsch abgeändert. Ich wollte aus der bestehenden Methode process:

Code: Alles auswählen

    def process(self, listbox_item):
        self.view.entry_vars[0].set(listbox_item)
        print(self.view.entry_vars[0])
        print(listbox_item)
folgendes machen:

Code: Alles auswählen

    def process(self, listbox_item):
        self.view.entry_vars[0].set(listbox_item)
        print(listbox_item)
Da die Zeile:

Code: Alles auswählen

print(self.view.entry_vars[0])
die nicht benötigte Ausgabe von:
PY_VAR0
wirft.
wuf hat geschrieben:Meine Frage. Warum schreibst du in der folgenden Zeile die Parameternamen in Grossbuchstaben (wie Konstanten)?:
Hier musst du mich falsch verstanden haben. Ich meinte nicht die Argumente beim Aufruf bzw. Erstellung der Instanz für Controller sondern die Parameter im Konstruktor __init__ der Klasse Controller.

Habe deine Applikationdatei mit welcher das Ganze gestartet wird wie folgt geändert:

Code: Alles auswählen

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

import gui_KundenNeu_01 as app

MAIN_TITLE = 'Anlage Neukunden'
SUB_TITLE = 'Auswahl Kundenkreis'

# Kundendefinition
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'}

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


app.Controller(LISTBOX_ITEMS, DEFAULT_LABELS, MAIN_TITLE, SUB_TITLE).run()
In deiner Moduldatei habe ich die Klasse Model einmal eliminiert da sie für den momentane Stand deiner Anwendung noch nicht viel bringt. Habe noch folgendes gändert:

Code: Alles auswählen

class Controller(object):

    def __init__(self, listbox_items, default_labels, main_title, sub_title):
        #self.model = Model(listbox_items)
        #self.model2 = Model(default_labels)
        self.default_labels = default_labels
        self.view = ListGui(self, listbox_items, default_labels,
            main_title, sub_title, CONFIG)

    def process(self, listbox_item):
        self.view.entry_vars[0].set(listbox_item)
        print(listbox_item)

    def collect_entries(self):
        entry_data = dict()
        for index, entry_var in enumerate(self.view.entry_vars):
            print("{} : {}".format(self.default_labels[index],
                entry_var.get()))
            entry_data[self.default_labels[index]] = entry_var.get()
        print()
        print(entry_data)

    def run(self):
        self.view.run()


#class Model(object):

    #def __init__(self, items):
        #self.items = items
        #self.items2 = items


def main():
    Controller(LISTBOX_ITEMS, DEFAULT_LABELS, MAIN_TITLE, SUB_TITLE).run()
    
#--- MODUL-TEST ---------------------------------------------------------------#
if __name__ == '__main__':
    MAIN_TITLE = 'Anlage Neukunden'

    SUB_TITLE = 'Auswahl Kundenkreis'

    # Kundendefinition
    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'}

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

    main()
Ein Klick auf ein Element der Listbox erzeugt ein Eintrag im ersten Entry-Feld. Und ein aktivieren von Übernehmen gib auch alle Eingabefelder aus. Also bei mir funktioniert es so.
N.B: Die Moduldatei qui_KundenNeu.py kann mit dieser Änderung auch direkt gestartet werden.

Gruß wuf :wink:
Take it easy Mates!
Nobuddy
User
Beiträge: 1019
Registriert: Montag 30. Januar 2012, 16:38

Hallo wuf, habe alles so von dir übernommen, auf Grundlage von https://gist.github.com/4033430

Starte ich das Modul gui_list_work.py (alter Namen gui_KundenNeu.py) direkt, funktioniert alles so, wie es soll.
Rufe ich aber das Modul über ein anderes Modul auf und übergebe von Dort die Daten, funktioniert es wieder nicht.

Ich poste jetzt mal alle beteiligten Module, damit Du es besser nachvollziehen kannst.

Haupfenster (gui_start.py) von dem aus alles gesteuert werden soll.
Darin habe ich 2 Aufrufe, die gui_list_work.py aufrufen.
Zeile 215 - 218
Zeile 282 - 286
Das betreffende Modul gui_list_work.py.
Modul für Referenzdaten gui_list_names.py für (listbox_items, default_labels, main_title, sub_title).
Alle 3 Dateien hier: https://gist.github.com/4038350

Grüße Nobuddy
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hi Nobuddy

Leider nimmt deine Programm unter:
https://gist.github.com/4038350
schon eine Ausmass an, wo ich nicht mehr Zeit zum Durcharbeiten investieren möchte. Alleine die für mich neu hinzugekommene Datei gui_start.py importiert zusätzlich Ware aus Modulen wie:

Code: Alles auswählen

from gui_start_moduls import screen_blank, openfile, openfile_search
from gui_start_moduls import openfile_intern, openfile_save_intern
from filestart import fileopen
welche ich nicht habe.

Hier nochmals die gänderte Variante aus:
https://gist.github.com/4033430

Die Moduldatei (gui_KundenNeu_01.py):
http://www.python-forum.de/pastebin.php?mode=view&s=314
Die Startdatei (start_gui.py):
http://www.python-forum.de/pastebin.php?mode=view&s=315

Kopiere die Dateien:
gui_KundenNeu_01.py
start_gui.py

in ein eigenes Verzeichnis und starte die Datei start_gui.py

Dann muss das folgende funktionieren:
Ein Klick auf ein Element der Listbox transferiert es ins erste Eingabefeld (Kundenkreis). Ein aktivieren der Schaltfläche Übernehmen gib alle Eingabefelder aus. Wenn nicht dann musst du dich anderstwie schlau machen.

Gruß wuf :wink:
Take it easy Mates!
Nobuddy
User
Beiträge: 1019
Registriert: Montag 30. Januar 2012, 16:38

Hallo wuf, ja so funktioniert es.

Daß das Ganze zu komplex und zeitaufwendig für Dich ist verstehe ich, hast ja bestimmt noch ein paar Kleinigkeiten sonst zu erledigen. :wink:

Generell mal die Frage.
Wenn ich von meiner gui_start.py aus die gui_KundenNeu.py aufrufe, bleibt ja das Fenster von gui_start.py weiter offen und ein weiteres Fenster wird geöffnet (gui_KundenNeu.py), daß da das Problem ist?

Grüße Nobuddy
yipyip
User
Beiträge: 418
Registriert: Samstag 12. Juli 2008, 01:18

Also so langsam wird das Ganze doch arg unuebersichtlich. Jetzt habe ich bei mir 3 Dateien, 2 davon beinghalten eine Controller- und eine main-Definition. Beim fehlenden gui_start_moduls bin ich dann ausgestiegen.
Also:
In der jetzigen Phase kannst du noch alles in eine Datei packen. Sich alles zusammensuchen zu muessen ist fuer uns nicht so motivierend (und, so glaube ich, wird auch dir einen besseren Ueberlick verschaffen).
Fuer spaeter:
Ich hatte ja schon mal gesagt: Mach ein Github Repository. Damit meinte ich nicht die Gist Snippets, sondern ein "richtiges" Projekt auf Github. Dann kann man auch mit vielen Dateien arbeiten. (Wenn dein Projekt denn OpenSource sein soll.)

Nix fuer ungut
:wink:
yipyip
Nobuddy
User
Beiträge: 1019
Registriert: Montag 30. Januar 2012, 16:38

Nur keine Angst, möchte Euch da nicht überfordern, verstehe ja daß das zuviel ist.

Ich werde für meine gui_start.py für Euch ein Fenster mit nur einem Button kreiren, das dann die Funktion hat, das betreffende Modul gui_NeuKunden.py aufzurufen und die Daten an dieses Modul von gui_start.py aus zu übergeben.

Dann sollte das recht einfach sein, die Ausführungsweise von mir zu verstehen.

Das mit dem Github Repository, da kenne ich mich nicht aus, dachte das gist.github wäre dies.

Grüße Nobuddy :wink:
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hi Nobuddy
Nobuddy hat geschrieben:Generell mal die Frage.
Wenn ich von meiner gui_start.py aus die gui_KundenNeu.py aufrufe, bleibt ja das Fenster von gui_start.py weiter offen und ein weiteres Fenster wird geöffnet (gui_KundenNeu.py), daß da das Problem ist?
Es ist natürlich nur ein Fenster offen. Dies ist das Hauptfenster, welches mit allen folgenden Widget gefüllt wird. Was sicher nicht gut ist, dass dieses Hauptfenster im Modul in der Klasse ListGui erzeugt wird. Das ist sicher nicht mein Programmierstiel und ich möchte dir meinen nicht aufzwingen. Ich wollte dir nur zeigen wie du mit deinem Dateien Setup deine gui_KundenNeu.py aus einer anderen Datei (gui_start.py) mit importieren zum laufen bringst.
Nobuddy hat geschrieben:Ich werde für meine gui_start.py für Euch ein Fenster mit nur einem Button kreiren, das dann die Funktion hat, das betreffende Modul gui_NeuKunden.py aufzurufen und die Daten an dieses Modul von gui_start.py aus zu übergeben.
Dieser Ansatz ist schon besser, Wie schon yipyip vorgeschlagen hat würde ich die ganze Sache in eine Datei packen. Wenn das Werk einmal das macht was du dir vorstellst kannst du diese eine Datei immer noch in hunderte andere aufteilen.

Gruß wuf :wink:
Take it easy Mates!
Nobuddy
User
Beiträge: 1019
Registriert: Montag 30. Januar 2012, 16:38

Hallo wuf, hallo yipyip,

ich habe da noch jede Menge zu lernen, glaube da widerspricht Ihr mir nicht ... :wink:

Warum das Hauptfenster immer offen bleiben soll?
Meine Vorstellung ist in diesem zu arbeiten und wenn erforderlich weitere Fenster in die Arbeit mit einzubeziehen.
Nobuddy hat geschrieben:Ich werde für meine gui_start.py für Euch ein Fenster mit nur einem Button kreiren, das dann die Funktion hat, das betreffende Modul gui_NeuKunden.py aufzurufen und die Daten an dieses Modul von gui_start.py aus zu übergeben.
Dieser Ansatz ist schon besser, Wie schon yipyip vorgeschlagen hat würde ich die ganze Sache in eine Datei packen. Wenn das Werk einmal das macht was du dir vorstellst kannst du diese eine Datei immer noch in hunderte andere aufteilen.

Ich habe hier, wie versprochen das ONE_BUTTON_WINDOW kreirt, die zugehörigen Dateien sind ebenfalls dabei. :wink:
Sorry, wenn es momentan noch kein Github Repository ist.
https://gist.github.com/4040490

Ich denke, damit könnt Ihr das testen, was ich versucht habe mitzuteilen. :wink:

Grüße Nobuddy
Nobuddy
User
Beiträge: 1019
Registriert: Montag 30. Januar 2012, 16:38

Hallo zusammen

Nach vielen Versuchen eine Lösung zu finden, anhand der geposteten Dateien (Link), habe ich den Verdacht, daß das Hauptfenster das neu geöffnete Fenster blockiert, so daß das Neue Fenster sich selbst nicht aktualisieren kann. :?

Da hier im Thread das eigentliche Ziel erreicht wurde, werde ich einen neuen Thread eröffnen, um das aktuell vorliegende Problem evtl. doch noch lösen zu können.

Danke für Eure Unterstützung :wink:

Grüße Nobuddy
Antworten