我希望“编辑”按钮打开一个新窗口,然后能够编辑显示器上的值

2024-09-28 03:25:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我希望“编辑”按钮打开一个新窗口,然后能够编辑显示器上的值。例如,我想用“Daniel Keelagher”打开一个窗口,然后能够从所玩的游戏、进球、助攻等中获得+1或-1。请详细说明您的答案,因为我是一个哑巴和初学者

#Edit Function

root = Tk()
#Labels
lblTitle = Label(text="Chelsea FC Player Statistics",font=('bold', 15), fg="blue",).grid(row=0, column=1)
#Player Names Labels
lblPlayerNames = Label(text="Player Names",font=('bold')).grid(columnspan=1,row=1, column=1)
lblDKName = Label(text="Daniel Keelagher").grid(columnspan=1,row=2, column=1)
lblJKName = Label(text="Joseph Keelagher").grid(columnspan=1,row=3, column=1)
lblBMName = Label(text="Benjamin Miller").grid(columnspan=1,row=4, column=1)
lblJTName = Label(text="Jordan Terlato").grid(columnspan=1,row=5, column=1)
#Matches Played Labels
lblMatchesPlayed = Label(text="Matches Played",font=('bold')).grid(columnspan=1,row=1, column=2)
lblDKMatches = Label(text="10").grid(columnspan=1,row=2, column=2)
lblJKMatches = Label(text="9").grid(columnspan=1,row=3, column=2)
lblBMMatches = Label(text="9").grid(columnspan=1,row=4, column=2)
lblJTMatches = Label(text="8").grid(columnspan=1,row=5, column=2)
#Goals Labels
lblGoals = Label(text="Goals",font=('bold')).grid(row=1, column=3)
lblDKGoals = Label(text="4").grid(columnspan=1,row=2, column=3)
lblJKGoals = Label(text="2").grid(columnspan=1,row=3, column=3)
lblBMGoals = Label(text="0").grid(columnspan=1,row=4, column=3)
lblJTGoals = Label(text="1").grid(columnspan=1,row=5, column=3)
#Assists Labels
lblAssists = Label(text="Assists",font=('bold')).grid(columnspan=1,row=1, column=4)
lblDKAssists = Label(text="4").grid(columnspan=1,row=2, column=4)
lblJKAssists = Label(text="2").grid(columnspan=1,row=3, column=4)
lblBMAssists = Label(text="0").grid(columnspan=1,row=4, column=4)
lblJTAssists = Label(text="1").grid(columnspan=1,row=5, column=4)
#YellowCards Labels
lblYellowCards = Label(text="YC",font=('bold')).grid(columnspan=1,row=1, column=5)
lblDKYellowCards = Label(text="0").grid(columnspan=1,row=2, column=5)
lblJKYellowCards = Label(text="1").grid(columnspan=1,row=3, column=5)
lblBMYellowCards = Label(text="1").grid(columnspan=1,row=4, column=5)
lblJTYellowCards = Label(text="3").grid(columnspan=1,row=5, column=5)
#RedCards Labels
lblYellowCards = Label(text="RC",font=('bold')).grid(columnspan=1,row=1, column=6)
lblDKRedCards = Label(text="0").grid(columnspan=1,row=2, column=6)
lblJKRedCards = Label(text="0").grid(columnspan=1,row=3, column=6)
lblBMRedCards = Label(text="0").grid(columnspan=1,row=4, column=6)
lblJTRedCards = Label(text="1").grid(columnspan=1,row=5, column=6)


#Buttons
btnDKEdit = Button(root, text="Edit",).grid(columnspan=1,row=2, column=7)
btnJKEdit = Button(root, text="Edit", ).grid(columnspan=1,row=3, column=7)
btnBMEdit = Button(root, text="Edit", ).grid(columnspan=1,row=4,column=7)
btbJTEdit = Button(root, text="Edit",).grid(columnspan=1,row=5, column=7)```

Tags: text编辑labelscolumnbuttonrooteditlabel
3条回答

下面是另一种方法(函数式编程方法):

from tkinter import Tk, Frame, Button, Label, StringVar, Toplevel
from functools import partial


stored_data = {'Lionel Notmessi': {'Games Played': 340, 'Goals': 102, 'Assists': 223}, 'Firstname Lastname': {'Games Played': 279, 'Goals': 84, 'Assists': 56}}


def open_edit_window(player):
    tp = Toplevel(root)
    tp.focus_force()

    def del_n_refresh(event=None):
        tp.destroy()
        pack_all_players()

    tp.bind('<FocusOut>', del_n_refresh)
    tp.protocol('WM_DELETE_WINDOW', del_n_refresh)

    total_length = len(stored_data[player])

    def change(variable, stat_name, sign):
        current = int(variable.get())
        if sign == '-':
            stored_data[player][stat_name] = current - 1
            variable.set(current - 1)
        elif sign == '+':
            stored_data[player][stat_name] = current + 1
            variable.set(current + 1)

    stats_edit_frame = Frame(tp)
    stats_edit_frame.pack()

    Label(stats_edit_frame, text=player).grid(row=0, column=0, columnspan=total_length)

    value_list = []
    
    counter = 0
    for stats, values in stored_data[player].items():
        var = StringVar()
        var.set(values)
        value_list.append(var)

        edit_data_frame = Frame(stats_edit_frame)
        edit_data_frame.grid(row=1, column=counter, padx=5, pady=5)
        for i in range(3):
            edit_data_frame.columnconfigure(i, minsize=50)

        Label(edit_data_frame, text=stats).grid(row=0, column=0, columnspan=3)

        Button(edit_data_frame, text='-', command=partial(change, value_list[counter], stats, '-')).grid(row=1, column=0, sticky='nsew')

        Label(edit_data_frame, textvariable=value_list[counter]).grid(row=1, column=1)

        Button(edit_data_frame, text='+', command=partial(change, value_list[counter], stats, '+')).grid(row=1, column=2, sticky='nsew')
        counter += 1

    done = Button(stats_edit_frame, text='Done', command=del_n_refresh)
    done.grid(row=3, column=0, columnspan=total_length, sticky='nsew', pady=5, padx=5)


def pack_all_players():
    # this for loop is for refreshing the data
    for widget in all_player_frame.winfo_children():
        widget.destroy()

    for player in stored_data:
        player_frame = Frame(all_player_frame, width=100)
        player_frame.pack(side='left', pady=20, padx=20)

        Label(player_frame, text=player, font='default 12 normal').pack(side='top', pady=5)

        stats_frame = Frame(player_frame)
        stats_frame.pack(side='top', pady=10)
        for stats, values in stored_data[player].items():
            Label(stats_frame, text=f'{stats}: {values}').pack()

        Button(player_frame, text='Edit', width=15, command=partial(open_edit_window, player)).pack(side='bottom', pady=5)


root = Tk()

all_player_frame = Frame(root)
all_player_frame.pack()

pack_all_players()

root.mainloop()

所以这个过程已经在另一个答案中解释过了,在这里它几乎是一样的,几乎是相同的循环,几乎是相同的调用,但是使用函数而不是类。如果你问这是否可以实现:那么如果你的意思是仅仅将这些函数添加到你的代码(你发布的那一个)中,那么这些函数就可以做所有事情,从字面上说,因此唯一的实现就是复制粘贴到你的代码上,那么你也可以更改一些函数,修改它们等等,因为它们根据需要创建小部件,所以字典中的玩家数量基本上就是它将创建的相应小部件数量(您的方法似乎是硬编码信息)。如果你想保存到我在另一个答案中提到的文件中

因此,这完全是你的方式(至少是我能找到的最接近的方式,也是最糟糕的方式,但你确实如此):

# import what is necessary
from tkinter import Tk, Label, Button, IntVar, Toplevel
import json

# first try doing this code of block and if it raises the FileNotFoundError use the other bloc
try:
    # open 'settings.json' file and load the data (import json first)
    with open('settings.json') as file:
        stored_data = json.load(file)

except FileNotFoundError:
    # create sample data to add to the created file
    stored_data = {'Daniel Keelagher': {'Matches Played': 10, 'Goals': 4, 'Assists': 4, 'YC': 0, 'RC': 0},
                   'Joseph Keelagher': {'Matches Played': 9, 'Goals': 2, 'Assists': 2, 'YC': 1, 'RC': 0},
                   'Benjamin Miller': {'Matches Played': 9, 'Goals': 0, 'Assists': 0, 'YC': 1, 'RC': 0},
                   'Jordan Terlato': {'Matches Played': 8, 'Goals': 1, 'Assists': 1, 'YC': 3, 'RC': 1}}
    # create 'settings.json' file if the file was not found
    with open('settings.json', 'w') as file:
        # dump all the data in 'settings.json'
        json.dump(stored_data, file, indent=2)

# define function change which will be responsible for changing data in stored_data dictionary
def change(player, stat, value, operator):  # set required arguments for the function which will be the: player (key in the dictionary, i.e. 'Daniel Keelagher'); stat (key in the player dictionary i.e. 'Goals', 'Assists'); value (refers to the IntVar associated with the respective Label); operator (determines whether value will be subtracted or added)
    # getting the current value of the associated IntVar
    cur_value = value.get()
    # eval to determine the operation if/elif
    if operator == '-':
        # accessing the stored_data key and dictionary key under the stored_data[key]
        stored_data[player][stat] = cur_value - 1
        # setting the IntVar value
        value.set(cur_value - 1)
    elif operator == '+':
        # same as previous but adding value
        stored_data[player][stat] = cur_value + 1
        value.set(cur_value + 1)


# defining edit_dk which will be responsible for editing Daniel Keelagher so such similar functions should be created for all players i.e. edit_jk, edit_bm
def edit_dk():
    # creating a new window for data editing
    tp = Toplevel(root)

    # packing a label to display name
    Label(tp, text='Daniel Keelagher').grid(row=0, column=0, columnspan=15)

    # packing edit buttons and value label for data editing, command is set to change() and can be followed through using previous comments this explanation is for all the Label-Button groups below defined in this function
    Button(tp, text='-', command=lambda: change('Daniel Keelagher', 'Matches Played', dk_matches_var, '-')).grid(row=1, column=0)
    Label(tp, textvariable=dk_matches_var).grid(row=1, column=1)
    Button(tp, text='+', command=lambda: change('Daniel Keelagher', 'Matches Played', dk_matches_var, '+')).grid(row=1, column=2)

    Button(tp, text='-', command=lambda: change('Daniel Keelagher', 'Goals', dk_goals_var, '-')).grid(row=1, column=3)
    Label(tp, textvariable=dk_goals_var).grid(row=1, column=4)
    Button(tp, text='+', command=lambda: change('Daniel Keelagher', 'Goals', dk_goals_var, '+')).grid(row=1, column=5)

    Button(tp, text='-', command=lambda: change('Daniel Keelagher', 'Assists', dk_assists_var, '-')).grid(row=1, column=6)
    Label(tp, textvariable=dk_assists_var).grid(row=1, column=7)
    Button(tp, text='+', command=lambda: change('Daniel Keelagher', 'Assists', dk_assists_var, '+')).grid(row=1, column=8)

    Button(tp, text='-', command=lambda: change('Daniel Keelagher', 'YC', dk_yc_var, '-')).grid(row=1, column=9)
    Label(tp, textvariable=dk_yc_var).grid(row=1, column=10)
    Button(tp, text='+', command=lambda: change('Daniel Keelagher', 'YC', dk_yc_var, '+')).grid(row=1, column=11)

    Button(tp, text='-', command=lambda: change('Daniel Keelagher', 'RC', dk_rc_var, '-')).grid(row=1, column=12)
    Label(tp, textvariable=dk_rc_var).grid(row=1, column=13)
    Button(tp, text='+', command=lambda: change('Daniel Keelagher', 'RC', dk_rc_var, '+')).grid(row=1, column=14)


# initiating Tk class which also creates a window
root = Tk()

# Labels
Label(text="Chelsea FC Player Statistics", font=('bold', 15), fg="blue",).grid(row=0, column=1)

# Player Names Labels
Label(text="Player Names", font='bold').grid(columnspan=1, row=1, column=1)
Label(text="Daniel Keelagher").grid(columnspan=1, row=2, column=1)

# Matches Played Labels
Label(text="Matches Played", font='bold').grid(columnspan=1, row=1, column=2)
# setting up an IntVar for matches: for other players it could be for example bm_matches_var and is related to matches label (below) this explanation fits other IntVars too.
dk_matches_var = IntVar()
# set the variable to statistics the same for the rest
dk_matches_var.set(stored_data['Daniel Keelagher']['Matches Played'])
Label(textvariable=dk_matches_var).grid(columnspan=1, row=2, column=2)


# Goals Labels
Label(text="Goals", font='bold').grid(row=1, column=3)
dk_goals_var = IntVar()
dk_goals_var.set(stored_data['Daniel Keelagher']['Goals'])
Label(textvariable=dk_goals_var).grid(columnspan=1, row=2, column=3)

# Assists Labels
Label(text="Assists", font='bold').grid(columnspan=1, row=1, column=4)
dk_assists_var = IntVar()
dk_assists_var.set(stored_data['Daniel Keelagher']['Assists'])
Label(textvariable=dk_assists_var).grid(columnspan=1, row=2, column=4)

# YellowCards Labels
Label(text="YC", font='bold').grid(columnspan=1, row=1, column=5)
dk_yc_var = IntVar()
dk_yc_var.set(stored_data['Daniel Keelagher']['YC'])
Label(textvariable=dk_yc_var).grid(columnspan=1, row=2, column=5)

# RedCards Labels
Label(text="RC", font='bold').grid(columnspan=1, row=1, column=6)
dk_rc_var = IntVar()
dk_rc_var.set(stored_data['Daniel Keelagher']['RC'])
Label(textvariable=dk_rc_var).grid(columnspan=1, row=2, column=6)


# Buttons for other it could be something like `command=edit_bm`
Button(root, text="Edit", command=edit_dk).grid(columnspan=1, row=2, column=7)

# main loop of tkinter
root.mainloop()

# save file after closing the window
with open('settings.json', 'w') as file:
    json.dump(stored_data, file, indent=2)

这是一个播放器,您必须为字典中的每个播放器执行此操作,在首页中添加所有标签、所有变量、按钮,并为每个播放器定义函数(类似于我在本例中所示),您还必须匹配那些字典键(如函数中所定义)(只是举个例子,你应该会很好,但我真的建议你看看我给出的其他答案,“研究它们”并使用它们,看看教程(如评论中提到的)因为这是最糟糕的方法,尤其是因为有很多更简单的方法,所以这里是你可以做的,但你不应该做,因为这在客观上是不必要的)

唯一不必更改的是change函数定义,如果您有疑问,也可以更改

此外,如果您对此感兴趣,我已经在第一个答案中介绍了保存到文件

这是我的解决方案(相当长,但我会尽可能地解释大部分部分(解释如下),但在这种情况下,不会有新的窗口,而且这更多的是一个示例,说明如何做到这一点,只是为了给您一个想法。):

from tkinter import Tk, Button, Frame, Label, StringVar
from tkinter.ttk import Separator
from functools import partial


stored_data = {'Lionel Notmessi': {'Games Played': 340, 'Goals': 102, 'Assists': 223}, 'Firstname Lastname': {'Games Played': 279, 'Goals': 84, 'Assists': 56}}


class MainWindow(Tk):
    def __init__(self):
        Tk.__init__(self)
        self.resizable(False, False)

        self.players_frame = Frame(self)
        self.players_frame.pack(fill='both', expand=True)

        self.data_value_list = []

        for index, player in enumerate(list(stored_data)):
            player_frame = Frame(self.players_frame)
            player_frame.pack(side='left')
            Label(player_frame, text=player, height=2, width=30, anchor='n', font='default 11 bold').pack(side='top', pady=10)

            var = StringVar()
            self.data_value_list.append(var)

            Label(player_frame, textvariable=self.data_value_list[index], height=8, width=30).pack(side='top', pady=10)

            Button(player_frame, text='Edit', command=partial(self.select, player)).pack(side='bottom', pady=10, fill='x', expand=True)

        self.refresh_data()

    def select(self, key):
        self.players_frame.pack_forget()
        player_edit_frame = EditData(self, stored_data, key)
        player_edit_frame.pack(fill='both', expand=True)

    def refresh_data(self):
        for var, player in zip(self.data_value_list, list(stored_data)):
            data = ''
            for name, value in stored_data[player].items():
                data += f'{name}: {value}\n\n'
            var.set(data)


class EditData(Frame):
    def __init__(self, parent, data, key):
        Frame.__init__(self, parent)
        self.parent = parent
        self.data = data
        self.key = key

        self.total_width = len(list(data[key].keys()))

        name = Label(self, text=key, anchor='n', height=3)
        name.grid(row=0, column=0, columnspan=self.total_width, sticky='nsew', pady=10)

        self.value_list = []
        index = 0
        for key, value in data[self.key].items():
            item_frame = Frame(self)
            item_frame.grid(row=1, column=index, sticky='nsew', padx=5)
            for i in range(3):
                item_frame.columnconfigure(i, minsize=50)

            var = StringVar()
            var.set(value)
            self.value_list.append(var)

            Label(item_frame, text=key).grid(row=0, column=0, columnspan=3, sticky='nsew')

            minus = Button(item_frame, text='-', command=partial(self.change, self.value_list[index], '-', key))
            minus.grid(row=1, column=0, sticky='nsew')

            value_label = Label(item_frame, textvariable=self.value_list[index])
            value_label.grid(row=1, column=1, sticky='nsew')

            plus = Button(item_frame, text='+', command=partial(self.change, self.value_list[index], '+', key))
            plus.grid(row=1, column=2, sticky='nsew')

            index += 1

        Separator(self, orient='horizontal').grid(row=2, column=0, columnspan=self.total_width, sticky='nsew', pady=5)

        Button(self, text='Done', command=self.done).grid(row=3, column=0, columnspan=self.total_width, sticky='nsew')

    def change(self, var, operator, key):
        current = var.get()
        if operator == '-':
            total = int(current) - 1
            var.set(str(total))
            self.data[self.key][key] = total
        if operator == '+':
            total = int(current) + 1
            var.set(str(total))
            self.data[self.key][key] = total

    def done(self):
        self.parent.refresh_data()
        self.parent.players_frame.pack(expand=True, fill='both')
        self.destroy()


root = MainWindow()
root.mainloop()

因此,第一件事是导入将要使用的所有必要模块

接下来,我将一个变量stored_data设置为一个字典,该字典将是主要的数据存储位置,所有关于球员的数据都将在这里存储

然后我创建了一个名为MainWindow的类,它继承了tkinter的主窗口Tk,这样就可以获得Tk()功能,例如.mainloop()方法

MainWindow构造函数方法(启动时将调用什么)中,我首先将窗口设置为在x和y方向上都不可压缩,这样就不会导致窗口小部件不可见的问题

然后,我创建了一个框架来组织所有播放器内容的显示位置,还创建了另一个用于存储StringVar值的列表,以便轻松更新当前数据标签(启动程序时看到的标签)

然后,我为字典中的每个键创建了一个框架来再次组织显示的小部件。然后在框架中我打包了所有相关的东西,我输入了球员的名字,他们的统计数据和编辑按钮(因为我只关注这个功能)。还为每个玩家在列表中添加了StringVar。这些StringVar设置将显示统计信息的标签的值。StringVar是通过索引访问的

然后我调用了self.refresh_data(),它基本上将列表中每个StringVar的值设置为相应的字典值。基本上显示统计数据

然后还有定义的select()方法(通过按钮调用),该方法启动EditData,然后在从几何体管理器中删除self.players_frame后将其放在屏幕上,使其不再可见,只有编辑框可见

EditData类。在初始化时,它接受给定给它的参数,并将它们设置为类属性,以便在整个类中更容易访问

然后测量总宽度以计算网格的列跨度,并通过测量由stored_data键创建的列表的长度来完成,因此基本上长度就是玩家的数量

然后这个名字就会出现在屏幕上

再次创建另一个用于存储StringVar的self.value_list,并且将索引设置为0(因为我不知道如何在for循环中实现它(足够简单)(使用enumerate()))。每次迭代都会增加索引

然后创建标签和按钮,并将其网格化到item_frame中,该类位于从Frame继承的类内,因此该类基本上是一个较大的帧,在该类内,程序创建较小的帧,用于数据更改和布局组织。然后在item_frame中,每个列都被设置为minsize=50,这样它们的大小就相同了,因为所有数据都不会占用那么多空间

然后再次设置StringVar并将其附加到列表中,以便以后访问它

整体

  name 
- data + 

布局被创建,按钮被设置为方法change()并给定参数(该partial()将这些函数设置为始终使用相同的给定变量执行,以便可以轻松地在循环中创建按钮)。当调用change时,它会获取该数据部分的当前值,然后根据它是“-”还是“+”,它会对当前值进行加减,并将其设置为新值,同时还会更改字典中的值,以便下次显示此帧时,它会显示新数据,并在“首页”上显示统计信息显示更新的数据

还有一个“Done”按钮,按下该按钮时调用done()方法,然后调用parent(即MainWindow)方法refresh_data()来显示新的数据,然后它会将调用之前删除的帧打包回去摧毁这个类,然后摧毁自己

然后我们就开始MainWindow

root = MainWindow()
root.mainloop()

就这样

显然,可以进行一些设计改进。
此外,如果希望保存数据,以便每次启动时都显示更改的数据,则可以在关闭窗口之前将数据写入文件

如果你有问题,就问他们

关于文件保存:

您可以添加以下(MainWindow类):

self.protocol('WM_DELETE_WINDOW', lambda: self.save(stored_data))

调用__init__方法来执行关闭窗口时给定的函数

还应添加以下内容:

with open('stored_data.json') as file:
    stored_data = json.load(file)

在文件开始时,请确保您的目录中有该文件,您还必须:

import json

然后定义关闭窗口时调用的save()方法(在MainWindow类中):

def save(self, data):
        with open('stored_data.json', 'w') as file_:
            json.dump(data, file_, indent=2)
        self.destroy()

因此,它会将更新的数据写入该文件,并记住在之后销毁该窗口,否则它将无法关闭

现在,您可以在运行程序时加载数据,如果进行了更改,这些数据将保存到文件中,以便下次运行程序时访问

如果你有问题,再次问他们

添加了Toplevel(确实是最小的更改,但添加了一些类似bind的内容,以确保如果用户将焦点放在编辑窗口之外,它将关闭,从而多个相同的窗口不会打开(因此还定义了另一种方法),所有更改如下所示:

from tkinter import Tk, Button, Frame, Label, StringVar, Toplevel, Entry
from tkinter.ttk import Separator
from functools import partial


stored_data = {'Lionel Notmessi': {'Games Played': 340, 'Goals': 102, 'Assists': 223}, 'Firstname Lastname': {'Games Played': 279, 'Goals': 84, 'Assists': 56}}


class MainWindow(Tk):
    def __init__(self):
        Tk.__init__(self)
        self.resizable(False, False)

        self.players_frame = Frame(self)
        self.players_frame.pack(fill='both', expand=True)

        self.data_value_list = []

        for index, player in enumerate(list(stored_data)):
            player_frame = Frame(self.players_frame)
            player_frame.pack(side='left')
            Label(player_frame, text=player, height=2, width=30, anchor='n', font='default 11 bold').pack(side='top', pady=10)

            var = StringVar()
            self.data_value_list.append(var)

            Label(player_frame, textvariable=self.data_value_list[index], height=8, width=30).pack(side='top', pady=10)

            Button(player_frame, text='Edit', command=partial(self.select, player)).pack(side='bottom', pady=10, fill='x', expand=True)

        self.refresh_data()

    def select(self, key):
        player_edit_frame = EditData(self, stored_data, key)
        player_edit_frame.focus_force()

    def refresh_data(self):
        for var, player in zip(self.data_value_list, list(stored_data)):
            data = ''
            for name, value in stored_data[player].items():
                data += f'{name}: {value}\n\n'
            var.set(data)


class EditData(Toplevel):
    def __init__(self, parent, data, key):
        Toplevel.__init__(self, parent)
        self.parent = parent
        self.data = data
        self.key = key

        self.bind('<FocusOut>', self.focus_out)

        self.total_width = len(list(data[key].keys()))

        name = Label(self, text=key, anchor='n', height=3)
        name.grid(row=0, column=0, columnspan=self.total_width, sticky='nsew', pady=10)

        self.value_list = []
        index = 0
        for key, value in data[self.key].items():
            item_frame = Frame(self)
            item_frame.grid(row=1, column=index, sticky='nsew', padx=5)
            for i in range(3):
                item_frame.columnconfigure(i, minsize=50)

            var = StringVar()
            var.set(value)
            self.value_list.append(var)

            Label(item_frame, text=key).grid(row=0, column=0, columnspan=3, sticky='nsew')

            minus = Button(item_frame, text='-', command=partial(self.change, self.value_list[index], '-', key))
            minus.grid(row=1, column=0, sticky='nsew')

            value_label = Label(item_frame, textvariable=self.value_list[index])
            value_label.grid(row=1, column=1, sticky='nsew')

            plus = Button(item_frame, text='+', command=partial(self.change, self.value_list[index], '+', key))
            plus.grid(row=1, column=2, sticky='nsew')

            index += 1

        Separator(self, orient='horizontal').grid(row=2, column=0, columnspan=self.total_width, sticky='nsew', pady=5)

        Button(self, text='Done', command=self.done).grid(row=3, column=0, columnspan=self.total_width, sticky='nsew')

    def change(self, var, operator, key):
        current = var.get()
        if operator == '-':
            total = int(current) - 1
            var.set(str(total))
            self.data[self.key][key] = total
        if operator == '+':
            total = int(current) + 1
            var.set(str(total))
            self.data[self.key][key] = total

    def done(self):
        self.parent.refresh_data()
        self.destroy()

    def focus_out(self, event):
        self.parent.refresh_data()
        if event.widget == self:
            self.destroy()


root = MainWindow()
root.mainloop()

改变MainWindow

更改了select()方法以显示顶层

def select(self, key):
        player_edit_frame = EditData(self, stored_data, key)
        player_edit_frame.focus_force()

变化EditFrame

从顶层继承的

class EditData(Toplevel):
    def __init__(self, parent, data, key):
        Toplevel.__init__(self, parent)

附加绑定

self.bind('<FocusOut>', self.focus_out)

bind附带的一个方法(它检查焦点是否在整个窗口之外,否则即使焦点在条目小部件之外也会导致它关闭)

def focus_out(self, event):
        self.parent.refresh_data()
        if event.widget == self:
            self.destroy()

相关问题 更多 >

    热门问题