类型错误:“StringVar”对象不可调用

罗图阿

我一直在努力阅读一本关于学习使用 tkinter 和使用 Python 创建 GUI 的书。预定链接

我已经到了第 3 章,到目前为止还不错。我已经阅读了这一章,并重新开始研究代码并重建他们的应用程序。据我所知,我已经逐字复制了所有代码,但是当我运行代码时,出现以下错误

self.input = input_class(self, **input_args) TypeError: 'StringVar' object is not callable

我用谷歌搜索了错误,它似乎与语法错误有关,或者在某些时候只是变量名称不匹配。我已经看了好几次我写的东西,开始觉得我只见树木不见森林。我看不出我写的代码和我从书中复制的代码有什么不同,也看不出任何不应该工作的原因。

python GUI TypeError:'str'对象不可调用

https://errorcodespro.com/typeerror-list-object-is-not-callable/

我已经下载了本书附带的示例文件,并且运行良好(虽然它似乎已经更新了一些,因为它与本书的部分不同,但错误消息突出显示的部分似乎是相同的.)

我写的代码如下(如果有人有这本书,会有细微的差异,因为我没有填写所有表单元素,因为它只是重复将小部件放入表单中,我不明白为什么不包括它们会导致错误例如 'self.inputs['Date'] = LabelInput(recordinfo, "Date", input_var=tk.StringVar()) self.inputs['Date'].grid(row=0, column=0)':

我已经用 >>>>>>>code here<<<<<<<<<< 突出显示了明显导致错误的那一行,以防有人认为这是问题所在,我只是想为您突出显示它.

from datetime import datetime
import os
import csv
import tkinter as tk
from tkinter import ttk

class LabelInput (tk.Frame):

def __init__(self, parent, label='', input_class=ttk.Entry, input_var=None, input_args=None, label_args=None, **kwargs):
    super().__init__(parent, **kwargs)
    input_args = input_args or {}
    label_args = label_args or {}
    self.variable = input_var

    if input_class in (ttk.Checkbutton, ttk.Button, ttk.Radiobutton):
        input_args["text"] = label
        input_args["variable"] = input_var
    else:
        self.label = ttk.Label(self, text=label, **label_args)
        self.label.grid(row=0, column=0, sticky=(tk.W + tk.E))
        input_args["textvariable"] = input_var

    >>>>>>>self.input = input_class(self, **input_args)<<<<<<<<<<<<
    self.input.grid(row=1, column=0, sticky=(tk.W + tk.E))
    self.columnconfigure(0, weight=1)

def grid(self, sticky=(tk.E + tk.W), **kwargs):
    super().grid(sticky=sticky, **kwargs)

def get(self):
    try:
        if self.variable:
            return self.variable.get()
        elif type(self.input) == tk.Text:
            return self.input.get('1.0', tk.END)
        else:
            return self.input.get()
    except (TypeError, tk.TclError):
        return ''

def set(self, value, *args, **kwargs):
    if type(self.variable) == tk.BooleanVar:
        self.variable.set(bool(value))
    elif self.variable:
        self.variable.set(value, *args, **kwargs)
    elif type(self.input) in (ttk.Checkbutton, ttk.Radiobutton):
        if value:
            self.input.select()
        else:
            self.input.deselect()
    elif type(self.input) == tk.Text:
        self.input.delete('1.0', tk.END)
        self.input.insert('1.0', value)
    else:
        self.input.delete(0, tk.END)
        self.input.insert(0, value)

class DataRecordForm(tk.Frame):

def __init__(self, parent, *args, **kwargs):
    super().__init__(parent, *args, **kwargs)

    self.inputs = {}

    recordinfo = tk.LabelFrame(self, text="Record Information")

    self.inputs['Date'] = LabelInput(recordinfo, "Date", input_var=tk.StringVar())
    self.inputs['Date'].grid(row=0, column=0)

    self.inputs['Time'] = LabelInput (recordinfo, "Time", input_class=ttk.Combobox, input_var=tk.StringVar(), input_args={"values": ["8:00", "12:00", "16:00", "20:00"]})
    self.inputs['Time'].grid(row=0, column=1)

    self.inputs['Technician'] = LabelInput (recordinfo, "Technician", input_class=tk.StringVar())
    self.inputs['Technician'].grid(row=0, column=2)

    self.inputs['Lab'] = LabelInput(recordinfo, "Lab", input_class=ttk.Combobox, input_var=tk.StingVar(), input_args = {"values": ["A", "B", "C"]})
    self.inputs['Labs'].grid(row=1, column=0)

    environmentinfo = tk.LabelFrame(self, text="Enivronment Information")

    self.inputs['Humidity'] = LabelInput(environmentinfo, "Humidity (g/m3)", input_class=tk.Spinbox, input_var=tk.DoubleVar(), input_args={"from_": 0.5, "to": 52.0, "increment": .01})
    self.inputs['Humidity'].grid(row=0, column=0)

    self.inputs['Equipment Fault'] = LabelInput(environmentinfo, "Equipment Fault", input_class=ttk.Checkbutton, input_var=tk.BooleanVar())
    self.inputs['Equipment Fault'].grid(row=1, column=0, columnspan=3)

    self.inputs['Notes'] = LabelInput(self, "Notes", input_class=tk.Text, input_args={"width": 75, "height": 10})
    self.inputs['Notes'].grid(sticky="w", row=3, column=0)

def get(self):
    data = {}
    for key, widget in self.inputs.items():
        data[key] = widget.get()
    return data

def reset(self):
    for widget in self.inputs.values():
        widget.set('')

class Application(tk.Tk):
""" ROOT WINDOW """
def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.title("Data Entry")
    self.resizable(width=False, height=False)

    ttk.Label(self, text="Data Entry", font=("TkDefaultFont", 16)).grid(row=0)

    self.recordform = DataRecordForm(self)
    self.recordform.grid(row=1, padx=10)

    self.savebutton = ttk.Button(self, text="Save", command=self.on_save)
    self.savebutton.grid(sticky=tk.E, row=2, padx=10)

    self.status = tk.StringVar()
    self.statusbar = ttk.Label(self, textvariable=self.status)
    self.statusbar.grid(sticky=tk.W + tk.E, row=3, padx=10)

    def on_save(self):
        datestring = datetime.today().strftime("%Y-%m-%d")
        filename = "Data Entry_{}.csv".format(datestring)
        newfile = not os.path.exists(filename)

        data = self.recordform.get()

        with open(filename, 'a') as fh:
            csvwriter = csv.DictWriter(fh, fieldnames=data.keys())
            if newfile:
                csvwriter.writeheader()
            csvwriter.writerow(data)

if __name__ == "__main__":
app = Application()
app.mainloop()

以下是我下载的随本书提供的示例代码。如上所述,它似乎已经更新,但对我来说有问题的部分似乎是相同的。

from datetime import datetime
import os
import csv
import tkinter as tk
from tkinter import ttk`


class LabelInput(tk.Frame):
"""A widget containing a label and input together."""

def __init__(self, parent, label='', input_class=ttk.Entry,
             input_var=None, input_args=None, label_args=None,
             **kwargs):
    super().__init__(parent, **kwargs)
    input_args = input_args or {}
    label_args = label_args or {}
    self.variable = input_var

    if input_class in (ttk.Checkbutton, ttk.Button, ttk.Radiobutton):
        input_args["text"] = label
        input_args["variable"] = input_var
    else:
        self.label = ttk.Label(self, text=label, **label_args)
        self.label.grid(row=0, column=0, sticky=(tk.W + tk.E))
        input_args["textvariable"] = input_var

    self.input = input_class(self, **input_args)
    self.input.grid(row=1, column=0, sticky=(tk.W + tk.E))
    self.columnconfigure(0, weight=1)

def grid(self, sticky=(tk.E + tk.W), **kwargs):
    super().grid(sticky=sticky, **kwargs)

def get(self):
    if self.variable:
        return self.variable.get()
    elif type(self.input) == tk.Text:
        return self.input.get('1.0', tk.END)
    else:
        return self.input.get()

def set(self, value, *args, **kwargs):
    if type(self.variable) == tk.BooleanVar:
            self.variable.set(bool(value))
    elif self.variable:
            self.variable.set(value, *args, **kwargs)
    elif type(self.input).__name__.endswith('button'):
        if value:
            self.input.select()
        else:
            self.input.deselect()
    elif type(self.input) == tk.Text:
        self.input.delete('1.0', tk.END)
        self.input.insert('1.0', value)
    else:
        self.input.delete(0, tk.END)
        self.input.insert(0, value)


class DataRecordForm(tk.Frame):
"""The input form for our widgets"""

def __init__(self, parent, *args, **kwargs):
    super().__init__(parent, *args, **kwargs)
    # A dict to keep track of input widgets
    self.inputs = {}

    # Build the form
    # recordinfo section
    recordinfo = tk.LabelFrame(self, text="Record Information")

    # line 1
    self.inputs['Date'] = LabelInput(
        recordinfo, "Date",
        input_var=tk.StringVar()
    )
    self.inputs['Date'].grid(row=0, column=0)
    self.inputs['Time'] = LabelInput(
        recordinfo, "Time",
        input_class=ttk.Combobox,
        input_var=tk.StringVar(),
        input_args={"values": ["8:00", "12:00", "16:00", "20:00"]}
    )
    self.inputs['Time'].grid(row=0, column=1)
    self.inputs['Technician'] = LabelInput(
        recordinfo, "Technician",
        input_var=tk.StringVar()
    )
    self.inputs['Technician'].grid(row=0, column=2)

    # line 2
    self.inputs['Lab'] = LabelInput(
        recordinfo, "Lab",
        input_class=ttk.Combobox,
        input_var=tk.StringVar(),
        input_args={"values": ["A", "B", "C", "D", "E"]}
    )
    self.inputs['Lab'].grid(row=1, column=0)
    self.inputs['Plot'] = LabelInput(
        recordinfo, "Plot",
        input_class=ttk.Combobox,
        input_var=tk.IntVar(),
        input_args={"values": list(range(1, 21))}
    )
    self.inputs['Plot'].grid(row=1, column=1)
    self.inputs['Seed sample'] = LabelInput(
        recordinfo, "Seed sample",
        input_var=tk.StringVar()
    )
    self.inputs['Seed sample'].grid(row=1, column=2)

    recordinfo.grid(row=0, column=0, sticky=(tk.W + tk.E))

    # Environment Data
    environmentinfo = tk.LabelFrame(self, text="Environment Data")
    self.inputs['Humidity'] = LabelInput(
        environmentinfo, "Humidity (g/m³)",
        input_class=tk.Spinbox,
        input_var=tk.DoubleVar(),
        input_args={"from_": 0.5, "to": 52.0, "increment": .01}
    )
    self.inputs['Humidity'].grid(row=0, column=0)
    self.inputs['Light'] = LabelInput(
        environmentinfo, "Light (klx)",
        input_class=tk.Spinbox,
        input_var=tk.DoubleVar(),
        input_args={"from_": 0, "to": 100, "increment": .01}
    )
    self.inputs['Light'].grid(row=0, column=1)
    self.inputs['Temperature'] = LabelInput(
        environmentinfo, "Tenmperature (°C)",
        input_class=tk.Spinbox,
        input_var=tk.DoubleVar(),
        input_args={"from_": 4, "to": 40, "increment": .01}
    )
    self.inputs['Temperature'].grid(row=0, column=2)
    self.inputs['Equipment Fault'] = LabelInput(
        environmentinfo, "Equipment Fault",
        input_class=ttk.Checkbutton,
        input_var=tk.BooleanVar()
    )
    self.inputs['Equipment Fault'].grid(row=1, column=0, columnspan=3)
    environmentinfo.grid(row=1, column=0, sticky=(tk.W + tk.E))

    # Plant Data section
    plantinfo = tk.LabelFrame(self, text="Plant Data")

    self.inputs['Plants'] = LabelInput(
        plantinfo, "Plants",
        input_class=tk.Spinbox,
        input_var=tk.IntVar(),
        input_args={"from_": 0, "to": 20}
    )
    self.inputs['Plants'].grid(row=0, column=0)
    self.inputs['Blossoms'] = LabelInput(
        plantinfo, "Blossoms",
        input_class=tk.Spinbox,
        input_var=tk.IntVar(),
        input_args={"from_": 0, "to": 1000}
    )
    self.inputs['Blossoms'].grid(row=0, column=1)
    self.inputs['Fruit'] = LabelInput(
        plantinfo, "Fruit",
        input_class=tk.Spinbox,
        input_var=tk.IntVar(),
        input_args={"from_": 0, "to": 1000}
    )
    self.inputs['Fruit'].grid(row=0, column=2)

    # Height data
    self.inputs['Min Height'] = LabelInput(
        plantinfo, "Min Height (cm)",
        input_class=tk.Spinbox,
        input_var=tk.DoubleVar(),
        input_args={"from_": 0, "to": 1000, "increment": .01}
    )
    self.inputs['Min Height'].grid(row=1, column=0)
    self.inputs['Max Height'] = LabelInput(
        plantinfo, "Max Height (cm)",
        input_class=tk.Spinbox,
        input_var=tk.DoubleVar(),
        input_args={"from_": 0, "to": 1000, "increment": .01}
    )
    self.inputs['Max Height'].grid(row=1, column=1)
    self.inputs['Median Height'] = LabelInput(
        plantinfo, "Median Height (cm)",
        input_class=tk.Spinbox,
        input_var=tk.DoubleVar(),
        input_args={"from_": 0, "to": 1000, "increment": .01}
    )
    self.inputs['Median Height'].grid(row=1, column=2)

    plantinfo.grid(row=2, column=0, sticky=(tk.W + tk.E))

    # Notes section
    self.inputs['Notes'] = LabelInput(
        self, "Notes",
        input_class=tk.Text,
        input_args={"width": 75, "height": 10}
    )
    self.inputs['Notes'].grid(sticky=tk.W, row=3, column=0)

    # default the form
    self.reset()

def get(self):
    """Retrieve data from form as a dict"""

    # We need to retrieve the data from Tkinter variables
    # and place it in regular Python objects

    data = {}
    for key, widget in self.inputs.items():
        data[key] = widget.get()
    return data

def reset(self):
    """Resets the form entries"""

    # clear all values
    for widget in self.inputs.values():
        widget.set('')


class Application(tk.Tk):
"""Application root window"""

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

    self.title("ABQ Data Entry Application")
    self.resizable(width=False, height=False)

    ttk.Label(
        self,
        text="ABQ Data Entry Application",
        font=("TkDefaultFont", 16)
    ).grid(row=0)

    self.recordform = DataRecordForm(self)
    self.recordform.grid(row=1, padx=10)

    self.savebutton = ttk.Button(self, text="Save", command=self.on_save)
    self.savebutton.grid(sticky=tk.E, row=2, padx=10)

    # status bar
    self.status = tk.StringVar()
    self.statusbar = ttk.Label(self, textvariable=self.status)
    self.statusbar.grid(sticky=(tk.W + tk.E), row=3, padx=10)

    self.records_saved = 0

def on_save(self):
    """Handles save button clicks"""

    # For now, we save to a hardcoded filename with a datestring.
    # If it doesnt' exist, create it,
    # otherwise just append to the existing file
    datestring = datetime.today().strftime("%Y-%m-%d")
    filename = "abq_data_record_{}.csv".format(datestring)
    newfile = not os.path.exists(filename)

    data = self.recordform.get()

    with open(filename, 'a') as fh:
        csvwriter = csv.DictWriter(fh, fieldnames=data.keys())
        if newfile:
            csvwriter.writeheader()
        csvwriter.writerow(data)

    self.records_saved += 1
    self.status.set(
        "{} records saved this session".format(self.records_saved))
    self.recordform.reset()


if __name__ == "__main__":

app = Application()
app.mainloop()

此代码有效,但我无法弄清楚使此版本有效而​​我的失败的区别是什么。

无花果梁

DataRecordForm__init__()函数中,您正在创建许多LabelInput实例。在其他人中:

self.inputs['Technician'] = LabelInput (recordinfo, "Technician", input_class=tk.StringVar())

此调用将input_class参数作为传递tk.StringVar()

据我了解,您应该将其作为input_var而不是input_class. 这似乎也是唯一出现此错误的行。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

类型错误“类”对象不可调用

类型错误:“Vocab”对象不可调用

类型错误:“ShiftSerializer”对象不可调用

类型错误:Int对象不可调用

类型错误:“布尔”对象不可调用

类型错误:“条目”对象不可调用

类型错误:“球”对象不可调用?

类型错误:“IndicesClient”对象不可调用

类型错误:“WebElement”对象不可调用

类型错误:int 对象不可调用

硒错误“类型错误:‘str’对象不可调用”

错误类型错误:“str”对象不可调用

类型错误:“模块”对象不可调用 - pygsp 模块不可调用

此错误的任何解决方法---> TypeError:“ StringVar”对象不可调用

澄清类型错误:“str”对象不可调用

类型错误:“int”对象不可调用 colab 研究

matplotlib图例类型错误:“列表”对象不可调用

底图类型错误:“模块”对象不可调用

如何处理不可调用的对象类型的错误

类型错误:“模块”对象在 Keras 中不可调用 Tensorboard

类型错误:“列表”对象不可调用,sys.argv()

类型错误:“DataFrame”对象不可调用 - 触发数据框

在Keras中合并,类型错误:模块对象不可调用?

Mechanicalsoup 类型错误:“模块”对象不可调用

类型错误:'bool' 对象在 Pygame 中不可调用

进度条 - 类型错误:“模块”对象不可调用

类型错误:“str”对象不可调用 1

获取类型错误:“模块”对象不可调用

模型拟合/类型错误:“ NoneType”对象不可调用