简体   繁体   English

为什么在打印时使用python中的tkinter将输入表示为对象?

[英]why is the input when printed represented as an object using tkinter in python?

I am writing a program that will take skill names as input from text entries and calculate the corresponding value of all of the skills entered. 我正在编写一个程序,该程序将从文本条目中输入技能名称作为输入,并计算输入的所有技能的相应值。 When I enter a skill in the program and then print the skill to the shell it appears as an object? 当我在程序中输入技能然后将技能打印到外壳时,它会显示为对象吗? Why does this happen and how can I fix it, do I need a repr or str ? 为什么会发生这种情况,我该如何解决?是否需要reprstr Why doesn't the delete method to clear the text entry work as well? 为什么删除文本输入的delete方法也不起作用?

import tkinter as tk
from tkinter import ttk

#make the lists to store the skill names
floorEle1Skills = []

class startValue(tk.Tk):

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

        tk.Tk.__init__(self, *args, **kwargs)

        tk.Tk.wm_title(self, "Start Value Calculator")
        tk.Tk.minsize(self, width = 350, height = 300)

        container = tk.Frame(self)
        container.pack(side = 'top', fill = 'both', expand = True)
        container.grid_rowconfigure(0, weight = 1)
        container.grid_columnconfigure(0, weight = 1)

        self.frames = {}

        for f in (startPage, floorPage, pommelPage, ringsPage, vaultPage, pbarsPage, hbarPage):

            frame = f(container, self)

            self.frames[f] = frame

            frame.grid(row = 0, column = 0, sticky = "nsew")

        self.showFrame(startPage)

        #make the lists to store the skill names
        floorEle1Skills = []

    def showFrame(self, cont):

        frame = self.frames[cont]
        frame.tkraise()

    def floorEle1(skill):
        floorEle1Skills.append(skill)
        #clear the text entry
        #ele1Entry.delete(0, tk.END)
        #why doesnt this work???
        #why is it printed as an object??
        print(floorEle1Skills)


class startPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        label = tk.Label(self, text = "Select Event")
        label.pack(pady = 10, padx = 10)

        floorButton = ttk.Button(self, text = "Floor", command = lambda : controller.showFrame(floorPage))
        floorButton.pack()


class floorPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        label = tk.Label(self, text = "Floor")
        label.pack(pady = 10, padx = 10)

        #make the entries and labels
        ele1Label = tk.Label(self, text = "Element Group 1:")
        ele1Label.pack()
        skill1 = tk.StringVar()
        ele1Entry = tk.Entry(self, textvariable = skill1)
        ele1Entry.pack()
        ele1Button = ttk.Button(self, text = "Add", command = lambda : controller.floorEle1())
        ele1Button.pack()

        startButton = ttk.Button(self, text = "Back to Start", command = lambda : controller.showFrame(startPage))
        startButton.pack(side = 'bottom')

Welcome to Python. 欢迎使用Python。 The problem is in the function floorEle1(skill) . 问题出在函数floorEle1(skill) This is a member function of class startValue , but the argument list doesn't begin with self . 这是class startValue的成员函数,但是参数列表并非以self开头。 Python doesn't force you to name the first variable self ; Python不会强迫您命名第一个变量self you can actually name it whatever you want (but don't do it!). 您实际上可以随心所欲地为其命名(但不要这样做!)。 So within this function the variable named skill acts just like the variable self . 因此,在此函数中,名为skill的变量的行为就像变量self It's exactly as if you had written this: 就像您已经写过这样:

def floorEle1(self):
    floorEle1Skills.append(self)
    #clear the text entry
    #ele1Entry.delete(0, tk.END)
    #why doesnt this work???
    #why is it printed as an object??
    print(floorEle1Skills)

I think you can see now that your code, in effect, appends self to floorEle1Skills; 我认为您现在可以看到您的代码实际上将self附加到floorEle1Skills了; ie, you append the instance of your main window! 即,您附加主窗口的实例! So when you print the list, the print statement shows that the list contains an object. 因此,当您打印列表时,print语句显示该列表包含一个对象。

As already mentioned in the another answer the problem with the code turns around the function floorEle1(self, skill) , BUT ... there are also some other issues that should be properly addressed in order to get the entered skills passed to the list of skills (see code below): 正如在另一个答案中已经提到的那样,代码的问题围绕着函数floorEle1(self, skill) ,但是... ...还有一些其他问题应该适当解决,以便将输入的技能传递到列表中。技能(请参见下面的代码):

import tkinter as tk
from tkinter import ttk

#make the lists to store the skill names
# floorEle1Skills = []

class startValue(tk.Tk):

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

        tk.Tk.__init__(self, *args, **kwargs)

        tk.Tk.wm_title(self, "Start Value Calculator")
        tk.Tk.minsize(self, width = 350, height = 300)

        container = tk.Frame(self)
        container.pack(side = 'top', fill = 'both', expand = True)
        container.grid_rowconfigure(0, weight = 1)
        container.grid_columnconfigure(0, weight = 1)

        self.frames = {}

        for f in (startPage, floorPage): # , pommelPage, ringsPage, vaultPage, pbarsPage, hbarPage):

            frame = f(container, self)

            self.frames[f] = frame

            frame.grid(row = 0, column = 0, sticky = "nsew")

        self.showFrame(startPage)

        #make the lists to store the skill names
        self.floorEle1Skills = []

    def showFrame(self, cont):

        self.floorEle1Skills = []
        frame = self.frames[cont]
        frame.tkraise()

    def floorEle1(self, skill):
        print("#", skill.get())
        self.floorEle1Skills.append(skill)
        #clear the text entry
        #ele1Entry.delete(0, tk.END)
        #why doesnt this work???
        #why is it printed as an object??
        for item in self.floorEle1Skills:
            print("##",item.get())


class startPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        label = tk.Label(self, text = "Select Event")
        label.pack(pady = 10, padx = 10)

        floorButton = ttk.Button(self, text = "Floor", command = lambda : controller.showFrame(floorPage))
        floorButton.pack()


class floorPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        label = tk.Label(self, text = "Floor")
        label.pack(pady = 10, padx = 10)

        #make the entries and labels
        ele1Label = tk.Label(self, text = "Element Group 1:")
        ele1Label.pack()
        skill1 = tk.StringVar()
        ele1Entry = tk.Entry(self, textvariable = skill1)
        ele1Entry.pack()
        ele1Button = ttk.Button(self, text = "Add", command = lambda : controller.floorEle1(ele1Entry))
        ele1Button.pack()

        startButton = ttk.Button(self, text = "Back to Start", command = lambda : controller.showFrame(startPage))
        startButton.pack(side = 'bottom')

root = tk.Tk()
my_gui = startValue()
root.mainloop()

Other changes in the code are: 代码中的其他更改包括:

definition of self.floorEle1Skills = [] in the '__ init __()' function and passing the appropriate parameter to controller.floorEle1(ele1Entry) so that the input string value is passed to the function handling the button push. 在'__ init __()'函数中定义self.floorEle1Skills = [] ,并将适当的参数传递给controller.floorEle1(ele1Entry)以便将输入字符串值传递给处理按钮按下的函数。

The above code prints the user input to the terminal (twice, first from the passed user input, second all items in the list). 上面的代码将用户输入打印到终端(两次,首先是从传递的用户输入开始,其次是列表中的所有项目)。

Placing self.floorEle1Skills = [] line in showFrame() resets the list collecting the input of skills (making restart of input possible). self.floorEle1Skills = []行放在showFrame()重置收集技能输入的列表(使输入可能重新启动)。

The code above solves both issues addressed in the question, but this doesn't mean that there are not further issues needing to be solved. 上面的代码解决了问题中解决的两个问题,但这并不意味着没有其他问题需要解决。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM