2017-04-05 21 views
0

Ich erstelle ein einfaches GUI-Programm, um die Zeit von einem bestimmten Ereignis zu messen. Ich erhalte eine Fehlermeldung:TypeError: 'DoubleVar' -Objekt kann nicht implizit in str konvertiert werden

/usr/bin/python3.5 /home/cali/PycharmProjects/str8/str8.py Traceback (most recent call last): File "/home/cali/PycharmProjects/str8/str8.py", line 51, in app = App(root) File "/home/cali/PycharmProjects/str8/str8.py", line 22, in init Label(self, text=measurement + ": " + self.counters[measurement], font='Verdana 8').grid(row=i+1, column=0, sticky=W) TypeError: Can't convert 'DoubleVar' object to str implicitly

Process finished with exit code 1

ich das versucht:

Label(self, text=measurement + ": " + str(self.counters[measurement]), font='Verdana 8').grid(row=i+1, column=0, sticky=W) 

... aber es gibt mir dies:

GUI program

Hier ist, was ich getan habe:

# str8.py 
# Program to count time from a certain event 

from tkinter import * 
from datetime import * 


class App(Frame): 

    def __init__(self, *args, **kwargs): 

     Frame.__init__(self, *args, **kwargs) 
     self.grid(sticky = N + W + E + S) 

     Label(self, text = 'You have been STR8 for:', font="Verdana 8 bold").grid(row=0, sticky=W) 

     self.counters = dict() 
     measurements = [ 'Years', 'Weeks', 'Days', 'Hours', 'Minutes', 'Seconds' ] 

     for i, measurement in enumerate(measurements): 
      self.counters[measurement] = DoubleVar() 
      Label(self, text=measurement + ": " + self.counters[measurement], font='Verdana 8').grid(row=i+1, column=0, sticky=W) 
      self.counters[measurement].set(0) 

     Button(self, 
       text="EXIT", 
       font="Verdana 8", 
       height=1, 
       width=19, 
       command=quit).grid(row=7, column=0) 

     self.increment() 

    def increment(self): 
     event = datetime(2017, 4, 4, 0, 0, 0) 
     today = datetime.now() 

     str8 = today - event 
     self.counters['Seconds'].set(round(str8.total_seconds(), 2)) 
     self.counters['Minutes'].set(round(str8.total_seconds()/ 60, 2)) 
     self.counters['Hours'].set(round(str8.total_seconds()/3600, 2)) 
     self.counters['Days'].set(round(str8.total_seconds()/(3600 * 24), 2)) 
     self.counters['Weeks'].set(round(str8.total_seconds()/(3600 * 24 * 7), 2)) 
     self.counters['Years'].set(round(str8.total_seconds()/(3600 * 24 * 7 * 52), 2)) 

     self.after(1000, self.increment) 


if __name__ == '__main__': 
    root = Tk() 
    app = App(root) 
    root.title("STR8") 
    root.resizable(width=False, height=False) 
    app.mainloop() 

Antwort

1

Ein Label kann einen Text mit dem Argument text anzeigen ODER den Wert einer tkinter-Variablen wie eine DoubleVar mit dem Argument textvariable anzeigen. Es kann nicht beides. Entweder verwenden Sie diese:

lbl = Label(self, text=measurement + ": ", font='Verdana 8') 
lbl.grid(row=i+1, column=0, sticky=W) 

Oder diese:

lbl = Label(self, textvariable=self.counters[measurement], font='Verdana 8') 
lbl.grid(row=i+1, column=0, sticky=W) 

Edit: Eine Lösung für Ihr Problem wäre es, Ihre eigene Art von Label zu machen, die sowohl handhaben kann:

import tkinter as tk 
from datetime import datetime 

class FormatLabel(tk.Label): 
    '''A new type of Label widget that allows both a text and textvariable''' 
    def __init__(self, master=None, **kwargs): 
     self.textvariable = kwargs.pop('textvariable', tk.StringVar(master)) 
     self.text = kwargs.pop('text', '{}') 
     self.textvariable.trace('w', self.update_text) 
     tk.Label.__init__(self, master, **kwargs) 

    def update_text(self, *args): 
     self.config(text=self.text.format(self.textvariable.get())) 

class App(tk.Frame): 
    def __init__(self, master=None, **kwargs): 
     tk.Frame.__init__(self, master, **kwargs) 

     lbl = tk.Label(self, text = 'You have been STR8 for:', font="Verdana 8 bold") 
     lbl.grid(row=0, sticky=tk.W) 

     self.counters = dict() 
     measurements = [ 'Years', 'Weeks', 'Days', 'Hours', 'Minutes', 'Seconds' ] 

     for i, measurement in enumerate(measurements): 
      self.counters[measurement] = tk.DoubleVar() 
      lbl = FormatLabel(self, 
       text=measurement + ": {:.2f}", # set the rounding here 
       textvariable = self.counters[measurement], 
       font='Verdana 8') 
      lbl.grid(row=i+1, column=0, sticky=tk.W) 
      self.counters[measurement].set(0) 

     btn = tk.Button(self, 
       text="EXIT", 
       font="Verdana 8", 
       height=1, 
       width=19, 
       command=quit) 
     btn.grid(row=7, column=0) 

     self.increment() 

    def increment(self): 
     event = datetime(2017, 4, 4, 0, 0, 0) 
     today = datetime.now() 

     str8 = (today - event).total_seconds() 
     self.counters['Seconds'].set(str8) 
     self.counters['Minutes'].set(str8/60.) 
     self.counters['Hours'].set(str8/3600.) 
     self.counters['Days'].set(str8/(3600. * 24)) 
     self.counters['Weeks'].set(str8/(3600. * 24 * 7)) 
     self.counters['Years'].set(str8/(3600. * 24 * 7 * 52)) 

     self.after(1000, self.increment) 

def main(): 
    root = tk.Tk() 
    app = App(root) 
    app.pack() 
    root.title("STR8") 
    root.resizable(width=False, height=False) 
    app.mainloop() 

if __name__ == '__main__': 
    main() 

Hinweis Ich habe auch einige andere Teile deines Codes repariert. Vor allem, dass Sie keine Platzhalterimporte verwenden sollten (from module import *), sollten Sie Widgets nicht in derselben Zeile wie Sie sie definieren, und Sie sollten versuchen, den Code nicht zu wiederholen.

+0

Dann würde ich eine große Lücke zwischen den Etiketten bekommen, das ist der Grund, warum ich versuchte, die beiden in einem Etikett zu kombinieren. Komm schon, eine Lösung für mein Problem muss sehr einfach sein. –

+0

Einfach, nein. Aber machbar. Ich habe meine Antwort bearbeitet, um Ihnen einen Weg zu zeigen. – Novel

+0

Vielen Dank Herr, das ist der Geist! –

Verwandte Themen