Dropdown menü deaktivieren

Fragen zu Tkinter.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Marvin75854: Ups, ich hatte einen Beitrag von Dir übersehen.

Der Unterschied zwischen einer Funktion und einer Methode ist nicht der wie die Argumente übergeben werden, das ist letztlich bei beiden gleich, sondern das eine Methode zu einem Objekt gehört in dem diese Methode, Daten die den Zustand des Objekts beschreiben, und noch andere Methoden, *sinnvoll* zusammengefasst sind. Und Du hast da IMHO zwei Funktionen und Argumente für die Funktionen zu einer Klasse zusammengefasst die semantisch gar keine Klasse ist. Was man dadurch zeigen kann, das es sich ganz einfach als zwei einzelne Funktionen schreiben lässt, und dabei IMHO auch gleich noch lesbarer wird, weil bei `berechnen()` und `ausgabe()` jetzt sichtbarer ist, was die jeweils an Werten brauchen und an den Aufrufer zurückgeben.

Bei der Variante mit `Vector` übergibt man nun statt `hx`, `dy`, und `hz` einzeln, ein `Vector`-Objekt für `point`. Und für `ddy` die -365 die vorher hart kodiert an zwei Stellen im Quelltext stand. Bei `h_point` so ähnlich nur das dort die `y`-Komponente die -365 ist.

Ich konnte mich ja nur an den Namen orientieren. Ist das echt so weit an der Bedeutung vorbei die das tatsächlich hat? Bilden die drei Argumente keinen Punkt? Und erstellt `HDPA_Berechnen()` nicht etwas das sich durch vier Punkte im Raum beschreiben lässt, wobei die alle in einer Ebene parallel zur Z-Achse liegen?

Benutzung könnte so aussehen (ungetestet):

Code: Alles auswählen

            ddy = -365
            hx, dy, hz = (
                float(entry.get()) for entry in [self.hx, self.dy, self.hz]
            )

            filename = tkFileDialog.asksaveasfilename(
                initialdir=os.getcwd(),
                title='Speichern der Include-Datei',
                filetypes=(('all files', '*.*'), ('inc files', '*.inc'))
            )
            with open(filename, 'a') as out_file:
                out_file.write(
                    '$Erstellt durch COG-Tool am: {0}\n'.format(
                        time.strftime('%d.%m.%Y %H:%M:%S')
                    )
                )
                
                hdpa_points = hdpa_berechnen(Vector(hx, dy, hz), ddy)
                hdpa_ausgabe(
                    Vector(hx, ddy, hz),
                    self.sitzreihe,
                    self.i,
                    hdpa_points,
                    out_file
                )
                
                out_file.write('ENDDATA\n') 
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Marvin75854

__blackjack__ hat geschrieben: Montag 30. Juli 2018, 21:05 Der Unterschied zwischen einer Funktion und einer Methode ist nicht der wie die Argumente übergeben werden, das ist letztlich bei beiden gleich, sondern das eine Methode zu einem Objekt gehört in dem diese Methode, Daten die den Zustand des Objekts beschreiben, und noch andere Methoden, *sinnvoll* zusammengefasst sind. Und Du hast da IMHO zwei Funktionen und Argumente für die Funktionen zu einer Klasse zusammengefasst die semantisch gar keine Klasse ist. Was man dadurch zeigen kann, das es sich ganz einfach als zwei einzelne Funktionen schreiben lässt, und dabei IMHO auch gleich noch lesbarer wird, weil bei `berechnen()` und `ausgabe()` jetzt sichtbarer ist, was die jeweils an Werten brauchen und an den Aufrufer zurückgeben.
Ja das meinte ich ja ganz am Anfang schon mal, dass ich den Sinn der Klassen nicht so ganz verstehe, weil es mit normalen Funktionen genauso funktioniert und wahrscheinlich übersichtlicher ist. Vielleicht ist mein Code auch nicht perfekt für die Anwendung von Klassen am Anfang. Werde das jetzt wirklich erstmal mit Funktionen alles machen und vielleicht verstehe ich das später dann doch noch besser.

__blackjack__ hat geschrieben: Montag 30. Juli 2018, 21:05 Bei der Variante mit `Vector` übergibt man nun statt `hx`, `dy`, und `hz` einzeln, ein `Vector`-Objekt für `point`. Und für `ddy` die -365 die vorher hart kodiert an zwei Stellen im Quelltext stand. Bei `h_point` so ähnlich nur das dort die `y`-Komponente die -365 ist.

Ich konnte mich ja nur an den Namen orientieren. Ist das echt so weit an der Bedeutung vorbei die das tatsächlich hat? Bilden die drei Argumente keinen Punkt? Und erstellt `HDPA_Berechnen()` nicht etwas das sich durch vier Punkte im Raum beschreiben lässt, wobei die alle in einer Ebene parallel zur Z-Achse liegen?
Nein ich habe es jetzt verstanden. Genau so ist es. Man gibt einen Punkt ein aus dem dann eine Fläche errechnet wird. Die y-Koordinate von dem Punkt den man eingibt ist -365. Da die immer -365 ist, wäre es einfach unnötig die eingeben zu müssen. Und ddy ist dann einfach die Verschiebung der Fläche auf der y-Achse. ddy soll auch später noch für ganze andere Funktionen verwendet werden. Wie ich das mache, weiß ich noch nicht.

__blackjack__ hat geschrieben: Montag 30. Juli 2018, 21:05 Benutzung könnte so aussehen (ungetestet):

Code: Alles auswählen

            ddy = -365
            hx, dy, hz = (
                float(entry.get()) for entry in [self.hx, self.dy, self.hz]
            )

            filename = tkFileDialog.asksaveasfilename(
                initialdir=os.getcwd(),
                title='Speichern der Include-Datei',
                filetypes=(('all files', '*.*'), ('inc files', '*.inc'))
            )
            with open(filename, 'a') as out_file:
                out_file.write(
                    '$Erstellt durch COG-Tool am: {0}\n'.format(
                        time.strftime('%d.%m.%Y %H:%M:%S')
                    )
                )
                
                hdpa_points = hdpa_berechnen(Vector(hx, dy, hz), ddy)
                hdpa_ausgabe(
                    Vector(hx, ddy, hz),
                    self.sitzreihe,
                    self.i,
                    hdpa_points,
                    out_file
                )
                
                out_file.write('ENDDATA\n') 
Das hilft mir extrem. Konnte ich auch fast genau so übernehmen. Ich werde jetzt wirklich erstmal versuchen alles in Funktionen zu machen. Die GUI Elemente würde ich aber weiterhin gerne auf Klassen aufteilen, weiß aber nicht so richtig wie ich dann am Ende über einen Ausgabe Button alles Funktionen bündeln kann.
Im Moment ist es ja so, dass ich mit einer Klasse hdpa die GUI Elemente auf dem ersten Reiter erzeuge. Dann habe ich die Klasse hdpa in der main Methode nochmal aufgerufen um auch auf dem zweiten Reiter der GUI die Elemente zu erzeugen. In der Klasse habe ich auch den Export Button definiert der die Funktionen in der Programmlogik aufruft. Der Funktioniert auch, allerdings habe ich das Problem, dass ich den Export Button jetzt zwei mal habe. Und es kommen später auch noch weitere Funktionen dazu die auch was exportieren sollen. Ich will also einen Export Button, der alle Berechnungen durchführt und alle Ergebnisse der gesamten GUI ausgibt. Bzw. wichtig ist nur die Ausgabe. Die Berechnungen können schon vorher durchgeführt worden sein.
Also meine Idee war eine eigene Klasse für den Button zu schreiben der dann die GUI Klassen aufruft. Dann hätte ich die GUI Elemente aber ja alle doppelt übereinander liegen. Hier nochmal der Code. Das meiste stammt ja eh von dir. :D :

Code: Alles auswählen

#!/usr/bin/python
from __future__ import print_function
import subprocess
from Tkinter import *
import Tkinter, Tkconstants, tkFileDialog
import os
from tkMessageBox import *
import math
import sys
import time
import Tix as tx

import Programmlogik_2



class HDPA_Sitzreihe_1(Frame):
    def __init__(self, parent, name_Bild):
        Frame.__init__(self, parent)
        
        Label(self, text="X").grid(row=13)
	Label(self, text="Z").grid(row=13, column=1)
        self.name_Bild = name_Bild

	self.hx = Entry(self)
	self.hz = Entry(self)
	self.hx.grid(row=14, column=0)
	self.hz.grid(row=14, column=1)

	Label(self, text="Y-Abstand: COG/H-Punkt zu Airbag").grid(row=15,pady=(20,0))
	self.dy = Entry(self)
	self.dy.grid(row=16, column=0) 
        
        
        self.HDPA = Label(self, text="H-Punkt WS50%")
	self.HDPA.grid(row=12, column=0, padx=20)
        
	self.box = IntVar()
	Checkbutton(self, text="HDPA Feld", variable=self.box).grid(row=11)        
        
        self.logo = PhotoImage(file=self.name_Bild)
	w1 = Label(self, image=self.logo).grid(row=0, column=0, pady=20,padx=20, rowspan=10, columnspan=5)
        
        self.sitzreihe = 1
        self.i = 1
        
        
        
        
        
        self.Export_button = Button(self, text="Export", command=self.Export)
        self.Export_button.grid(row=18, column=0)
        
        
        
    def Export(self):
    
        if self.box.get() == 1:
        
            ddy = -365
        
            hx, dy, hz = (
                float(entry.get()) for entry in [self.hx, self.dy, self.hz]
            )
        
            filename = tkFileDialog.asksaveasfilename(
                initialdir=os.getcwd(),
                title='Speichern der Include-Datei',
                filetypes=(('all files', '*.*'), ('inc files', '*.inc'))
            )
            with open(filename, 'a') as out_file:
                out_file.write(
                    '$Erstellt durch COG-Tool am: {0}\n'.format(
                        time.strftime('%d.%m.%Y %H:%M:%S')
                    )
                )
                
                hdpa_points = Programmlogik_2.hdpa_berechnen(Programmlogik_2.Vector(hx, dy, hz), ddy)
                Programmlogik_2.hdpa_ausgabe(
                    Programmlogik_2.Vector(hx, ddy, hz),
                    self.sitzreihe,
                    self.i,
                    hdpa_points,
                    out_file
                    
                )
                
                out_file.write('ENDDATA\n') 
            
        else:
            print("Kein HDPA-Feld")
            print(self.hx)
                
        
        
        
#class HDPA_Sitzreihe_3(Frame):
#    def __init__(self, parent):
#        Frame.__init__(self, parent)        
#        
#        self.logo = PhotoImage(file="Sitzreferenzfeld_3.Reihe.gif")
#        w = Label(self, image=self.logo).grid(row=0, column=0, pady=20,padx=20, rowspan=10, columnspan=5)
        
        
        

def main():
    GUI = tx.Tk()
    GUI.title ("COG Tool") 
    GUI.geometry("1800x800")
    
    swr=tx.ScrolledWindow(GUI)
    swr.pack(fill=tx.BOTH, expand=1)
    
    nb=tx.NoteBook(swr.window)
    nb.pack(fill=tx.BOTH, expand=1)

    nb.add("sitzreihe"+str(1),label="1. Sitzreihe")
    nb.add("sitzreihe"+str(2),label="2. Sitzreihe")
    nb.add("sitzreihe"+str(3),label="3. Sitzreihe")
     
    
    hdpa_sitzreihe_1 = HDPA_Sitzreihe_1(nb.sitzreihe1,"Sitzreferenzfeld.gif")
    hdpa_sitzreihe_1.grid(row=0, column=0)
    
    
    hdpa_sitzreihe_2 = HDPA_Sitzreihe_1(nb.sitzreihe2,"Sitzreferenzfeld_2.Reihe.gif")
    hdpa_sitzreihe_2.grid(row=0, column=0)
 
#    hdpa_sitzreihe_3 = HDPA_Sitzreihe_3(nb.sitzreihe3)
#    hdpa_sitzreihe_3.grid(row=0, column=0) 
 
    
    GUI.mainloop()


if __name__ == "__main__": 
    main()

Und die Programmlogik:

Code: Alles auswählen

#!/usr/bin/python
from __future__ import print_function
import subprocess
from Tkinter import *
import Tkinter, Tkconstants, tkFileDialog
import os
from tkMessageBox import *
import math
import sys
import time
import Tix as tx


class Vector(object):
    
    def __init__(self, x=0, y=0, z=0):
        self.x = x
        self.y = y
        self.z = z
    
    def __str__(self):
        return '({0.x}, {0.y}, {0.z})'.format(self)
    
    def __add__(self, other):
        return Vector(self.x + other.x, self.y + other.y, self.z + other.z)

        
def hdpa_berechnen(point, ddy):
    return [
        point + Vector(126 - 82, ddy, 594 - 58),
        point + Vector(147 + 82, ddy, 594 - 52),
        point + Vector(126 - 82, ddy, 693 + 82),
        point + Vector(147 + 82, ddy, 693 + 82),
    ]


def hdpa_ausgabe(h_point, sitzreihe, i_start, node_points, out_file):
    out_file.write(
        '$H-Punkt: {0}\n'
        '$HDPA-Feld fuer die {1}. Sitzreihe:\n'.format(h_point, sitzreihe)
    )
    i = None
    for i, point in enumerate(node_points, i_start):
        out_file.write(
            'NODE  / 1000000{0}{1.x:16.6f}{1.y:16.6f}{1.z:16.6f}\n'.format(
                i, point
            )
        )
    indices = [0, 1, 3, 2]
    if len(indices) != i:
        raise ValueError(
            'wrong number of node points ({} != {})'.format(len(indices), i)
        )
    out_file.write(
        'SHELL / 1000000{0}       11000000{1}        \n'
        'PART  / 1000000{0}SHELL          1                        \n'
        'NAMEDefault HDPA_Feld_{0}.Sitzreihe\n'
        '                    \n'
        '                              \n'
        '        1.    3               \n\n'
        'END_PART\n'.format(
            sitzreihe,
            '1000000'.join(str(i_start + j) for j in indices),
        )
    )
Meine Idee wäre eine Klasse für den Button zu schreiben, der dann eine Methode/Funktion aufruft die über die hdpa Klassen und die Klassen die noch später dazu kommen die jeweiligen Berechnungs/Ausgabe Funktionen aufruft. Also dass nicht erneut ein Objekt der Klassen erzeugt wird, sondern nur auf das bereits erzeugte Objekt zugegriffen wird. Also, dass die Funktionen der Klasse durch eine externe Klasse aufgerufen werden. Keine Ahnung ob ich das richtig erklären kann. Vielleicht könnte ich das über Vererbungen machen? Ich will das nicht wieder alles zu extrem miteinander verstricken.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Marvin75854 hat geschrieben: Dienstag 31. Juli 2018, 08:07 Meine Idee wäre eine Klasse für den Button zu schreiben,
Ein Button ist einfach nur ein Button, der braucht keine eigene Klasse. Was Du machen könntest, wäre eine Klasse für das Hauptfenster, denn das hat ja mit den ganzen Sitzreihen und Knöpfen einiges an Zustand.

Module werden komplett kein geschrieben, Programmlogik_2 hat außerdem noch eine Nummer, was kein guter Modulname ist. Komplett groß geschrieben Namen sind für Konstanten reserviert, GUI sollte also gui heißen, denn Variablen und Attribute werden komplett_klein geschrieben. Sternchenimporte vermeiden, die ganzen Tkinter-Namen kannst Du ja auch über tx.xxx referenzieren.
Marvin75854 hat geschrieben: Dienstag 31. Juli 2018, 08:07Also dass nicht erneut ein Objekt der Klassen erzeugt wird, sondern nur auf das bereits erzeugte Objekt zugegriffen wird.
Von welchen Klassen sprichst Du hier? Bisher hast Du nur GUI-Klassen, die einmal am Anfang erzeugt werden. Für die Berechnung sehe ich noch nicht die Notwendigkeit von Klassen. Vererbung ist dann noch eine Stufe später dran. Erst wenn Du merkst, dass es sinnvoll ist aus Funktionen eine Klasse zu machen und wenn Du später mehrere Klassen hast, die gemeinsame Methoden und Zustände haben, dann kannst Du darüber nachdenken, eine Überklasse einzurichten, aber wirklich nur dann, wenn es eine IST-EINE-Beziehung zwischen den Klassen gibt.
Marvin75854

Sirius3 hat geschrieben: Dienstag 31. Juli 2018, 08:46 Von welchen Klassen sprichst Du hier? Bisher hast Du nur GUI-Klassen, die einmal am Anfang erzeugt werden. Für die Berechnung sehe ich noch nicht die Notwendigkeit von Klassen. Vererbung ist dann noch eine Stufe später dran. Erst wenn Du merkst, dass es sinnvoll ist aus Funktionen eine Klasse zu machen und wenn Du später mehrere Klassen hast, die gemeinsame Methoden und Zustände haben, dann kannst Du darüber nachdenken, eine Überklasse einzurichten, aber wirklich nur dann, wenn es eine IST-EINE-Beziehung zwischen den Klassen gibt.
Ja bisher schon. Ich werde aber am Ende noch mehrere Klassen schreiben, da auf meiner GUI ja sehr viel mehr Eingabefelder sein sollen als ich bisher habe. Ich will am Ende alles über einen Button laufen lassen. Also ein Button soll sich Werte aus Eingabefeldern von der GUI holen, mehrere Funktionen aufrufen und alles in eine Text Datei schreiben. Die GUI Elemente in den Klassen werden ja ganz am Anfang in der main Methode erzeugt. Jetzt habe ich bisher immer nur aus der Klasse selbst auf Funktionen zugegriffen. Aber wie kann ich es hinkriegen, dass der Button aus bspw. 3 verschiedenen Klassen mit GUI Elementen die Werte holt und damit 5 verschiedene Funktionen ausführt. Ich wüsste wie ich es mache, wenn ich die gesamte GUI in eine Klasse schreibe, aber dann kann ich es ja auch gleich wieder global definieren...
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Marvin75854: Die drei verschiedenen Klassen mit GUI-Elementen müssen da halt eine Methode für vorsehen. So wie `Entry`-Objekte eine `get()`-Methode haben.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hi Marvin75854

Hier noch einige Tipps:
a) Für das Einrücken um 4 Stellen nur Tabs oder Spaces aber nicht beides verwenden. Ich verwende z.B. nur Spaces.
b) Ich würde nur mit tkinter Python3.xx verwenden.
c) Auf die Verwendung von Tix würde ich verzichten und an Stelle ttk Widgets verwenden.

Habe anhand der vorhergehenden Beiträgen versucht das folgende Skript zu erstellen. Konnte aber mit der Klassenmethode hdpa_ausgabe abbrechen müssen da ich eine nähere Beschreibung der ganzen Rechnerei und deiner Anwendung benötige. Was ist in deinem Skript der Unterschied zwischen self.sitzreihe und self.i (i_start) :

Code: Alles auswählen

import os
import time
from functools import partial

import tkinter as tk
import tkinter.ttk as ttk
from tkinter import filedialog

APP_TITLE = "COG Tool"
APP_XPOS = 50
APP_YPOS = 50
APP_WIDTH = 800 #1800
APP_HEIGHT = 400 #800

class ModelVector(object):

    def __init__(self, x=0, y=0, z=0):
        self.x = x
        self.y = y
        self.z = z

    def __str__(self):
        return '({0.x}, {0.y}, {0.z})'.format(self)
    
    def __add__(self, other):
        return ModelVector(
            self.x + other.x, self.y + other.y, self.z + other.z)

class ModelMain(object):
    DDY = -365
    def __init__(self, app):
        self.app = app
        self.ddy = self.DDY
        
    def export(self, filename, row_index, point_values):
        x, y, z = point_values
        
        with open(filename, 'a') as out_file:
            out_file.write('$Erstellt durch COG-Tool am: {0}\n'.format(
                    time.strftime('%d.%m.%Y %H:%M:%S')))

            
            hdpa_points = self.hdpa_berechnen(ModelVector(x, y, z), self.ddy)
            self.hdpa_ausgabe(
                ModelVector(x, self.ddy, z),
                row_index, #self.sitzreihe
                row_index, #self.i,
                hdpa_points,
                out_file)
            
            out_file.write('ENDDATA\n') 

    def hdpa_berechnen(self, point, ddy):
        return [
            point + ModelVector(126 - 82, ddy, 594 - 58),
            point + ModelVector(147 + 82, ddy, 594 - 52),
            point + ModelVector(126 - 82, ddy, 693 + 82),
            point + ModelVector(147 + 82, ddy, 693 + 82)]


    def hdpa_ausgabe(self, h_point, sitzreihe, i_start, node_points, out_file):
        print("Hier bricht meine Unterstützung ab!")
        return
        
        out_file.write(
            '$H-Punkt: {0}\n'
            '$HDPA-Feld fuer die {1}. Sitzreihe:\n'.format(h_point, sitzreihe)
        )
        i = None
        for i, point in enumerate(node_points, i_start):
            out_file.write(
                'NODE  / 1000000{0}{1.x:16.6f}{1.y:16.6f}{1.z:16.6f}\n'.format(
                    i, point
                )
            )
    
        indices = [0, 1, 3, 2]
        print("Check:", len(indices), i)
        if len(indices) != i:
            raise ValueError(
                'wrong number of node points ({} != {})'.format(len(indices), i)
            )
        out_file.write(
            'SHELL / 1000000{0}       11000000{1}        \n'
            'PART  / 1000000{0}SHELL          1                        \n'
            'NAMEDefault HDPA_Feld_{0}.Sitzreihe\n'
            '                    \n'
            '                              \n'
            '        1.    3               \n\n'
            'END_PART\n'.format(
                sitzreihe,
                '1000000'.join(str(i_start + j) for j in indices),
            )
        )
        
class GuiSeatRow(tk.Frame):
    ROW_NR_FONT = "Helvetica 22 bold"
    
    def __init__(self, gui, row):
        self.gui = gui
        self.row = row
        
        self.build()
        
    def build(self):
        tk.Frame.__init__(self, self.gui.main_frame)
        
        self.row_var = tk.IntVar(self.gui.app.main_win, self.row+1)
        tk.Label(self, textvariable= self.row_var, bg='blue',
            fg='white', font=self.ROW_NR_FONT, width=2
            ).pack(pady=(5, 10))
        
        self.box = tk.IntVar(self.gui.app.main_win, False)
        tk.Checkbutton(self, text="HDPA Feld", variable=self.box
            ).pack()        
 
        self.hdpa = tk.Label(self, text="H-Punkt WS50%")
        self.hdpa.pack(pady=5)
      
        entry_frame = tk.Frame(self)
        entry_frame.pack(pady=5)
        
        label_frame = tk.LabelFrame(entry_frame, text="X:", relief='flat')
        label_frame.pack(side='left')
        self.hx_var = tk.StringVar(self.gui.app.main_win, 0)
        tk.Entry(label_frame, textvariable=self.hx_var).pack()
        
        label_frame = tk.LabelFrame(entry_frame, text="Z:", relief='flat')
        label_frame.pack(side='left')
        self.hz_var = tk.StringVar(self.gui.app.main_win, 0)
        tk.Entry(label_frame, textvariable=self.hz_var).pack()
 
        label_text = "Y-Abstand:\nCOG/H-Punkt zu Airbag"
        label_frame = tk.LabelFrame(self, text=label_text,
            relief='flat')
        label_frame.pack(anchor='w', pady=5)
        self.dy_var = tk.StringVar(self.gui.app.main_win, 0)
        tk.Entry(label_frame, textvariable=self.dy_var).pack() 

        tk.Button(self, text="Export", command=partial(
            self.gui.export, self.row)).pack(pady=5)

        
class GuiMain(object):
    NOTEBOOK_TAB_FONT = ("Helvetica", 12, "bold")
    ANZAHL_SITZREIHEN = 5
    
    def __init__(self, app):
        self.app = app
        
        self.seat_rows = list()
        
        self.build()
        
        for row in range(self.ANZAHL_SITZREIHEN):
            seat_row = GuiSeatRow(self, row)
            seat_row.pack()
            self.note_book.add(seat_row, text="Sitzreihe-{}".format(row+1),
                sticky='nw', padding=10)
            self.seat_rows.append(seat_row)
        
    def build(self):
        self.main_frame = tk.Frame(self.app.main_win)
        self.main_frame.pack(fill='both', expand=True, padx=5, pady=5)

        self.note_book = ttk.Notebook(self.main_frame)
        self.note_book.pack(fill='both', expand=True)

    def file_dialog(self):
        filename = filedialog.asksaveasfilename(
            initialdir=os.getcwd(),
            title='Speichern der Include-Datei',
            filetypes=(('all files', '*.*'), ('inc files', '*.inc')))
        return filename
            
        
    def export(self, row_index):
        if self.seat_rows[row_index].box.get():
            hx_var = self.seat_rows[row_index].hx_var
            dy_var = self.seat_rows[row_index].dy_var
            hz_var = self.seat_rows[row_index].hz_var
                       
            self.app.export(row_index, (float(entry_var.get()) 
                for entry_var in [hx_var, dy_var, hz_var]))
        else:
            print("Kein HDPA-Feld")
            print(self.seat_rows[row_index].hx_var.get())
     
class App(object):

    def __init__(self, main_win):
        self.main_win = main_win
        self.main_win.protocol("WM_DELETE_WINDOW", self.close)
        
        self.model = ModelMain(self)
        self.gui = GuiMain(self)
            
    def export(self, row_index, point_values):
        filename = self.gui.file_dialog()
        if filename != ():
            self.model.export(filename, row_index, point_values)
        else:
            print("Filedialog wurde abgebrochen")
                
    def close(self):
        print("Application-Shutdown")
        self.main_win.withdraw()
        self.main_win.destroy()
        
               
def main():
    main_win = tk.Tk()
    main_win.title(APP_TITLE)
    #main_win.geometry("+{}+{}".format(APP_XPOS, APP_YPOS))
    main_win.geometry("{}x{}".format(APP_WIDTH, APP_HEIGHT))
    main_win.option_add("*highlightThickness", 0)
    ttk_style = ttk.Style()
    ttk_style.configure('TNotebook.Tab', font="Helvetica 10 bold",
        foreground='blue', background='gray75')
    
    app = App(main_win)
    
    main_win.mainloop()
 
 
if __name__ == '__main__':
    main()
Gruss wuf ;-)
Take it easy Mates!
Marvin75854

Hi wuf,


a) Für das Einrücken um 4 Stellen nur Tabs oder Spaces aber nicht beides verwenden. Ich verwende z.B. nur Spaces.

Mache ich eigentlich auch immer so. Habe aber viel zusammenkopiert. Deswegen ist es wahrscheinlich teilweise unterschiedlich.
wuf hat geschrieben: Donnerstag 2. August 2018, 10:06 b) Ich würde nur mit tkinter Python3.xx verwenden.
Ich arbeite nicht an meinem privaten Rechner und hier ist nur python 2.6.6 installiert. Ich weiß nicht, ob ich hier eine neuere Version installieren könnte. Ich müsste dafür dann mal mit der IT-Abteilung sprechen, denke aber das ist keine Option. Zumal ich sowieso nur noch 2 Monate Zeit habe.

wuf hat geschrieben: Donnerstag 2. August 2018, 10:06 c) Auf die Verwendung von Tix würde ich verzichten und an Stelle ttk Widgets verwenden.
Das ist bei mir glaube ich nicht dabei: ImportError: No module named ttk. Habe auch verschiedene Schreibweisen ausprobiert. Deshalb funktioniert auch leider dein Code nicht. Werde mir den gleich mal genauer angucken.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@wuf: Hier fällt gleich wieder auf das `hdpa_berechnen()` und `hdpa_ausgabe()` gar keine Methoden sind, sondern einfach nur Funktionen die in die Klasse gesteckt wurden. Ich würde da auch nicht überall den Präfix `Model` davor setzen. Zudem sollte das `app` nicht bekommen. Wird ja sowieso nicht verwendet.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Ok Marvin75854

Hier die Variante für Python2.xx:

Code: Alles auswählen

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

import os
import time
from functools import partial

import Tkinter as tk
import ttk
import tkFileDialog

APP_TITLE = "COG Tool"
APP_XPOS = 50
APP_YPOS = 50
APP_WIDTH = 800 #1800
APP_HEIGHT = 400 #800

class ModelVector(object):

    def __init__(self, x=0, y=0, z=0):
        self.x = x
        self.y = y
        self.z = z

    def __str__(self):
        return '({0.x}, {0.y}, {0.z})'.format(self)
    
    def __add__(self, other):
        return ModelVector(
            self.x + other.x, self.y + other.y, self.z + other.z)

class ModelMain(object):
    DDY = -365
    def __init__(self):
        self.ddy = self.DDY
        
    def export(self, filename, row_index, point_values):
        x, y, z = point_values
        
        with open(filename, 'a') as out_file:
            out_file.write('$Erstellt durch COG-Tool am: {0}\n'.format(
                    time.strftime('%d.%m.%Y %H:%M:%S')))

            
            hdpa_points = self.hdpa_berechnen(ModelVector(x, y, z), self.ddy)
            self.hdpa_ausgabe(
                ModelVector(x, self.ddy, z),
                row_index, #self.sitzreihe
                row_index, #self.i,
                hdpa_points,
                out_file)
            
            out_file.write('ENDDATA\n') 

    def hdpa_berechnen(self, point, ddy):
        return [
            point + ModelVector(126 - 82, ddy, 594 - 58),
            point + ModelVector(147 + 82, ddy, 594 - 52),
            point + ModelVector(126 - 82, ddy, 693 + 82),
            point + ModelVector(147 + 82, ddy, 693 + 82)]


    def hdpa_ausgabe(self, h_point, sitzreihe, i_start, node_points, out_file):
        print("Hier bricht meine Unterstützung ab!")
        return
        
        out_file.write(
            '$H-Punkt: {0}\n'
            '$HDPA-Feld fuer die {1}. Sitzreihe:\n'.format(h_point, sitzreihe)
        )
        i = None
        for i, point in enumerate(node_points, i_start):
            out_file.write(
                'NODE  / 1000000{0}{1.x:16.6f}{1.y:16.6f}{1.z:16.6f}\n'.format(
                    i, point
                )
            )
    
        indices = [0, 1, 3, 2]
        print("Check:", len(indices), i)
        if len(indices) != i:
            raise ValueError(
                'wrong number of node points ({} != {})'.format(len(indices), i)
            )
        out_file.write(
            'SHELL / 1000000{0}       11000000{1}        \n'
            'PART  / 1000000{0}SHELL          1                        \n'
            'NAMEDefault HDPA_Feld_{0}.Sitzreihe\n'
            '                    \n'
            '                              \n'
            '        1.    3               \n\n'
            'END_PART\n'.format(
                sitzreihe,
                '1000000'.join(str(i_start + j) for j in indices),
            )
        )
        
class GuiSeatRow(tk.Frame):
    ROW_NR_FONT = "Helvetica 22 bold"
    
    def __init__(self, gui, row):
        self.gui = gui
        self.row = row
        
        self.build()
        
    def build(self):
        tk.Frame.__init__(self, self.gui.main_frame)
        
        self.row_var = tk.IntVar(self.gui.app.main_win, self.row+1)
        tk.Label(self, textvariable= self.row_var, bg='blue',
            fg='white', font=self.ROW_NR_FONT, width=2
            ).pack(pady=(5, 10))
        
        self.box = tk.IntVar(self.gui.app.main_win, False)
        tk.Checkbutton(self, text="HDPA Feld", variable=self.box
            ).pack()        
 
        self.hdpa = tk.Label(self, text="H-Punkt WS50%")
        self.hdpa.pack(pady=5)
      
        entry_frame = tk.Frame(self)
        entry_frame.pack(pady=5)
        
        label_frame = tk.LabelFrame(entry_frame, text="X:", relief='flat')
        label_frame.pack(side='left')
        self.hx_var = tk.StringVar(self.gui.app.main_win, 0)
        tk.Entry(label_frame, textvariable=self.hx_var).pack()
        
        label_frame = tk.LabelFrame(entry_frame, text="Z:", relief='flat')
        label_frame.pack(side='left')
        self.hz_var = tk.StringVar(self.gui.app.main_win, 0)
        tk.Entry(label_frame, textvariable=self.hz_var).pack()
 
        label_text = "Y-Abstand:\nCOG/H-Punkt zu Airbag"
        label_frame = tk.LabelFrame(self, text=label_text,
            relief='flat')
        label_frame.pack(anchor='w', pady=5)
        self.dy_var = tk.StringVar(self.gui.app.main_win, 0)
        tk.Entry(label_frame, textvariable=self.dy_var).pack() 

        tk.Button(self, text="Export", command=partial(
            self.gui.export, self.row)).pack(pady=5)

        
class GuiMain(object):
    NOTEBOOK_TAB_FONT = ("Helvetica", 12, "bold")
    ANZAHL_SITZREIHEN = 5
    
    def __init__(self, app):
        self.app = app
        
        self.seat_rows = list()
        
        self.build()
        
        for row in range(self.ANZAHL_SITZREIHEN):
            seat_row = GuiSeatRow(self, row)
            seat_row.pack()
            self.note_book.add(seat_row, text="Sitzreihe-{}".format(row+1),
                sticky='nw', padding=10)
            self.seat_rows.append(seat_row)
        
    def build(self):
        self.main_frame = tk.Frame(self.app.main_win)
        self.main_frame.pack(fill='both', expand=True, padx=5, pady=5)

        self.note_book = ttk.Notebook(self.main_frame)
        self.note_book.pack(fill='both', expand=True)

    def file_dialog(self):
        filename = tkFileDialog.asksaveasfilename(
            initialdir=os.getcwd(),
            title='Speichern der Include-Datei',
            filetypes=(('all files', '*.*'), ('inc files', '*.inc')))
        return filename
            
        
    def export(self, row_index):
        if self.seat_rows[row_index].box.get():
            hx_var = self.seat_rows[row_index].hx_var
            dy_var = self.seat_rows[row_index].dy_var
            hz_var = self.seat_rows[row_index].hz_var
                       
            self.app.export(row_index, (float(entry_var.get()) 
                for entry_var in [hx_var, dy_var, hz_var]))
        else:
            print("Kein HDPA-Feld")
            print(self.seat_rows[row_index].hx_var.get())
     
class App(object):

    def __init__(self, main_win):
        self.main_win = main_win
        self.main_win.protocol("WM_DELETE_WINDOW", self.close)
        
        self.model = ModelMain()
        self.gui = GuiMain(self)
            
    def export(self, row_index, point_values):
        filename = self.gui.file_dialog()
        if filename != ():
            self.model.export(filename, row_index, point_values)
        else:
            print("Filedialog wurde abgebrochen")
                
    def close(self):
        print("Application-Shutdown")
        self.main_win.withdraw()
        self.main_win.destroy()
        
               
def main():
    main_win = tk.Tk()
    main_win.title(APP_TITLE)
    #main_win.geometry("+{}+{}".format(APP_XPOS, APP_YPOS))
    main_win.geometry("{}x{}".format(APP_WIDTH, APP_HEIGHT))
    main_win.option_add("*highlightThickness", 0)
    ttk_style = ttk.Style()
    ttk_style.configure('TNotebook.Tab', font="Helvetica 10 bold",
        foreground='blue', background='gray75')
    
    app = App(main_win)
    
    main_win.mainloop()
 
 
if __name__ == '__main__':
    main()      
Gruss wuf ;-)
Take it easy Mates!
Marvin75854

wuf hat geschrieben: Donnerstag 2. August 2018, 15:46 Ok Marvin75854

Hier die Variante für Python2.xx:

Code: Alles auswählen

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

import os
import time
from functools import partial

import Tkinter as tk
import ttk
import tkFileDialog

APP_TITLE = "COG Tool"
APP_XPOS = 50
APP_YPOS = 50
APP_WIDTH = 800 #1800
APP_HEIGHT = 400 #800

class ModelVector(object):

    def __init__(self, x=0, y=0, z=0):
        self.x = x
        self.y = y
        self.z = z

    def __str__(self):
        return '({0.x}, {0.y}, {0.z})'.format(self)
    
    def __add__(self, other):
        return ModelVector(
            self.x + other.x, self.y + other.y, self.z + other.z)

class ModelMain(object):
    DDY = -365
    def __init__(self):
        self.ddy = self.DDY
        
    def export(self, filename, row_index, point_values):
        x, y, z = point_values
        
        with open(filename, 'a') as out_file:
            out_file.write('$Erstellt durch COG-Tool am: {0}\n'.format(
                    time.strftime('%d.%m.%Y %H:%M:%S')))

            
            hdpa_points = self.hdpa_berechnen(ModelVector(x, y, z), self.ddy)
            self.hdpa_ausgabe(
                ModelVector(x, self.ddy, z),
                row_index, #self.sitzreihe
                row_index, #self.i,
                hdpa_points,
                out_file)
            
            out_file.write('ENDDATA\n') 

    def hdpa_berechnen(self, point, ddy):
        return [
            point + ModelVector(126 - 82, ddy, 594 - 58),
            point + ModelVector(147 + 82, ddy, 594 - 52),
            point + ModelVector(126 - 82, ddy, 693 + 82),
            point + ModelVector(147 + 82, ddy, 693 + 82)]


    def hdpa_ausgabe(self, h_point, sitzreihe, i_start, node_points, out_file):
        print("Hier bricht meine Unterstützung ab!")
        return
        
        out_file.write(
            '$H-Punkt: {0}\n'
            '$HDPA-Feld fuer die {1}. Sitzreihe:\n'.format(h_point, sitzreihe)
        )
        i = None
        for i, point in enumerate(node_points, i_start):
            out_file.write(
                'NODE  / 1000000{0}{1.x:16.6f}{1.y:16.6f}{1.z:16.6f}\n'.format(
                    i, point
                )
            )
    
        indices = [0, 1, 3, 2]
        print("Check:", len(indices), i)
        if len(indices) != i:
            raise ValueError(
                'wrong number of node points ({} != {})'.format(len(indices), i)
            )
        out_file.write(
            'SHELL / 1000000{0}       11000000{1}        \n'
            'PART  / 1000000{0}SHELL          1                        \n'
            'NAMEDefault HDPA_Feld_{0}.Sitzreihe\n'
            '                    \n'
            '                              \n'
            '        1.    3               \n\n'
            'END_PART\n'.format(
                sitzreihe,
                '1000000'.join(str(i_start + j) for j in indices),
            )
        )
        
class GuiSeatRow(tk.Frame):
    ROW_NR_FONT = "Helvetica 22 bold"
    
    def __init__(self, gui, row):
        self.gui = gui
        self.row = row
        
        self.build()
        
    def build(self):
        tk.Frame.__init__(self, self.gui.main_frame)
        
        self.row_var = tk.IntVar(self.gui.app.main_win, self.row+1)
        tk.Label(self, textvariable= self.row_var, bg='blue',
            fg='white', font=self.ROW_NR_FONT, width=2
            ).pack(pady=(5, 10))
        
        self.box = tk.IntVar(self.gui.app.main_win, False)
        tk.Checkbutton(self, text="HDPA Feld", variable=self.box
            ).pack()        
 
        self.hdpa = tk.Label(self, text="H-Punkt WS50%")
        self.hdpa.pack(pady=5)
      
        entry_frame = tk.Frame(self)
        entry_frame.pack(pady=5)
        
        label_frame = tk.LabelFrame(entry_frame, text="X:", relief='flat')
        label_frame.pack(side='left')
        self.hx_var = tk.StringVar(self.gui.app.main_win, 0)
        tk.Entry(label_frame, textvariable=self.hx_var).pack()
        
        label_frame = tk.LabelFrame(entry_frame, text="Z:", relief='flat')
        label_frame.pack(side='left')
        self.hz_var = tk.StringVar(self.gui.app.main_win, 0)
        tk.Entry(label_frame, textvariable=self.hz_var).pack()
 
        label_text = "Y-Abstand:\nCOG/H-Punkt zu Airbag"
        label_frame = tk.LabelFrame(self, text=label_text,
            relief='flat')
        label_frame.pack(anchor='w', pady=5)
        self.dy_var = tk.StringVar(self.gui.app.main_win, 0)
        tk.Entry(label_frame, textvariable=self.dy_var).pack() 

        tk.Button(self, text="Export", command=partial(
            self.gui.export, self.row)).pack(pady=5)

        
class GuiMain(object):
    NOTEBOOK_TAB_FONT = ("Helvetica", 12, "bold")
    ANZAHL_SITZREIHEN = 5
    
    def __init__(self, app):
        self.app = app
        
        self.seat_rows = list()
        
        self.build()
        
        for row in range(self.ANZAHL_SITZREIHEN):
            seat_row = GuiSeatRow(self, row)
            seat_row.pack()
            self.note_book.add(seat_row, text="Sitzreihe-{}".format(row+1),
                sticky='nw', padding=10)
            self.seat_rows.append(seat_row)
        
    def build(self):
        self.main_frame = tk.Frame(self.app.main_win)
        self.main_frame.pack(fill='both', expand=True, padx=5, pady=5)

        self.note_book = ttk.Notebook(self.main_frame)
        self.note_book.pack(fill='both', expand=True)

    def file_dialog(self):
        filename = tkFileDialog.asksaveasfilename(
            initialdir=os.getcwd(),
            title='Speichern der Include-Datei',
            filetypes=(('all files', '*.*'), ('inc files', '*.inc')))
        return filename
            
        
    def export(self, row_index):
        if self.seat_rows[row_index].box.get():
            hx_var = self.seat_rows[row_index].hx_var
            dy_var = self.seat_rows[row_index].dy_var
            hz_var = self.seat_rows[row_index].hz_var
                       
            self.app.export(row_index, (float(entry_var.get()) 
                for entry_var in [hx_var, dy_var, hz_var]))
        else:
            print("Kein HDPA-Feld")
            print(self.seat_rows[row_index].hx_var.get())
     
class App(object):

    def __init__(self, main_win):
        self.main_win = main_win
        self.main_win.protocol("WM_DELETE_WINDOW", self.close)
        
        self.model = ModelMain()
        self.gui = GuiMain(self)
            
    def export(self, row_index, point_values):
        filename = self.gui.file_dialog()
        if filename != ():
            self.model.export(filename, row_index, point_values)
        else:
            print("Filedialog wurde abgebrochen")
                
    def close(self):
        print("Application-Shutdown")
        self.main_win.withdraw()
        self.main_win.destroy()
        
               
def main():
    main_win = tk.Tk()
    main_win.title(APP_TITLE)
    #main_win.geometry("+{}+{}".format(APP_XPOS, APP_YPOS))
    main_win.geometry("{}x{}".format(APP_WIDTH, APP_HEIGHT))
    main_win.option_add("*highlightThickness", 0)
    ttk_style = ttk.Style()
    ttk_style.configure('TNotebook.Tab', font="Helvetica 10 bold",
        foreground='blue', background='gray75')
    
    app = App(main_win)
    
    main_win.mainloop()
 
 
if __name__ == '__main__':
    main()      
Gruss wuf ;-)

Ich habe leider das tkk Modul nicht. Das ist, wenn ich das richtig gelesen habe, nicht standardmäßig dabei. Oder gibt es dafür noch andere Schreibweisen? Daher hat der Code so bei mir leider auch nicht funktioniert. Ich konnte mir da aber trotzdem noch einige nützliche Dinge rausziehen.

Und nochmal Vielen Dank an euch alle. Hat mir sehr geholfen.
Habe immer noch nicht alles so richtig verstanden, aber mein Code ist jetzt um einiges besser geworden. Da das Programm laut Kunden voraussichtlich nur sehr wenig oder gar nicht erweitert wird, ist das so in Ordnung, wenn er nicht 100% perfekt ist. Leider könnte das zeitlich recht eng werden, wenn ich noch mehr Zeit investiere. Wichtig ist, dass ich einige Variablen Global definiere, die dann die Berechnungen beeinflussen und man das Programm so ggf. flexibel justieren kann. Und für meine Dummy Klassen werde ich ein extra Modul schreiben, falls noch einer hinzugefügt werden soll. Ansonsten wird im Programm nichts verändert werden.
Marvin75854

Eine Frage habe ich aber noch. Ist es möglich mit einer If-Abfrage zu testen ob eine bestimmte Funktion im Programm schon ausgeführt worden ist? Ich will über einen Button einen subprocess einbauen und Vorraussetzung dafür ist, dass vorher eine bestimmte Funktion bereits eine Datei rausgeschrieben hat. Das heißt, dass wenn die Funktion noch nicht ausgeführt wurde, soll diese automatisch ausgeführt werden, eine Datei rausschreiben und danach direkt der subprocess.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Man testet, ob eine Funktion schon ausgeführt worden ist, indem man ein Variable nach der Ausführung setzt und diese beim nächsten Mal abfrägt.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wenn du so etwas willst, dann musst du das programmieren. Indem du dir in einer Variable merkst, ob etwas passiert ist. Oder noch besser, indem du es pruefst, ob die gewuenschte Datei existiert. Denn dann kann es nicht passieren, dass du *denkst* du hast die Datei geschrieben, weil du die Variable gesetzt (oder nicht zurueck-gesetzt) hast, ohne das die Realitaet damit uebereinstimmt.
Marvin75854

Ja so ähnlich habe ich es schon, dachte nur es gibt da vielleicht eine bessere Möglichkeit.


Ist es möglich eine Klasse über eine Variable aufzurufen? Weiß nicht wie ich das beschreiben soll. Hier mal ein kurzes Beispiel:

Code: Alles auswählen


Dummy_1 = StringVar(self)
Dummy_1.set("H395")
popupMenuD1 = OptionMenu(GUI, Dummy_1, *choicesD)
popupMenuD1.grid(row=3, column=6, padx = 20)

        

x = Dummy_1(...)
x.calc()

class H395:
    def __init__(...):
        ...
    def calc(self):
        ...

class WS50:
... 

class...:
...
Also ich habe einige Klassen und will jetzt über ein Dropdownmenü einen Dummy auswählen und automatisch die entsprechende Klasse erstellt wird. Also den Namen der Klasse über die Variable "Dummy_1" aufrufe. In meinem Programm sind die Klassen und das OptionMenu noch in verschiedenen Modulen. Das Ziel ist, dass es möglich ist zu einem späteren Zeitpunkt eine Klasse hinzuzufügen ohne viel im Programm ändern zu müssen. Ich müsste dann ja nur "choicesD" noch anpassen.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Dazu benutzt man ein Wörterbuch. Das bildet Optionen auf Klassen oder Funktionen ab. Wenn eine neue Klasse dazu kommt, dann muss die nur in das Wörterbuch eingetragen werden. Und um die Reihenfolge zu definieren, benutzt man ein OrderedDict.
Marvin75854

__deets__ hat geschrieben: Freitag 10. August 2018, 10:02 Dazu benutzt man ein Wörterbuch. Das bildet Optionen auf Klassen oder Funktionen ab. Wenn eine neue Klasse dazu kommt, dann muss die nur in das Wörterbuch eingetragen werden. Und um die Reihenfolge zu definieren, benutzt man ein OrderedDict.
Habe mal ein bisschen guckt. Ist es nicht so, dass ich in einem Wörterbuch der Variablen Dummy_1 quasi den Namen "H395" zuweise. Ich will aber ja dass, Dummy_1 über die GUI mit einem DropdownMenu ausgewählt werden soll. Das heißt ich habe ein DropdownMenu mit 5 Auswahlmöglichkeiten und will dann dementsprechend die richtige Klasse aufrufen. Ist die Reihenfolge nicht egal? Ich kann mit der Reihenfolge ja bestimmte Elemente im Wörterbuch aufrufen. Ich weiß aber ja vorher nicht, welche Auswahl ich auf der GUI treffe und dementsprechend auch nicht an welcher Stelle das im Wörterbuch steht.

Es ist ja so, dass ich etwas auswähle was dann unter Dummy_1 hinterlegt ist. Das Funktioniert perfekt. Auch bei Print(Dummy_1) gibt er mir dann ganz normal den Inhalt aus, also z.b. "H395" aus. Ist es nicht irgendwie möglich, dass bei dem Klassenaufruf "x = Dummy_1 (...)" auch der Inhalt, also "H395" anstatt von dem eigentlichen Wort "Dummy_1" beachtet wird?
Ich kann "Dummy_1" ja nicht fest den Audruck "H395", weil er ja flexibel sein soll und eben auf der GUI ausgewählt wird
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das Wörterbuch bildet Dropdown-Optionen auf die Klasse (nicht deren NAMEN) ab.

Code: Alles auswählen

sauna_options = { 
     “finnisch” : FinnishSaunaClass,
     “rauch” : RauchSauna,
}
Deine Auswahl-Variable Dummy_1 (ganz mieser Name übrigens) beihnaltet dann eben einen der Schlüssel. Und wenn der Benutzer “Los geht’s “ drückt, wird eben die Klasse nachgeschlagen & erzeugt:

Code: Alles auswählen

sauna_options[Dummy_1.get()]()
Marvin75854

__deets__ hat geschrieben: Freitag 10. August 2018, 11:20 Das Wörterbuch bildet Dropdown-Optionen auf die Klasse (nicht deren NAMEN) ab.

Code: Alles auswählen

sauna_options = { 
     “finnisch” : FinnishSaunaClass,
     “rauch” : RauchSauna,
}
Deine Auswahl-Variable Dummy_1 (ganz mieser Name übrigens) beihnaltet dann eben einen der Schlüssel. Und wenn der Benutzer “Los geht’s “ drückt, wird eben die Klasse nachgeschlagen & erzeugt:

Code: Alles auswählen

sauna_options[Dummy_1.get()]()
Ah ok. Habe das ganze jetzt mal getestet und es klappt

Code: Alles auswählen


GUI = tx.Tk()
GUI.title ("COG Tool") 
GUI.geometry("1800x800")

choicesD = ('SID-IIs',"H395")  

Dummy_1 = StringVar(GUI)
Dummy_1.set("H395")
popupMenuD1 = OptionMenu(GUI, Dummy_1, *choicesD)
popupMenuD1.grid(row=1, column=0)

class H395:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def calc(self):
        return(self.x+self.y)

class SIDIIs:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        
    def calc(self):
        return(self.x*self.y)

Dummy_options = {"H395" : H395,
                 "SID-IIs" : SIDIIs
}
def test():
    x = Dummy_options[Dummy_1.get()](5, 5)
    print(x.calc())

button = Button(GUI, text= "test", command=test).grid(row=0, column=0)

GUI.mainloop()
Ja das mit den Namen wurde hier schon einige male erwähnt :D Meine Namen sind auch wirklich suboptimal. In diesem Fall handelt es sich aber tatsächlich um einen Dummy der in Crashsimulationen eingesetzt wird. H395 und SIDIIs usw. sind dann Versionen von Dummys. und _1 einfach nur weil ich 4 Dummys übergeben muss um daraus ein Trefferfeld zu erzeugen.
Vielen Dank. Das mit dem Wörterbuch kann mir vielleicht sogar noch an anderen Stellen helfen.
Antworten