首页 > 解决方案 > Tkinter 数据框不保存您添加的内容,不列出最近的和旧的(只是最近的)

问题描述

我正在尝试获取用户输入,但我是 Python 新手。我正在尝试创建一个数据框,在您使用数据框添加人员后,您可以在其中保存项目。出于某种原因,当它被输入时,它看起来像这样:

这是代码结果

import tkinter as tk   
from tkinter import *
from tkinter import ttk             
from tkinter import font  as tkfont 
from tkinter import filedialog
from tkinter.filedialog import asksaveasfilename
import numpy as np
import pandas as pd
import pickle
from tkinter import messagebox

root= tk.Tk()
root.option_add('*Font', 'Calibri 19')
root.geometry("1440x900")
background = PhotoImage(file = "backtotheground.png") 

class My_GUI(tk.Tk):
    def __init__(self, master):
        self.master = master
        self.name = tk.Label(root, text = 'Name')
        self.name_entry=tk.Entry(root)
        self.info = tk.Label(root, text = 'Info')
        self.info_entry=tk.Entry(root)
        self.sub_btn=tk.Button(root,text = 'Add Person', command = self.add_frame)
        self.sub_btn.grid(row=1,column=0)
        self.save_btn=tk.Button(root,text = 'Save', command = self.save_frame)
        self.save_btn.grid(row=1,column=2)
        self.load_btn=tk.Button(root,text = 'Load', command = self.load_frame)
        self.load_btn.grid(row=1,column=5)
        self.delete_btn=tk.Button(root,text = 'Delete Person', command = self.delete_frame, compound=tk.CENTER)
        self.delete_btn.grid(row=100,column=6)

 def add_frame(self): 
        self.name.grid(row=0,column=0)
        self.name_entry.grid(row=0,column=0)
        self.info.grid(row=1,column=0)
        self.info_entry.grid(row=1,column=0)

        self.names=self.name_entry.get()
        self.bio=self.info_entry.get()

        global params
        params = [self.names,self.bio]
        print(params)
        self.a = params

  def save_frame(self):
        self.df = pd.DataFrame(self.a,index=['a','b']) 
        self.df.to_pickle("/Users/stantwiceforbetter/Downloads/Code/barbieworld/biography.pkl") 
        ftypes = [('Pickle File', '.pkl'),
                      ('All files', '*')]
        self.file = asksaveasfilename(filetypes=ftypes,defaultextension='.pkl')
        if self.file:
            self.a.save(self.file)
  def load_frame(self):
        scrollbar = Scrollbar(root)
        scrollbar.grid(row=4,column=3)

        total_rows = len(self.a)
        total_columns = len(self.a[0])
        for i in range(total_rows):
            for j in range(total_columns):
                self.e = Entry(root, width=20, fg='blue',
                               font=('Arial',16,'bold'))
                self.e.grid(row=5, column=j)
                mylist = Listbox(self.e, yscrollcommand = scrollbar.set,exportselection=False)
                mylist.insert(END, self.a[i][j])               
                mylist.grid(row=4,column=2)

    def delete_frame(self):
        scrollbar = Scrollbar(self.master,orient=VERTICAL)
        listbox = Listbox(self.master, yscrollcommand=scrollbar.set, selectmode=MULTIPLE)
        messagebox.showinfo( "Confirmation", "Are you sure you want to delete this person? This action cannot be undone.")
        sel = listbox.curselection()
        for index in sel[::-1]:
            index.delete('1.0', END)
showframe = My_GUI(root)
root.mainloop()

我想确保它显示的选项卡不重叠,更新的人在一个带有个人简介和人名的表格中,并且我希望该表格也包含较旧的输入(除非您删除我想要工作的输入。 )

标签: dataframetkinter

解决方案


好的,我会尽力帮助你解决这个问题,因为你是 Python 新手,因为看到这个让我很伤心。

您在代码中做错了什么,立即导入相同的模块两次。

import tkinter as tk
from tkinter import *

它是同一个模块,除了你*在命名它时都使用它导入所有内容并访问它tkas tk)。这是不好的,没有必要。from tkinter import *是建议的方法tkinter,因此您需要删除代码中的所有 tk 调用(除非您想保留import tkinter as tk然后保留代码中的所有 tk 调用)。

第二 -Tk()应该只创建一次,不应该被多次调用。( root= tk.Tk()& showframe = My_GUI(root).

您有两种选择来解决这个问题 - 1. class My_GUI:2. 完全删除 root 并创建MY_GUI您的Tk实例。

第三 -global是一个很大的禁忌。而且,你在那里使用 global 有什么意义?

第四 - 语法。除非给出函数参数,否则等号两边应该有空格

第五 - 在向 StackOverflow 添加代码时,请确保它在某种程度上处于工作状态。这包括正确的缩进和删除所需的缺失文件(您的背景图像和您的 pkl 文件)

第六 - 现在关于您的外观问题,请检查以下几行 self.sub_btn.grid(row=1,column=0)self.info.grid(row=1,column=0)self.info_entry.grid(row=1,column=0). 您将所有这三个放置在同一个确切的位置。

将网格想象成棋盘,您所做的就是取 3 个棋子并将它们放在同一个正方形上。同样的问题适用于您的姓名字段 -self.name.grid(row=0,column=0)self.name_entry.grid(row=0,column=0).

将它们移动到不同的行和列,而不是在同一个位置,这样看起来会更好。

第七 - 工作永远不会在窗口元素本身中完成,您应该始终添加一个框架并在其之上构建应用程序。

第八 - 建议每行 79 个字符。

import pickle
from tkinter import *
from tkinter import ttk
from tkinter.font import Font
from tkinter import filedialog
from tkinter import messagebox
from tkinter.filedialog import asksaveasfilename

import numpy as np
import pandas as pd


class My_GUI:
    def __init__(self, master):
        self.master = master
        # Main frame to add all the elements into.
        self.mainframe = Frame(self.master)
        self.name = Label(self.mainframe, text='Name')
        self.name_entry = Entry(self.mainframe)
        self.info = Label(self.mainframe, text='Info')
        self.info_entry = Entry(self.mainframe)
        self.sub_btn = Button(self.mainframe, text='Add Person',
                              command=self.add_frame)
        self.save_btn = Button(self.mainframe, text='Save',
                               command=self.save_frame)
        self.load_btn = Button(self.mainframe, text='Load',
                               command=self.load_frame)
        self.delete_btn = Button(self.mainframe, text='Delete Person',
                                 command=self.delete_frame, compound=CENTER)
        self.mainframe.pack(fill=BOTH)
        self.sub_btn.grid(row=1, column=0)
        self.save_btn.grid(row=1, column=2)
        self.load_btn.grid(row=1, column=5)
        self.delete_btn.grid(row=100, column=6)

    def add_frame(self):
        self.name.grid(row=0, column=0)
        self.name_entry.grid(row=0, column=1)
        self.info.grid(row=1, column=0)
        self.info_entry.grid(row=1, column=1)
        self.sub_btn.grid(row=2, column=0, columnspan=2)

        self.names = self.name_entry.get()
        self.bio = self.info_entry.get()

        params = [self.names, self.bio]
        print(params)
        self.a = params

    def save_frame(self):
        self.df = pd.DataFrame(self.a, index=['a','b'])
        self.df.to_pickle("/Users/stantwiceforbetter/Downloads/Code/"
                          "barbieworld/biography.pkl")
        ftypes = [('Pickle File', '.pkl'),
                      ('All files', '*')]
        self.file = asksaveasfilename(filetypes=ftypes,
                                      defaultextension='.pkl')
        if self.file:
            self.a.save(self.file)

    def load_frame(self):
        scrollbar = Scrollbar(self.mainframe)
        scrollbar.grid(row=4, column=3)

        total_rows = len(self.a)
        total_columns = len(self.a[0])
        for i in range(total_rows):
            for j in range(total_columns):
                self.e = Entry(self.mainframe, width=20, fg='blue',
                               font=('Arial', 16, 'bold'))
                self.e.grid(row=5, column=j)
                mylist = Listbox(self.e, yscrollcommand=scrollbar.set,
                                 exportselection=False)
                mylist.insert(END, self.a[i][j])
                mylist.grid(row=4, column=2)

    def delete_frame(self):
        scrollbar = Scrollbar(self.mainframe, orient=VERTICAL)
        listbox = Listbox(self.mainframe, yscrollcommand=scrollbar.set,
                          selectmode=MULTIPLE)
        messagebox.showinfo("Confirmation", "Are you sure you want to delete "
                                            "this person? This action cannot "
                                            "be undone.")
        sel = listbox.curselection()
        for index in sel[::-1]:
            index.delete('1.0', END)


def main():
    root = Tk()
    root.option_add('*Font', 'Calibri 19')
    root.geometry("1440x900")
    showframe = My_GUI(root)
    background = PhotoImage(file="backtotheground.png")
    root.mainloop()


if __name__ == '__main__':
    main()

我几乎没有碰任何我不需要的东西。祝 Python 好运。


推荐阅读