首页 > 解决方案 > (tkinter)我将按钮网格化到框架的方式有问题吗?

问题描述

所以基本上我在 tkinter 中制作了一个 mp3 播放器,我希望用户能够添加播放列表(按钮)。如您所见,我在框架中添加了一个带有加号图标的(添加播放列表)按钮,该按钮调用一个函数来弹出一个窗口供用户输入新播放列表的名称。 在此处输入图像描述

我正在单击按钮,然后会弹出“添加播放列表”窗口,但是当我输入名称并单击确认时会发生这种情况在此处输入图像描述

顶部按钮被挤压掉(它们仍然可见),而我刚刚添加的按钮似乎被切断了,我也无法使用滚动条。

但是,因为我编写了一些代码,以便我的程序将新播放列表的名称存储在一个 txt 文件中,然后获取这一行来创建播放列表按钮,所以每当我重新运行我的程序时,网格似乎都很好。(下图)滚动条也可以正常工作。

在此处输入图像描述

有什么办法可以以某种方式更新网格,以便它根据需要显示而无需(当然)重新运行应用程序?我试过self.playlist_frame.update_idletasks()了,但似乎没有任何效果。(self.playlists_frame我放置按钮并将滚动条链接到的框架在哪里)我也尝试过在单击确认按钮时调用创建按钮的功能,但这似乎也没有效果(当我说没有效果时,我的意思是同样的事情也会发生)

这是我的代码:

class MyApp:
    def __init__(self):

        self.root = tk.Tk()

        self.width = self.root.winfo_screenwidth()
        self.height = self.root.winfo_screenheight()
        self.height = self.root.winfo_screenheight() - int(self.height / 13)

        self.root.geometry(f'{self.width}x{self.height}')

        self.root.state('zoomed')
        self.root.resizable(False, True)

        self.c = '#14141D'

        self.playlists = {} 

        self.main = ttk.Notebook(self.root)

        # TABS
        self.home_tab = tk.Frame(self.main)
        self.playlists_tab = tk.Frame(self.main)
        self.manual_tab = tk.Frame(self.main)
       
        self.playlists_canvas = tk.Canvas(self.playlists_tab, bg=self.c)
        self.playlist_frame = tk.Frame(self.playlists_canvas, bg=self.c)

这就是我放置画布、框架、滚动条和添加播放列表按钮的方式

    def widgets(self):
        self.playlist_frame = tk.Frame(self.playlists_canvas, bg=self.c)

        self.playlists_canvas.create_window((0,0),window=self.playlist_frame, anchor='center')
        self.playlists_canvas.config(bg=self.c)

        self.playlists_canvas.place(height=int(self.height / 1.428), width=self.width, x=0, y=int(self.height / 9))

        self.add_playlists_button = tk.Button(self.playlists_canvas, image=self.add_img, bg=self.c, bd=0,
                                              command=self.add_playlists)
        self.add_playlists_button.place(x=1284, y=75)

        self.playlists_scrollbar.pack(side='right', fill='y')
        self.playlists_canvas.config(yscrollcommand=self.playlists_scrollbar.set)
        self.playlists_canvas.bind('<Configure>', lambda e: 
        self.playlists_canvas.configure(
            scrollregion=self.playlists_canvas.bbox('all')))


self.playlists 是一个空字典,稍后(当我向其中添加项目时)将获得表单

self.playlists = {'rock':[], 'metal':[]}

这是一个关键:带有空列表的“摇滚”(以便我以后可以添加歌曲)

我制作了一个函数 (create_playlists(self)),它将播放列表按钮附加到列表中,然后对同一列表中的项目进行网格化。

def create_playlists(self):
    self.playlists_buttons_list = []

    for i in range(len(self.playlists.keys())):
        self.playlists_buttons_list.append(tk.Button(self.playlist_frame, bg=self.c,
                                                     text=' ' + list(self.playlists.keys())[i].split('!')[0],
                                                     height=280, width=300,
                                                     font=('Baskerville Old Face', int(self.height / 30)),
                                                     fg='pink', anchor='n',
                                                     activebackground=self.c, activeforeground='pink',
                                                     image=self.default_img,
                                                     compound=tk.LEFT, relief='sunken', overrelief='raised'))

    row = 0
    column = 0
    for i in self.playlists_buttons_list:
        if column > 3:
            row += 1
            column = 0

        if column > 7:
            row += 1
            column = 0

        i.grid(row=row, column=column)
        column += 1

这是单击确认按钮时调用的函数:

def get_name(self):
    self.name_of_plst = self.plst_entry.get()
    # self.plst_entry is the entry widget in the window that pops up
    if self.name_of_plst != '' and self.name_of_plst != '\n':
        self.playlists[self.name_of_plst] = []
        # this way I add an item to my dictionary ('name_of_new_playlist':[])
        self.create_playlists()

无论如何,这里是我正在运行的最小可复制示例。

import os
import tkinter as tk
from tkinter import ttk
from PIL import Image, ImageTk


class MyApp:
    def __init__(self):

        self.root = tk.Tk()

        self.width = self.root.winfo_screenwidth()
        self.height = self.root.winfo_screenheight()
        self.height = self.root.winfo_screenheight() - int(self.height / 13)
        self.root.geometry(f'{self.width}x{self.height}')
        self.root.title("Mp3")

        self.c = '#14141D'

        self.playlists_buttons_list = []
        self.playlists = {}
        self.helping_d = {}

        self.main = ttk.Notebook(self.root)
        self.playlists_tab = tk.Frame(self.main)
        self.playlist_menu_frame = tk.Frame(self.playlists_tab, bg=self.c)
        self.playlists_canvas = tk.Canvas(self.playlists_tab, bg=self.c)
        self.playlist_frame = tk.Frame(self.playlists_canvas, bg=self.c)
        self.playlists_scrollbar = ttk.Scrollbar(self.playlists_tab, orient='vertical',
                                                 command=self.playlists_canvas.yview)
        self.add_playlist_win = tk.Toplevel(self.root)
        self.add_playlists_button = tk.Button(self.playlist_frame)
        self.default_img = Image.open('images/default.png').resize((75, 72))
        self.default_img = ImageTk.PhotoImage(self.default_img)
        self.add_img = Image.open('images/add.png').resize((50, 50))
        self.add_img = ImageTk.PhotoImage(self.add_img)
        self.widgets()
        self.root.mainloop()

    def widgets(self):
        self.playlists_tab.place(height=self.height, width=self.width, x=0, y=0)
        self.main.add(self.playlists_tab, text="Playlists")
        self.main.pack(expand=1, fill="both")
        self.playlist_frame = tk.Frame(self.playlists_canvas, bg=self.c)
        self.playlists_canvas.create_window((0, 0), window=self.playlist_frame, anchor='center')
        self.playlists_canvas.config(bg=self.c)
        self.playlists_canvas.place(height=int(self.height / 1.428), width=self.width, x=0, y=int(self.height / 9))
        self.add_playlists_button = tk.Button(self.playlists_canvas, image=self.add_img, bg=self.c, bd=0,
                                              command=self.add_playlists)
        self.add_playlists_button.place(x=1284, y=75)
        self.playlists_scrollbar.pack(side='right', fill='y')
        self.playlists_canvas.config(yscrollcommand=self.playlists_scrollbar.set)
        self.playlists_canvas.bind('<Configure>', lambda e: self.playlists_canvas.configure(
            scrollregion=self.playlists_canvas.bbox('all')))

        if os.path.getsize('playlistsnames.txt') != 0:
            lines = open('playlistsnames.txt', 'r', encoding='utf-8').read().splitlines()
            for i in lines:
                self.playlists[i] = []

        self.create_playlists()

    def create_playlists(self):
        self.playlists_buttons_list = []

        for i in range(len(self.playlists.keys())):
            self.playlists_buttons_list.append(tk.Button(self.playlist_frame, bg=self.c,
                                                         text=' ' + list(self.playlists.keys())[i].split('!')[0],
                                                         fg='white', image=self.default_img, height=280, width=300))
            row = 0
            column = 0
            for i in self.playlists_buttons_list:
                if column > 3:
                    row += 1
                    column = 0
                if column > 7:
                    row += 1
                    column = 0
                i.grid(row=row, column=column)
                column += 1

    def get_name(self):
        self.name_of_plst = self.plst_entry.get()
        self.playlists[self.name_of_plst] = []
        self.create_playlists()

        with open('playlistsnames.txt', 'a', encoding='utf-8') as names_file:
            names_file.write(self.name_of_plst + '!\n')

    def add_playlists(self):
        self.add_playlist_win = tk.Toplevel(self.root)
        self.name_label = tk.Label(self.add_playlist_win, text='Name:', bg=self.c, fg='pink').pack()
        self.plst_entry = tk.Entry(self.add_playlist_win)
        self.plst_entry.pack()
        self.confirm_btn = tk.Button(self.add_playlist_win, text='Confirm', bg=self.c, fg='pink',
                                     command=self.get_name).pack()
        self.add_playlist_win.mainloop()


MyApp()

标签: pythontkinter

解决方案


推荐阅读