TypeError:无法将“DoubleVar”对象隐式转换为str

2024-09-28 20:44:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在创建一个简单的GUI程序来测量某个事件的时间。我得到一个错误:

/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

我试过这个:

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

…但它给了我这个:

GUI program

以下是我所做的:

# 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()

Tags: textselfrootgridrowtotalmeasurementseconds
1条回答
网友
1楼 · 发布于 2024-09-28 20:44:55

标签可以使用text参数显示一些文本,也可以使用textvariable参数显示来自tkinter变量的值,就像DoubleVar一样。它不能两者兼而有之。使用以下选项之一:

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

或者这个:

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

编辑:解决问题的方法是制作自己的标签类型,可以同时处理以下两个方面:

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()

注意,我还修复了代码的一些其他部分;最值得注意的是,不应使用通配符导入(from module import *),不应在定义小部件时将其布局在同一行上,并且应尽量避免重复代码。你知道吗

相关问题 更多 >