2016-07-29 29 views
0

Ich habe versucht, einen einfachen ganzzahligen Zeichenrechner mit tkinter zu erstellen. Es hat eine Klasse mit zwei verschiedenen Funktionen. Die zweite Funktion soll ausgelöst werden, wenn der Benutzer die "Enter" -Taste drückt. Wenn ich den Code ausführe, erscheint das Fenster genau so, wie es soll. Aber wenn ich "Enter" tippe und drücke, läuft die zweite Funktion nicht und aktualisiert das Etikett nicht. Ich möchte, dass es aktualisiert entweder als "Diese Nummer ist positiv.", "Diese Zahl ist 0." oder "Diese Zahl ist negativ." Stattdessen bleibt es leer.Tkinter-Rechner kann Etikett nicht aktualisieren

Ich bezweifle, dass es relevant ist, aber ich habe dieses Programm in PyCharm Community Edition 5.0.4 gemacht, und ich verwende Python 3.5 (32-Bit).

import tkinter 

class IntegerSign: 

    def __init__(self): 
     self.window = tkinter.Tk() 
     self.window.title("Integer Sign Calculator") 
     self.window.geometry("300x150") 

     self.number_frame = tkinter.Frame(self.window) 

     self.solution_frame = tkinter.Frame(self.window) 
     self.button_frame = tkinter.Frame(self.window) 

     self.number_label = tkinter.Label(self.number_frame, text="Enter an integer:") 
     self.number_entry = tkinter.Entry(self.number_frame, width=10) 
     self.number_label.pack(side='left') 
     self.number_entry.pack(side='left') 

     self.statement = tkinter.StringVar() 
     self.solution_label = tkinter.Label(self.solution_frame, textvariable=self.statement) 

     self.statement = tkinter.Label(self.solution_frame, textvariable=self.statement) 

     self.solution_label.pack(side='left') 

     self.calc_button = tkinter.Button(self.button_frame, text='Enter', command=self.calc_answer) 
     self.quit_button = tkinter.Button(self.button_frame, text='Quit', command=self.window.destroy) 

     self.calc_button.pack(side='left') 
     self.quit_button.pack(side='left') 

     self.number_frame.pack() 
     self.solution_frame.pack() 
     self.button_frame.pack() 

     tkinter.mainloop() 

    def calc_answer(self): 
     self.number = int(self.number_entry.get()) 
     self.statement = tkinter.StringVar() 

     if self.number > 0: 
      self.statement = "This number is positive." 
     elif self.number == 0: 
      self.statement = "This number is 0." 
     else: 
      self.statement = "This number is negative." 
IntegerSign() 

Antwort

1

Das erste Problem ändern: in Ihrem Konstruktor Sie eine Variable mit dem Namen self.statement zu einem StringVar initialisieren und dann wieder auf ein Etikett initialisieren. Nach dieser zweiten Initialisierung haben Sie keine Möglichkeit, auf das erste Objekt zuzugreifen. Sie müssen zwei verschiedene Namen verwenden.

Das zweite Problem: in der Event-Handler, calc_answer, erstellen Sie ein neues Objekt mit dem Namen self.statement, sondern müssen Sie set einen neuen Wert in die alten (siehe docs). Hier ist eine modifizierte Version des Programms, das wie beabsichtigt funktioniert:

import tkinter 

class IntegerSign: 

    def __init__(self): 
     self.window = tkinter.Tk() 
     self.window.title("Integer Sign Calculator") 
     self.window.geometry("300x150") 

     self.number_frame = tkinter.Frame(self.window) 

     self.solution_frame = tkinter.Frame(self.window) 
     self.button_frame = tkinter.Frame(self.window) 

     self.number_label = tkinter.Label(self.number_frame, text="Enter an integer:") 
     self.number_entry = tkinter.Entry(self.number_frame, width=10) 
     self.number_label.pack(side='left') 
     self.number_entry.pack(side='left') 

     self.solution_string = tkinter.StringVar() 
     self.solution_label = tkinter.Label(self.solution_frame, textvariable=self.solution_string) 

     self.statement = tkinter.Label(self.solution_frame, textvariable=self.solution_string) 

     self.solution_label.pack(side='left') 

     self.calc_button = tkinter.Button(self.button_frame, text='Enter', command=self.calc_answer) 
     self.quit_button = tkinter.Button(self.button_frame, text='Quit', command=self.window.destroy) 

     self.calc_button.pack(side='left') 
     self.quit_button.pack(side='left') 

     self.number_frame.pack() 
     self.solution_frame.pack() 
     self.button_frame.pack() 

     tkinter.mainloop() 

    def calc_answer(self): 
     self.number = int(self.number_entry.get()) 

     if self.number > 0: 
      self.solution_string.set("This number is positive.") 
     elif self.number == 0: 
      self.solution_string.set("This number is 0.") 
     else: 
      self.solution_string.set("This number is negative.") 
IntegerSign() 

Dieser Code funktioniert, enthält aber eine schlechte Praxis, die ich empfehlen Sie beheben. Die Funktion tkinter.mainloop() ist im Wesentlichen eine Endlosschleife und Sie haben sie im Konstruktor platziert. Daher wird der Konstruktor nicht so zurückgegeben, wie es normalerweise für einen Konstruktor vorgesehen ist. Nehmen Sie diese Anweisung aus der __init__-Funktion und legen Sie sie am Ende, nach dem Aufruf an IntegerSign, und machen Sie dies zu einem Muster, das in Zukunft verwendet werden soll.

+0

Danke. Jetzt funktioniert es. –

+0

Gut. Bitte akzeptiere die Antwort. –

1

Um den Wert eines StringVar stellen Sie die set Methode verwenden müssen. Jetzt haben Sie nur die Variable neu zugewiesen. Sie können den Wert für die Zeichenfolgevariable (Standard) auch festlegen, indem Sie bei der ersten Initialisierung einen Wert angeben. z.B. - var = tk.StringVar(value="some value")

Edit: Habe nicht gesehen, dass Sie auch self.statement als Label-Widget setzen ... Das würde funktionieren, wenn Sie die Methode ganz unten in dieser Antwort verwenden würden, und ignoriert (optional) Stringvar ist vollständig. Aber wenn Sie das tun, können Sie es sich als Haftnotizen vorstellen. Sie haben eine Notiz angeheftet, die besagt: "Diese Variable enthält diesen Wert". Dann haben Sie die Variable neu zugewiesen und eine weitere Notiz über die vorherige gelegt, die besagt, dass "sie jetzt diesen Wert hält" als eine wirklich lose visuelle Analogie.

>>> import tkinter as tk 
>>> root = tk.Tk() 
>>> statement = tk.StringVar() 
>>> type(statement) 
>>> <class 'tkinter.StringVar'> 
>>> statement = "This number is positive" 
>>> type(statement) 
>>> <class 'str'> 
>>> statement = tk.StringVar() 
>>> statement.set("This number is positive") 
>>> statement.get() 
'This number is positive' 
>>> type(statement) 
>>> <class 'tkinter.StringVar'> 

Alternativ können Sie nur den Text Etiketten von label_widget['text'] = 'new_text' tun