【问题标题】:Both buttons opens same table in csv problem?两个按钮在 csv 问题中打开同一张表?
【发布时间】:2020-05-26 10:15:14
【问题描述】:

这是两个按钮

second_year_icon = tk.PhotoImage(file = r"D:\Academy Management Application\Icons\2nd_year_icon.png")
global second_year_btn
second_year_btn = tk.Button(label_frame, font=LARGE_FONT, image=second_year_icon,
                      border=0 ,command=lambda : controller.show_frame(second_year) )
second_year_btn.grid(row=0 , column =0, padx=(10,10) , pady=(10,0), sticky=tk.E)


first_year_icon=tk.PhotoImage(file = r"D:\Academy Management 
Application\Icons\1st_year_icon.png")

        global first_year_btn
        first_year_btn = tk.Button(label_frame, font=LARGE_FONT, image=first_year_icon
                            , command=lambda : controller.show_frame(second_year), border=0 )
        first_year_btn.grid(row=0 , column =1, padx=(10,10) , pady=(10,0), sticky=tk.E)

现在如果单击 first_year_btn,当我单击 second_year_btn 时它也会显示相同的数据。我知道我犯了一些愚蠢的错误,但不知道是哪一个。我很几十。有谁能帮帮我吗?

reader = DictReader(f, delimiter=',')
    for row in reader:
        if first_year_btn:
            if row['Class Name'] == '09th':
                registration_no= row['Registration No']
                student_name = row['Student Name']
                f_name = row['Father Name']
                gender = row['Gender']
                class_name =row['Class Name']
                class_session =row['Class Session']
                admission_date =row['Admission Date']
                monthly_fee = row['Monthly Fee']
                dues_payment=row['Dues']
                tree.insert("", 0, values=(registration_no, student_name, f_name,gender,class_name,class_session,admission_date,monthly_fee,dues_payment))
        elif  second_year_btn :

            if row['Class Name'] == 'Second Year':
                registration_no = row['Registration No']
                student_name = row['Student Name']
                f_name = row['Father Name']
                gender = row['Gender']
                class_name = row['Class Name']
                class_session = row['Class Session']
                admission_date = row['Admission Date']
                monthly_fee = row['Monthly Fee']
                dues_payment = row['Dues']
                tree.insert("", 0, values=(
                registration_no, student_name, f_name, gender, class_name, class_session, admission_date,
                monthly_fee, dues_payment))

【问题讨论】:

  • first_year_btn 应该是 command=lambda: controller.show_frame(first_year) 吗?
  • class second_year(tk.Frame):我正在使用类方法,所以它会打开另一个框架,在那个框架中我正在打开一个表
  • 我可以选择为每个按钮创建类,但它不会遵循 DRY 代码,我想为单个类中的两个按钮创建功能
  • 那么您的代码如何知道哪个按钮触发了命令?
  • 是的,这就是为什么我在上一个问题中也问过这个问题。我有一个 csv 文件。我想从那个 csv 文件中读取数据,我正在使用类方法,在第一类中我创建了按钮,现在在第二类中,我想根据将被单击的按钮显示数据,我非常满意。因为不知道该怎么做

标签: python python-3.x csv tkinter tk


【解决方案1】:

以下是基于您发布的代码的简单示例:

import tkinter as tk
from tkinter import ttk
from csv import DictReader

class App(tk.Tk):
  def __init__(self):
    super().__init__()

    mainframe = tk.Frame(self)
    mainframe.pack(fill=tk.BOTH, expand=1)

    mainframe.rowconfigure(0, weight=1)
    mainframe.columnconfigure(0, weight=1)

    self.frames = {}
    for f in (main_page, second_year):
      frame = f(mainframe, self)
      frame.grid(row=0, column=0, sticky='nsew')
      self.frames[f] = frame
    self.show_frame(main_page)

  def show_frame(self, fclass):
      frame = self.frames[fclass]
      frame.tkraise()
      return frame

class main_page(tk.Frame):
  def __init__(self, parent, controller):
    super().__init__(parent)
    self.controller = controller

    label_frame = tk.Frame(self)
    label_frame.pack(fill=tk.BOTH, expand=1)

    first_year_button = tk.Button(label_frame, text='First Year',
                                  width=20, command=lambda: self.select_year(1))
    first_year_button.grid(row=0, column=0, padx=10, pady=(10,0))

    second_year_button = tk.Button(label_frame, text='Second Year',
                                   width=20, command=lambda: self.select_year(2))
    second_year_button.grid(row=0, column=1, padx=10, pady=(10,0))

  def select_year(self, year):
    frame = self.controller.show_frame(second_year)
    frame.set_year(year)

class second_year(tk.Frame):
  def __init__(self, parent, controller):
    super().__init__(parent)

    columns = ('Reg #', 'Student Name', 'Father Name', 'Gender',
               'Class', 'Session', 'Admin. Fee', 'Monthly Fee', 'Dues')
    self.tree = ttk.Treeview(self, show='headings', columns=columns)
    self.tree.pack(fill=tk.BOTH, expand=1)

    for col in columns:
      self.tree.heading(col, text=col)
      self.tree.column(col, width=100, anchor='c')

  def set_year(self, year):
    if year == 1:
      filter = '09th'
    elif year == 2:
      filter = 'Second Year'
    else:
      filter = None
    if filter:
      with open('registration.csv', newline='') as f:
        reader = DictReader(f, delimiter=',')
        for row in reader:
          if row['Class Name'] == filter:
            registration_no= row['Registration No']
            student_name = row['Student Name']
            f_name = row['Father Name']
            gender = row['Gender']
            class_name = row['Class Name']
            class_session = row['Class Session']
            admission_date = row['Admission Date']
            monthly_fee = row['Monthly Fee']
            dues_payment = row['Dues']
            self.tree.insert('', 0, values=(registration_no, student_name, f_name, gender,
                                            class_name, class_session, admission_date,
                                            monthly_fee, dues_payment))

app = App()
app.mainloop()

【讨论】:

  • 你总是天才,只剩下一个问题,如果我点击后退按钮,它不会从树中删除数据,当我点击另一个数据时,它会在同一棵树中插入数据,这意味着它将数据插入到同一棵树,例如,当我单击第二年按钮时,它插入第二年数据,当我单击后退按钮并插入第一年数据时,它然后插入第一年数据和第二年数据也存在于其中
  • 在打开 registration.csv 文件之前添加 self.tree.delete(*self.tree.get_children())。或者在返回主页之前添加它。
  • 是的,你又是天才,只是我想问的最后一个问题,假设我正在使用一个实际的应用程序,我使用这种方法,每当我点击按钮时,它都会删除数据,然后再次点击它会重新加载所有数据,可以吗?还是有更好的使用方法?
  • 对不起,我没有找到你想要的。
  • 我询问这个​​语句 self.tree.delete(*self.tree.get_children()) ........意味着每次点击后退按钮时都会删除所有数据并插入新数据,这是一个好方法吗?还是有更好的办法?
【解决方案2】:

遵循这种结构,MainFrameClass 是您的旧类,来自 Library 或为您创建旧框架。它有一些在该框架内正在使用的变量。您的任务是创建新类,将旧类继承到新类中。创建新方法,通过该方法您只能更改要在框架内更改的那些变量。

class MainFrameClass:

    def __init__(self, name):
        self.name = name

    def say_hi(self):
        print("Hi, I am " + self.name)

class UpdatedClass(MainFrameClass):

    def show_name(self):
        print("Hi, I am " + self.name)

    def update_name(self,new_name):
        self.name = new_name

x = MainFrameClass("Old Variable Data Coming from Old Class")
y = UpdatedClass("New Variable Data Given to New Class")



y.show_name()
y.update_name('New Variable Data That was Updated Again')
y.show_name()

【讨论】:

  • class second_year(tk.Frame):我正在使用类方法,因此它会打开另一个框架,在该框架中我正在打开一个表格,我可以选择为每个按钮创建类,但它不会跟随干代码,我想为单个类中的两个按钮创建功能
  • 你不想每次打电话给你的班级都打开另一个框架?
  • 是的,是的,我只想在同一个框架中定义按钮功能
  • 好的,类实例controller.show_frame被配置为每次调用都会创建新的frame,不要这样。最好的选择是对 tkinter 使用过程编程,您可以在其中更改一次创建的帧的内容,而不是每次都调用 show_frame。即使您想使用 OOP 的美丽,那么您可能必须继承主类,并对其方法 .show_frame 进行一些更改。最好的选择是程序化,(创建一次框架,然后一次又一次地更改其内容。
  • 我的程序有多个页面,有多个功能,如果我按程序进行,我的代码会混乱,几乎我已经完成了我的一半应用程序,我想遵循 DRY 原则,请如果你可以在这段代码中做到这一点
猜你喜欢
  • 1970-01-01
  • 2021-05-15
  • 2014-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多