Files
CreoMigrate/lib/CreoMigrateGui.py
T

308 lines
12 KiB
Python

import tkinter as tk
from tkinter import ttk
from controller import Controller
from caditem import CadItem
#from tkinter import messagebox
#import logging
#logger = logging.getLogger(__name__)
class TreeView():
def __init__(self, frame, controller):
self.controller = controller
# a treeview
# hier Anzahl der sichtbaren Zeilen des Baums angeben:
self.tree = ttk.Treeview(frame, height=40)
# TODO hier anstatt root die Statistik rein schreiben.
self.tree.heading('#0', text='root', anchor=tk.W)
# add a scrollbar
scrollbar = ttk.Scrollbar(frame, orient=tk.VERTICAL, command=self.tree.yview)
self.tree.configure(yscroll=scrollbar.set)
scrollbar.grid(row=0, column=1, sticky='ns')
self.tree.bind('<<TreeviewSelect>>', self.item_selected)
def clear(self):
self.tree.delete()
def create(self, parent_children_mapping, red_ids):
# adding data of first column after root
pool = set()
for parent,children in parent_children_mapping.items():
if parent not in pool:
self.tree.insert('', tk.END, text=parent, iid=parent, open=True)
pool.add(parent)
cn = children
# sortiere die Zahlen im Baum immer aufsteigend
cn.sort(reverse=True)
for child_id in cn:
if child_id not in pool:
pool.add(child_id)
if child_id not in red_ids: rowtags = ('good')
else: rowtags = ('missing')
self.tree.insert('', tk.END, text=child_id, iid=child_id, tags=rowtags, open=True)
#self.tree.move(child_id, parent, 0)
# einmal über alles gehen und alle keys an die richtige Stelle schieben
for parent,children in parent_children_mapping.items():
for child_id in children:
self.tree.move(child_id, parent, 0)
# https://www.askpython.com/python-modules/tkinter/tkinter-colors
#self.tree.tag_configure('good', background='LawnGreen')
self.tree.tag_configure('good', background='white')
self.tree.tag_configure('missing', background='red')
def item_selected(self, event):
"""callback if an item in the tree has been selected
"""
cid = self.tree.selection()[0]
# trage es
self.controller.set_gui_data('teilenummer', cid)
self.controller.update_view()
# for selected_item in self.tree.selection():
# item = self.tree.item(selected_item)
# record = item['values']
# messagebox.showinfo(title='Information', message=','.join(record))
def get_handle(self):
return self.tree
class RightFrameLabels():
def __init__(self, frame, controller, nrow=0):
self.controller = controller
self.frame = frame
self.build_gui()
self.data_from_model()
self.set_start_rwo(nrow)
def get_rows(self):
return self.rownum
def set_start_rwo(self, nrow):
if nrow < 0:
raise Exception("this row can not be set")
self.rownum = nrow
def build_gui(self):
frame = self.frame
self.rownum = 0
col_left = 0
# Feld, SIVAS-Werte, Überschriebene Werte
feld_label = ttk.Label(frame, text="Feld" )
feld_label.grid(column=col_left, row=self.rownum, sticky=tk.W, padx=5, pady=5)
Sivas_label = ttk.Label(frame, text="SIVAS-Werte" )
Sivas_label.grid(column=col_left+1, row=self.rownum, sticky=tk.W, padx=5, pady=5)
transwritten_label = ttk.Label(frame, text="Überschriebene Werte" )
transwritten_label.grid(column=col_left+2, row=self.rownum, sticky=tk.W, padx=5, pady=5)
feld_label.configure(font=("Helvetica", 16))
Sivas_label.configure(font=("Helvetica",16))
transwritten_label.configure(font=("Helvetica",16))
self.rownum += 1
separator = ttk.Separator(frame, orient='horizontal')
separator.grid(column=col_left, columnspan=3, row=self.rownum, sticky=tk.EW, padx=5, pady=5)
self.rownum += 1
# Teilenummer
teilenummer_label = ttk.Label(frame, text="Teilenummer:")
teilenummer_label.grid(column=col_left, row=self.rownum, sticky=tk.W, padx=5, pady=5)
self.teilenummer_text = tk.StringVar()
teilenummer_entry = ttk.Entry(frame, textvariable=self.teilenummer_text)
teilenummer_entry.grid(column=col_left+1, row=self.rownum, sticky=tk.W, padx=5, pady=5)
self.rownum += 1
separator2 = ttk.Separator(frame, orient='horizontal')
separator2.grid(column=col_left, columnspan=3, row=self.rownum, sticky=tk.EW, padx=5, pady=5)
self.rownum += 1
def get_data(self):
return {
"teilennummer": self.teilenummer_text.get(),
}
def data_to_model(self):
data = self.get_data()
self.controller.set_gui_dict(data)
def data_from_model(self):
data = self.controller.get_all_gui_data()
if 'teilenummer' in data:
self.teilenummer_text.set(data["teilenummer"])
class RightFramePDM():
def __init__(self, frame, controller, nrow=0):
self.controller = controller
self.frame = frame
self.build_gui()
self.data_from_model()
self.set_start_rwo(nrow)
def get_rows(self):
return self.rownum
def set_start_rwo(self, nrow):
if nrow < 0:
raise Exception("this row can not be set")
self.rownum = nrow
def build_gui(self):
frame = self.frame
self.rownum = 4
col_left = 0
# pdmkategorie
pdmkategorie_label = ttk.Label(frame, text="PDM-Kategorie:" )
pdmkategorie_label.grid(column=col_left, row=self.rownum, sticky=tk.W, padx=5, pady=5)
self.pdm_category = tk.StringVar()
pdmkategorie_combo = ttk.Combobox(frame, textvariable=self.pdm_category)
pdmkategorie_combo['values'] = ["Baugruppe", "Einzelteil", "Kaufteil", "NichtSivas", "Normteil", "Schweissbaugruppe"]
pdmkategorie_combo['state'] = 'readonly'
pdmkategorie_combo.bind('<<ComboboxSelected>>', self.combo_callbacks) # falls nötig
pdmkategorie_combo.grid(column=col_left+2, row=self.rownum, sticky=tk.W, padx=5, pady=5)
self.rownum += 1
# Neuaufbau
neuaufbau_label = ttk.Label(frame, text="Neuaufbau:")
neuaufbau_label.grid(column=col_left, row=self.rownum, sticky=tk.W, padx=5, pady=5)
self.neuaufbau = None
neuaufbau_checkbutton = ttk.Checkbutton(frame,
text='ja',
variable=self.neuaufbau,
onvalue="True",
offvalue="False")
neuaufbau_checkbutton.grid(column=col_left+2, row=self.rownum, sticky=tk.W, padx=5, pady=5)
self.rownum += 1
# Lebenszyklusstatus
lebenszyklusstatus_label = ttk.Label(frame, text="Lebenszyklusstatus:")
lebenszyklusstatus_label.grid(column=col_left, row=self.rownum, sticky=tk.W, padx=5, pady=5)
self.lebenszyklus_status_neu = tk.StringVar()
lebenszyklusstatus_combo = ttk.Combobox(frame, textvariable=self.lebenszyklus_status_neu)
lebenszyklusstatus_combo['values'] = ["Serie", "Prototyp"]
lebenszyklusstatus_combo['state'] = 'readonly'
lebenszyklusstatus_combo.bind('<<ComboboxSelected>>', self.combo_callbacks)
lebenszyklusstatus_combo.grid(column=col_left+2, row=self.rownum, sticky=tk.W, padx=5, pady=5)
self.rownum += 1
# aus Halbzeug
halbzeug_label = ttk.Label(frame, text="aus Halbzeug:")
halbzeug_label.grid(column=col_left, row=self.rownum, sticky=tk.W, padx=5, pady=5)
self.aus_halbzeug_neu = None
aushalbzeug_checkbuttonr = ttk.Checkbutton(frame,
text='neu',
variable=self.aus_halbzeug_neu,
onvalue="True",
offvalue="False")
aushalbzeug_checkbuttonr.grid(column=col_left+2, row=self.rownum, sticky=tk.W, padx=5, pady=5)
self.rownum += 1
# Zusatzinformationen
zusatzinfos_label = ttk.Label(frame, text="Zusatzinformationen:")
zusatzinfos_label.grid(column=col_left, row=self.rownum, sticky=tk.W, padx=5, pady=5)
self.zusatzinfos_text = tk.StringVar()
zusatzinfos_entry = ttk.Entry(frame, textvariable=self.zusatzinfos_text)
zusatzinfos_entry.grid(column=col_left+2, row=self.rownum, sticky=tk.W, padx=5, pady=5)
self.rownum += 1
def get_data(self):
return {
"pdm_kategorie_neu": self.pdm_category.get(),
"neuaufbau": self.neuaufbau,
"lebenszyklus_status_neu": self.lebenszyklus_status_neu.get(),
"aus_halbzeug_neu": self.aus_halbzeug_neu,
"zusatzinfos_txt_neu": self.zusatzinfos_text.get(),
}
def data_to_model(self):
data = self.get_data()
self.controller.set_gui_dict(data)
def data_to_model(self, key, value):
self.controller.set_gui_data(key, value)
def data_from_model(self):
data = self.controller.get_all_gui_data()
if 'pdm_kategorie_neu' in data:
self.pdm_category.set(data["pdm_kategorie_neu"])
if 'neuaufbau' in data:
self.neuaufbau = data["neuaufbau"]
if 'lebenszyklus_status_neu' in data:
self.lebenszyklus_status_neu.set(data["lebenszyklus_status_neu"])
if 'aus_halbzeug_neu' in data:
self.zusatzinfos_text.set(data["aus_halbzeug_neu"])
if 'zusatzinfos_text_neu' in data:
self.aus_halbzeug_neu = data["zusatzinfos_text_neu"]
def combo_callbacks(self, event):
""" handle the changed event """
# TODO falls nötig
pass
class App():
def __init__(self, root, controller):
self.root = root
self.controller = controller
# configure the grid
# die erste Spalte mit Baum sollte unbeweglich bleiben bei Vergräßerung des Fensters.
# self.root.columnconfigure(0, weight=2)
self.root.columnconfigure(1, weight=1)
#self.root.geometry('800x800')
# Create left and right frames
left_frame = ttk.Frame(self.root, width=200, height=800)
left_frame.grid(row=0, column=0, padx=10, pady=5)
right_frame = ttk.Frame(self.root, width=650, height=800)
right_frame.grid(row=0, column=1, padx=10, pady=5)
style = ttk.Style(self.root)
style.theme_use('classic')
current_id = self.controller.get_current_asm_id()
parent_children_mapping = self.controller.get_parent_children()
red_ids = self.controller.get_red_ids()
self.tv = TreeView(left_frame, controller)
self.tv.create(parent_children_mapping, red_ids)
gridhdl = self.tv.get_handle()
gridhdl.grid(row=0, column=0, sticky=tk.NSEW)
self.rf0 = RightFrameLabels(right_frame, controller, 0)
nrows = self.rf0.get_rows()
self.rf1 = RightFramePDM(right_frame, controller, nrows)
nrows = self.rf1.get_rows()
#self.rf2 = RightFramePDM(right_frame, controller, nrows)
# TODO usw.
def update_view(self):
self.rf0.update_view()
self.rf1.update_view()
def mainloop(self):
self.root.mainloop()
if __name__ == "__main__":
""" using the Model-View-Controller (MVC) Pattern
- The MODEL is responsible for managing the data of the application. It
receives user input from the CONTROLLER
- The VIEW renders presentation of the model in a particular format.
- The CONTROLLER responds to the user input and performs interactions on the
data model objects. The CONTROLLER receives the input, optionally validates
it and then passes the input to the model.
MODEL
<-updates- ^--manipulates--
VIEW CONTROLLER
--sees --> -- uses -->
USER
"""