You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Tkinter分期付款功能支付完成后对应按钮无法即时删除问题求助

解决方案

修改思路

你遇到的问题本质是数据库数据更新后没有同步更新界面控件:分期按钮是首次打开分期窗口时一次性生成的,后续删除数据库记录不会自动触发界面按钮销毁,只需要补充按钮映射存储和同步销毁逻辑即可。

具体修改步骤

1. 新增按钮存储映射

在类的初始化方法中新增字典,用来存储每个分期描述对应的按钮实例,方便后续快速查找销毁:

def __init__(self, master):
    self.lista_opisa_rata = list()
    self.rata_buttons = dict() # 新增这行,key为分期描述,value为对应按钮控件
    # 剩余原有初始化代码保持不变

2. 优化分期窗口加载逻辑,避免重复生成按钮

修改otplata_na_rate_deiconify方法,每次打开窗口时先清空历史的按钮和数据,避免重复生成:

def otplata_na_rate_deiconify(self):
    # 新增:清空历史数据和旧按钮
    self.lista_opisa_rata.clear()
    for btn in self.rata_buttons.values():
        btn.destroy()
    self.rata_buttons.clear()

    # 以下是原有逻辑,仅需在生成按钮处新增存储逻辑
    self.master.withdraw()
    self.onr_top.deiconify()
    # ... 中间原有布局代码保持不变 ...

    c.execute('SELECT Opis FROM OTPLATA_NA_RATE')
    for opis in c:
        self.lista_opisa_rata.append(opis[0])
    column = 0
    row = 1
    for opis in self.lista_opisa_rata:
        function = lambda x=opis: self.get_description(x)
        rata_button = Button(self.onr_top, text=opis, width=10, command=function)
        rata_button.grid(row=row, column=column, padx=5, pady=5)
        self.rata_buttons[opis] = rata_button # 新增这行,把按钮存到字典里
        column += 1
        if column == 3:
            row += 1
            column = 0
    # ... 剩余原有代码保持不变 ...

3. 支付最后一期时同步销毁按钮

修改pay_selected方法,删除数据库记录后同步销毁界面上的对应按钮,同时清空右侧的分期展示信息:

def pay_selected(self):
    p_description = self.onr_oznacena_rata_txt.cget("text")
    num_of_installments = self.onr_broj_rata_txt.cget("text").split("/")
    if int(num_of_installments[0])+1 >= int(num_of_installments[1]):
        c.execute('DELETE FROM OTPLATA_NA_RATE WHERE Opis = ?', (p_description,))
        conn.commit()
        # 新增以下逻辑:销毁对应按钮+清空展示信息
        if p_description in self.rata_buttons:
            self.rata_buttons[p_description].destroy()
            del self.rata_buttons[p_description]
            self.lista_opisa_rata.remove(p_description)
            # 清空右侧展示内容
            self.onr_oznacena_rata_txt.config(text="")
            self.onr_broj_rata_txt.config(text="")
            self.onr_iznos_rate_txt.config(text="")
            self.onr_datum_isplate_txt.config(text="")
    else:
        target_3_novo = str(int(num_of_installments[0])+1) + "/" + num_of_installments[1]
        c.execute('UPDATE OTPLATA_NA_RATE SET Broj_rata = ? WHERE Opis = ?', (target_3_novo, p_description,))
        conn.commit()
        self.get_description(p_description)

完整修改后代码

from tkinter import *
import sqlite3

conn = sqlite3.connect('Financije.db')
c = conn.cursor()

c.execute('''CREATE TABLE IF NOT EXISTS PRIMANJA
             ([ID] INTEGER PRIMARY KEY,[Opis] text, [Iznos] integer, [Datum] text)''')

c.execute('''CREATE TABLE IF NOT EXISTS OTPLATA_NA_RATE
             ([ID] INTEGER PRIMARY KEY,[Opis] text, [Iznos_rate] integer, [Broj_rata] text, [Datum_kupnje] text)''')

c.execute('''CREATE TABLE IF NOT EXISTS SKIDANJE_S_RAČUNA
             ([ID] INTEGER PRIMARY KEY,[Opis] text, [Iznos] integer, [Date] text)''')

c.execute('''CREATE TABLE IF NOT EXISTS KASICA
             ([ID] INTEGER PRIMARY KEY, [Stanje_računa] integer)''')

c.execute('SELECT * FROM KASICA')
check = c.fetchone()
if check is None:
    c.execute('INSERT INTO KASICA VALUES (?, ?);', (None, 0.0))
c.execute('SELECT * FROM OTPLATA_NA_RATE')
check = c.fetchone()
if check is None:
    c.execute('INSERT INTO OTPLATA_NA_RATE VALUES (?, ?, ?, ?, ?);', (None, "Test1", 600, "0/2", "12/08/2021"))
    c.execute('INSERT INTO OTPLATA_NA_RATE VALUES (?, ?, ?, ?, ?);', (None, "Test2", 600, "0/3", "12/08/2021"))
    c.execute('INSERT INTO OTPLATA_NA_RATE VALUES (?, ?, ?, ?, ?);', (None, "Test3", 600, "0/4", "12/08/2021"))
    c.execute('INSERT INTO OTPLATA_NA_RATE VALUES (?, ?, ?, ?, ?);', (None, "Test4", 600, "0/5", "12/08/2021"))
    c.execute('INSERT INTO OTPLATA_NA_RATE VALUES (?, ?, ?, ?, ?);', (None, "Test5", 600, "0/6", "12/08/2021"))
# Save (commit) the changes
conn.commit()


class FinancialCalc:
    def __init__(self, master):
        self.lista_opisa_rata = list()
        self.rata_buttons = dict()

        # Start screen define:
        self.master = master
        self.master.title("Test")
        self.master.geometry("300x300")
        self.master.resizable(False, False)

        self.otplata_na_rate_button = Button(master, text="payment in installments",
                                             command=self.otplata_na_rate_deiconify)
        self.otplata_na_rate_button.place(x=95, y=155)

        #   Otplata_na_rate TopLevel - definiranje
        self.onr_top = Toplevel()
        self.onr_top.withdraw()
        self.onr_top.protocol("WM_DELETE_WINDOW", lambda: (self.master.deiconify(), self.onr_top.withdraw()))
        self.onr_top.title("Test")
        self.onr_label = Label(self.onr_top, text="List of payments:", font=("Helvetica", 11, "underline", "bold"))
        self.onr_opis_label = Label(self.onr_top, text="Payment description:", font=("Helvetica", 11, "underline", "bold"))
        self.onr_oznacena_rata_label = Label(self.onr_top, text="Installment description:", font=("Helvetica", 11))
        self.onr_broj_rata_label = Label(self.onr_top, text="Installments:", font=("Helvetica", 11))
        self.onr_iznos_rate_label = Label(self.onr_top, text="Value:", font=("Helvetica", 11))
        self.onr_datum_isplate_label = Label(self.onr_top, text="Final payment:", font=("Helvetica", 11))

        self.onr_oznacena_rata_txt = Label(self.onr_top, text="", font=("Helvetica", 11))
        self.onr_broj_rata_txt = Label(self.onr_top, text="", font=("Helvetica", 11))
        self.onr_iznos_rate_txt = Label(self.onr_top, text="", font=("Helvetica", 11))
        self.onr_datum_isplate_txt = Label(self.onr_top, text="", font=("Helvetica", 11))

        self.onr_pl_pojed_btn = Button(self.onr_top, text="Pay selected", command=self.pay_selected)

    def pay_selected(self):
        p_description = self.onr_oznacena_rata_txt.cget("text")
        num_of_installments = self.onr_broj_rata_txt.cget("text").split("/")
        if int(num_of_installments[0])+1 >= int(num_of_installments[1]):
            c.execute('DELETE FROM OTPLATA_NA_RATE WHERE Opis = ?', (p_description,))
            conn.commit()
            if p_description in self.rata_buttons:
                self.rata_buttons[p_description].destroy()
                del self.rata_buttons[p_description]
                self.lista_opisa_rata.remove(p_description)
                self.onr_oznacena_rata_txt.config(text="")
                self.onr_broj_rata_txt.config(text="")
                self.onr_iznos_rate_txt.config(text="")
                self.onr_datum_isplate_txt.config(text="")

        else:
            target_3_novo = str(int(num_of_installments[0])+1) + "/" + num_of_installments[1]
            c.execute('UPDATE OTPLATA_NA_RATE SET Broj_rata = ? WHERE Opis = ?', (target_3_novo, p_description,))
            conn.commit()
            self.get_description(p_description)

    def get_description(self, opis):
        c.execute('SELECT * FROM OTPLATA_NA_RATE WHERE Opis=?;', (opis,))
        for x in c:
            dodaj_godinu = 0
            self.onr_oznacena_rata_txt.config(text=x[1])
            self.onr_iznos_rate_txt.config(text=str(x[2]) + " kn")
            self.onr_broj_rata_txt.config(text=x[3])
            datum_racunanje = int(x[4].split("/")[1]) + int(x[3].split("/")[1])
            while datum_racunanje > 12:
                datum_racunanje -= 12
                dodaj_godinu += 1
            datum_isplate = str(datum_racunanje) + "/" + str(int(x[4].split("/")[2])+dodaj_godinu)
            self.onr_datum_isplate_txt.config(text=datum_isplate)

    def otplata_na_rate_deiconify(self):
        # 清空历史数据
        self.lista_opisa_rata.clear()
        for btn in self.rata_buttons.values():
            btn.destroy()
        self.rata_buttons.clear()

        # Otplata_na_rate TopLevel - define window:
        self.master.withdraw()
        self.onr_top.deiconify()
        self.onr_label.grid(row=0, columnspan=3, sticky="NESW")
        self.onr_opis_label.grid(row=0, column=5, sticky="NESW")
        self.onr_oznacena_rata_label.grid(row=1, column=4, padx=5, sticky="E")
        self.onr_broj_rata_label.grid(row=2, column=4, padx=5, sticky="E")
        self.onr_iznos_rate_label.grid(row=3, column=4, padx=5, sticky="E")
        self.onr_datum_isplate_label.grid(row=4, column=4, padx=5, sticky="E")

        self.onr_oznacena_rata_txt.grid(row=1, column=5, padx=5, sticky="NSWE")
        self.onr_broj_rata_txt.grid(row=2, column=5, padx=5, sticky="NSWE")
        self.onr_iznos_rate_txt.grid(row=3, column=5, padx=5, sticky="NSWE")
        self.onr_datum_isplate_txt.grid(row=4, column=5, padx=5, sticky="NSWE")

        c.execute('SELECT Opis FROM OTPLATA_NA_RATE')
        for opis in c:
            self.lista_opisa_rata.append(opis[0])
        column = 0
        row = 1
        for opis in self.lista_opisa_rata:
            # Append function to button
            function = lambda x=opis: self.get_description(x)
            rata_button = Button(self.onr_top, text=opis, width=10, command=function)
            rata_button.grid(row=row, column=column, padx=5, pady=5)
            self.rata_buttons[opis] = rata_button
            column += 1
            if column == 3:
                row += 1
                column = 0

        #   Define placement of Button widget - created with loop
        if row < 5:
            row = 5
        if row >= 5:
            row += 1

        self.onr_pl_pojed_btn.grid(row=row, column=5, padx=2, pady=5)

        x = self.master.winfo_x()
        y = self.master.winfo_y()
        self.onr_top.geometry(f"+{x}+{y}")


root = Tk()
my_gui = FinancialCalc(root)
root.mainloop()

内容的提问来源于stack exchange,提问作者Freezy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 18:06:03