2017-01-11 36 views
-2

Ich bin neu in Python und daher Tkinter. Für ein erstes kleines Projekt versuche ich ein Programm zum Schreiben einer CSV-Datei zu erstellen. Das Programm erhält beim Start einen Dateinamen, prüft die Datei auf einen Header und erstellt dynamisch die notwendige Anzahl von Eingabefeldern.Python Tkinter Gitter Layout durcheinander

Um die Fortsetzung zu erleichtern, wird die zuletzt eingegebene Zeile angezeigt.

Momentan bin ich auf halbem Weg und die letzte Zeile und die korrekte Anzahl der Eingabe Widgets werden angezeigt. Leider ist das Layout Müll.

Example

Ich habe die Etiketten erwartet vor dem Eintrag Widgets sein und die Schaltfläche Beenden auf der Unterseite.

Irgendwelche Ideen?

Vielen Dank im Voraus.

# -*- coding: utf-8 -*- 
import Tkinter as tk 
import argparse 
import time 

parser = argparse.ArgumentParser() 
parser.add_argument('filename', nargs=1, help="file to parse") 
args = parser.parse_args() 

filename = args.filename[0] 


def get_headers(filename): 
    with open(filename, 'r') as f: 
     headers = f.readline() 
    return(headers) 


def file_len(filename): 
    with open(filename) as f: 
     for i, l in enumerate(f): 
      pass 
    return i, l 


class Application(tk.Frame): 

    def __init__(self, headers, filename, last_line, master=None): 
     tk.Frame.__init__(self, master) 
     self.grid() 
     self.filename = filename 
     lastentry = self.createWidgets(self.filename, headers, last_line) 
     # print lastentry 
     # print(lastentry[0].get()) # Test 
     # lastentry[0].delete(0,tk.END) # Test 
     # lastentry[0].insert(0,"Test") # Test 

    def createWidgets(self, filename, headers, last_line): 
     headers = get_headers(filename).split(',') # .decode('utf8') 
     self.lastentry = [] 
     self.entryfield = [] 
     self.label = tk.Label(self, text="CSV Entry Tool").grid(columnspan=3, pady=(0,10)) 
     for x, y in enumerate(headers): 
      self.create_label_widget(x, y) 
     for x, y in enumerate(last_line): 
      self.lastentry.append(self.create_lastentry_widget(x, y)) 
     for x in range(len(last_line)): 
      self.entryfield.append(self.create_entry_widget(x)) 

     self.lastlineLabel = tk.Label(self, text="Last Entry: ").grid(row=2, column=1, padx=(10,10), pady=(0,15)) 
     self.entryLabel = tk.Label(self, text="New Entry: ").grid(row=3, column=1, padx=(10,10), pady=(0,15)) 

     self.quitButton = tk.Button(self, text='Quit', command=self.quit) 
     self.quitButton.grid(row=6, column=6) 
     return self.lastentry 


    def create_label_widget(self, x, y): 
     new_widget = tk.Label(self.master, text=y).grid(row=1, column=x+1, padx=(10,10), pady=(0,15)) 
     return new_widget 

    def create_entry_widget(self, x): 
     new_widget = tk.Entry(self.master) 
     new_widget.grid(row=3, column=x+1, padx=(10,10), pady=(0,15)) 
     return new_widget 

    def create_lastentry_widget(self, x, y): 
     new_widget = tk.Entry(self.master) 
     new_widget.grid(row=2, column=x+1, padx=(10,10), pady=(0,15)) 
     new_widget.insert(1, y) 
     new_widget.configure(state="readonly") 
     return new_widget 

headers = get_headers(filename).split(',') # .decode('utf8') 

print headers 

# Check Filelengh and get back last line. 
file_lengh, last_line = file_len(filename) 
print("Einträge: ".decode('utf8')) + str(file_lengh) 
last_line = last_line.split(',') 
print last_line 


app = Application(headers, filename, last_line) 
app.master.title('Sample application') 
app.mainloop() 
+0

BTW:. Code 'var = Widget (...) Raster (...)' 'weist None' zu' var' weil 'Raster()' 'kehrt None' - mach es in zwei Schritten 'var = Widget (...)' und 'var.grid (...)' oder überspringe Variable, wenn du sie nicht brauchst - 'Widget (...). grid (. ..) ' – furas

+1

Sie erstellen Beschriftungen und Schaltflächen in' self', aber andere Elemente in 'self.master' - so dass sie sich in verschiedenen Widgets befinden können, die ein eigenes Gitter haben. – furas

+0

BTW: Verwenden Sie das Modul 'csv', um CSV-Dateien zu lesen - jetzt liest es falsch meine Datei, die Komma in Text in einer Spalte hat - wie' "(x, y)" '. Es hat auch ein Problem, wenn der Text in einer Spalte "\ n" enthält. – furas

Antwort

2

Sie erstellen Etiketten und Schaltfläche in self aber auch andere Elemente in self.master - so können sie in verschiedenen Widgets sein, die eigene Gitter haben.

Nach dem Wechsel self.master in self und column=x+1 in column=x+2 bekam ich

enter image description here

ich auch ändern var = Widget(...).grid(...) in var = Widget(...) und var.grid(...)

Sie csv Moduldaten zu lesen, weil korrekte csv Reihe mit 3 verwenden sollen Spalten

"a","b","(x,y)" 

lesen Sie als 4 Spalten.

Und Sie können das gleiche Problem mit \n

"a","b","(x 
y)" 

Ihr Code liest dies als 2 Zeilen, aber es ist richtig, eine Zeile.

Code:

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

import Tkinter as tk 
import argparse 
import time 

# --- classes --- 

class Application(tk.Frame): 

    def __init__(self, headers, filename, last_line, master=None): 
     tk.Frame.__init__(self, master) 
     self.grid() 
     self.filename = filename 
     lastentry = self.createWidgets(self.filename, headers, last_line) 
     # print lastentry 
     # print(lastentry[0].get()) # Test 
     # lastentry[0].delete(0,tk.END) # Test 
     # lastentry[0].insert(0,"Test") # Test 

    def createWidgets(self, filename, headers, last_line): 
     headers = get_headers(filename).split(',') # .decode('utf8') 

     self.lastentry = [] 
     self.entryfield = [] 

     self.label = tk.Label(self, text="CSV Entry Tool") 
     self.label.grid(columnspan=3, pady=(0,10)) 

     for x, y in enumerate(headers): 
      self.create_label_widget(x, y) 

     for x, y in enumerate(last_line): 
      self.lastentry.append(self.create_lastentry_widget(x, y)) 

     for x in range(len(last_line)): 
      self.entryfield.append(self.create_entry_widget(x)) 

     self.lastlineLabel = tk.Label(self, text="Last Entry: ") 
     self.lastlineLabel.grid(row=2, column=1, padx=(10,10), pady=(0,15)) 

     self.entryLabel = tk.Label(self, text="New Entry: ") 
     self.entryLabel.grid(row=3, column=1, padx=(10,10), pady=(0,15)) 

     self.quitButton = tk.Button(self, text='Quit', command=self.quit) 
     self.quitButton.grid(row=6, column=4) 

     return self.lastentry 


    def create_label_widget(self, x, y): 
     new_widget = tk.Label(self, text=y) 
     new_widget.grid(row=1, column=x+2, padx=(10,10), pady=(0,15)) 
     return new_widget 

    def create_entry_widget(self, x): 
     new_widget = tk.Entry(self) 
     new_widget.grid(row=3, column=x+2, padx=(10,10), pady=(0,15)) 
     return new_widget 

    def create_lastentry_widget(self, x, y): 
     new_widget = tk.Entry(self) 
     new_widget.grid(row=2, column=x+2, padx=(10,10), pady=(0,15)) 
     new_widget.insert(1, y) 
     new_widget.configure(state="readonly") 
     return new_widget 

# --- functions --- 

def get_headers(filename): 
    with open(filename, 'r') as f: 
     headers = f.readline() 
    return(headers) 

def file_len(filename): 
    with open(filename) as f: 
     for i, l in enumerate(f): 
      pass 
    return i, l 

# --- main --- 

parser = argparse.ArgumentParser() 
parser.add_argument('filename', nargs=1, help="file to parse") 
args = parser.parse_args() 

filename = args.filename[0] 

headers = get_headers(filename).split(',') # .decode('utf8') 

print headers 

# Check Filelengh and get back last line. 
file_lengh, last_line = file_len(filename) 
print("Eintrage: ".decode('utf8')) + str(file_lengh) 
last_line = last_line.split(',') 
print last_line 

app = Application(headers, filename, last_line) 
app.master.title('Sample application') 
app.mainloop() 
+0

Vielen Dank für Ihre Antwort. – Avarion