python - (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()
解决方案
推荐阅读
- python - 烧瓶断言错误:400!= 201
- google-apps-script - 在 Google Apps 脚本中生成幂级数趋势线
- mongodb - mongodb属性的长度
- thymeleaf - 参考 thymleaf 模板的 href 或属性中的片段
- json - 我如何(通过 JSON API)让 Drupal 返回一个带有分类列表的 Json?
- c++ - 尝试使用 Visual Studio 2017 在 C++ 中运行子进程程序时出现 C2065 错误
- amazon-web-services - 通过 SSH 连接到位于 VPC 的私有子网中的 AWS EC2 实例
- php - Session.php 类无法正确加载
- jquery - 如何在 JSTL c:url 值中附加动态路径
- java - 有没有办法在 Redis 和关系数据库中使用带有 @RedisHash 的实体?