正确配置tkinter中的加载按钮并正确显示字典中的值

时间:2018-05-25 14:06:20

标签: python python-3.x tkinter

我是编码的新手。可能最多编码3周。我需要一些帮助来正确配置我的加载按钮。在我的程序中,我有一个输入框和按钮,可以自动生成输入框,然后使用该输入框输入字典的值。我想要我的加载按钮要做的是创建适当数量的输入框并为您填写输入框中的文本。到目前为止,它所做的只是填充标签中的字典,这是无用的。

这是我的代码。

from tkinter import *
import tkinter
from math import *
from tkinter.filedialog import askopenfilename
import json
import os

class App:
    def __init__(self,root):
        self.root = root
        self.entry = Entry(self.root)
        self.button = Button(self.root, text="Input number of items in bag", command=self.command)
        self.done = Button(self.root, text="Save File", command=self.save)
        self.load = Button(self.root, text="Load File", command=self.load_data)
        self.save = Button(self.root, text="Save List", command=self.dict)
        self.frame = Frame(self.root)
        self.browsebutton = Button(root, text="Browse", command=self.browsefunc)
        self.entry.pack(side=RIGHT)
        self.button.pack(side=RIGHT) 
        self.save.pack(side=LEFT)
        self.done.pack(side=BOTTOM)
        self.load.pack(side=BOTTOM)
        self.browsebutton.pack(side=BOTTOM)
        self.frame.pack()

        global pathlabel
        pathlabel= Label(self.root)
        pathlabel.pack(side=BOTTOM)

        Label(self.root, text="Enter calculation below:").pack()
        global entry
        entry = Entry(self.root)
        entry.bind("<Return>", self.evaluate)
        entry.pack()
        global res
        res = Label(self.root)
        res.pack()

        global lbl
        lbl = Label(self.root)
        lbl.pack(side=BOTTOM)

        global DND_label
        Label(self.root)
        DND_label = Label(self.root)
        DND_label.pack(side=TOP)


    def command(self):
        self.frame.destroy()
        self.frame = Frame(self.root)
        self.text = []

        for i in range(int(self.entry.get())):
            self.text.append(Entry(self.frame, text="Item " + str(i+1) + ': '))
            self.text[i].pack()
            self.frame.pack()
        lbl.config(text="Enter amount and item name.")


    def dict(self):
        global DND
        DND = {}
        for i in range(len(self.text)):
            DND.update({self.text[i].cget("text"): self.text[i].get()})
        for k, v in DND.items():
            print(v)
        DND_label.configure(text = "Inventory: " + str(DND.values()))

    def save(self):
        DND = {}
        for i in range(len(self.text)):
            DND.update({self.text[i].cget("text"): self.text[i].get()})
        try:
            with open(filename, 'w') as f:
                newpath = os.path.splitext(filename)[0] + "_NEW.txt"
                with open(newpath, 'w') as j:
                    json.dump(DND,j)
                    DND_label.configure(text = "Inventory: " + str(DND.values()))
            for k, v in DND.items():
                print(v)

        except FileNotFoundError:
            try:
                New_dir = os.mkdir(os.path.join(os.path.expanduser('~'), 'Documents', 'DND_player_inventories'))
                filepath = os.path.join(os.path.expanduser('~'), 'Documents', 'DND_player_inventories')
                file = 'DND_inventory.txt'
                newpath = os.path.join(filepath, file)
                with open(newpath, 'w') as j:
                    json.dump(DND,j)
                    DND_label.configure(text = "Inventory: " + str(DND.values()))
                for k, v in DND.items():
                    print(v)

            except FileExistsError:
                try:
                    filepath = os.path.join(os.path.expanduser('~'), 'Documents', 'DND_player_inventories')
                    file = 'DND_inventory.txt'
                    newpath = os.path.join(filepath, file)
                    with open(newpath, 'x') as j:
                        json.dump(DND,j)
                        DND_label.configure(text = "Inventory: " + str(DND.values()))
                    for k, v in DND.items():
                        print(v)

                except FileExistsError:
                    filepath = os.path.join(os.path.expanduser('~'), 'Documents', 'DND_player_inventories')
                    file = 'DND_inventory.txt'
                    file = os.path.join(filepath, file)
                    with open(file, 'r') as f:
                        newpath = os.path.join(filepath, file[0:-4]) + "_NEW.txt"
                        with open(newpath, 'w') as j:
                            json.dump(DND,j)
                            DND_label.configure(text = "Inventory: " + str(DND.values()))
                        for k, v in DND.items():
                            print(v)

        except NameError:
            try:
                New_dir = os.mkdir(os.path.join(os.path.expanduser('~'), 'Documents', 'DND_player_inventories'))
                filepath = os.path.join(os.path.expanduser('~'), 'Documents', 'DND_player_inventories')
                file = 'DND_inventory.txt'
                newpath = os.path.join(filepath, file)
                with open(newpath, 'w') as j:
                    json.dump(DND,j)
                    DND_label.configure(text = "Inventory: " + str(DND.values()))
                for k, v in DND.items():
                    print(v)

            except FileExistsError:
                try:
                    filepath = os.path.join(os.path.expanduser('~'), 'Documents', 'DND_player_inventories')
                    file = 'DND_inventory.txt'
                    newpath = os.path.join(filepath, file)
                    with open(newpath, 'x') as j:
                        json.dump(DND,j)
                        DND_label.configure(text = "Inventory: " + str(DND.values()))
                    for k, v in DND.items():
                        print(v)

                except FileExistsError:
                    filepath = os.path.join(os.path.expanduser('~'), 'Documents', 'DND_player_inventories')
                    file = 'DND_inventory.txt'
                    file = os.path.join(filepath, file)
                    with open(file, 'r') as f:
                        newpath = os.path.join(filepath, file[0:-4]) + "_NEW.txt"
                        with open(newpath, 'w') as j:
                            json.dump(DND,j)
                            DND_label.configure(text = "Inventory: " + str(DND.values()))
                    for k, v in DND.items():
                        print(v)

    def load_data(self):
        with open(filename, 'r') as f:
            try:
                DND = json.load(f)
            except ValueError:
                DND = {}
            for k, v in DND.items():
                DND_label.configure(text = "Inventory: " + str(DND.values()))
                print(v)

    @staticmethod
    def browsefunc():
        global filename
        filename = askopenfilename()
        pathlabel.config(text=filename)

    @staticmethod
    def evaluate(self):
        res.configure(text = "Answer: " + str(eval(entry.get())))



if __name__ == "__main__":
    global root
    root = Tk()
    root.title('DND Player inventories')
    App(root)
    root.mainloop()

这就是我的加载按钮。

    def load_data(self):
        with open(filename, 'r') as f:
            try:
                DND = json.load(f)
            except ValueError:
                DND = {}
            for k, v in DND.items():
                DND_label.configure(text = "Inventory: " + str(DND.values()))
                print(v)

我需要帮助的另一件事是显示字典值而没有额外的措辞。我使用下面的代码显示字典中的内容,它看起来并不好看。

DND_label.configure(text = "Inventory: " + str(DND.values()))

示例字典,将其保存在文本文件中并浏览到它以加载它。文本文件的名称并不重要。

{"Item 1: ": "test", "Item 2: ": "test 1", "Item 3: ": "test 3", "Item 4: ": "test 4"}

我正在使用tkinter作为gui。这只是一个帮助我学习的项目。深入了解如何以及为什么会非常感激。我确信有更简单的方法来编码,但这对我来说是可以理解的,因为我正在学习。

1 个答案:

答案 0 :(得分:0)

忽略我在代码中看到的所有其他问题,这是一个简单的MCVE示例,说明如何将文件中的字典加载到程序中,并将值放在输入字段中。

在制定未来问题时请使用我的下面示例,因为以下示例显示Minimal, Complete, and Verifiable example。至少可以重现与您的问题相关的问题或行为。如您所见,我不包括标题或其他与特定问题无关的其他函数或变量。

我的示例将使用几个类属性来保存字典并保存用于创建不同字段的列表。

我以这种方式使用列表,因为我可以轻松获取索引信息,并使用它以编程方式在正确的行和列中生成正确的标签和输入字段。

通过生成此列表,我们还可以使用它来存储新值并将它们保存到文件中,但如果您无法解决这个问题,那么这是另一个问题的答案。

这是我的示例词典:

{"Age":"30", "Name":"Mike", "Job":"Network Engineer"}

这是我的代码: 请记住,您需要使用自己的字典文件文件路径。

import tkinter as tk
import json


class App(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.button_frame = tk.Frame(self)
        self.button_frame.grid(row=0, column=0)
        self.data_frame = tk.Frame(self)
        self.data_frame.grid(row=0, column=2)
        self.loaded_dict = {}
        self.data_list = []

        tk.Button(self.button_frame, text="Load dictionary data",
                  command=self.load_dict).grid(row=0, column=0)

    def load_dict(self):
        self.loaded_dict = {}
        with open(".path/to/dict_file.txt", "r") as f:
            self.loaded_dict = json.load(f)
        if self.loaded_dict != {}:
            for key, value in self.loaded_dict.items():
                self.data_list.append([tk.Label(self.data_frame, text=key), tk.Entry(self.data_frame), value])
            for ndex, item in enumerate(self.data_list):
                item[0].grid(row=ndex, column=0)
                item[1].grid(row=ndex, column=1)
                item[1].insert(0, item[2])

if __name__ == "__main__":
    root = App()
    root.mainloop()

结果:

在按下按钮之前:

enter image description here

后:

enter image description here

现在这个例子非常基本,人们可以做更多的工作来管理框架的格式化和重置以加载其他东西,但是这个例子是在你要求的庄园中加载字典的最基本方法。

更新

要在下面的评论中回答您的问题,我们可以通过更改for循环的内容来仅加载标签的值。在for循环中,我们检查字典中每个键/值对的键和键值,然后使用该信息执行某些操作。我们需要做的就是告诉你的标签文本是该对的value部分。

改变这个:

for key, value in self.loaded_dict.items():
                    self.data_list.append([tk.Label(self.data_frame, text=key), tk.Entry(self.data_frame), value])
                for ndex, item in enumerate(self.data_list):
                    item[0].grid(row=ndex, column=0)
                    item[1].grid(row=ndex, column=1)
                    item[1].insert(0, item[2])

对此:

for key, value in self.loaded_dict.items():
                self.data_list.append([tk.Label(self.data_frame, text=value), tk.Entry(self.data_frame), value])
            for ndex, item in enumerate(self.data_list):
                item[0].grid(row=ndex, column=0)
                item[1].grid(row=ndex, column=1)

结果:

enter image description here

如前所述,这只是一个简单的例子。在掌握了基础知识后,您可以担心格式化等问题。