Моя программа CustomTkinter GUI не обновляется правильноLinux

Ответить
Anonymous
 Моя программа CustomTkinter GUI не обновляется правильно

Сообщение Anonymous »

попробуйте:
импортировать customtkinter как ctk
кроме (ImportError, ImportWarning):
quit("Please install customtkinter | pip install customtkinter")
импортировать getUserData как gud
class createMainWindow(ctk.CTkScrollableFrame):
def init(self, master, **kwargs):
super().init(master, **kwargs)
self.grid_columnconfigure(0, weight=1)

class createSideWindow(ctk.CTkFrame):
def init(self, master, контроллер, **kwargs):
super().init(master, **kwargs)
self.controller = контроллер
# Configure overall grid
self.grid_rowconfigure(0, weight=1) # top frame (buttons)
self.grid_rowconfigure(1, weight=1) # main content / playlists
self.grid_rowconfigure(2, weight=0) # bottom frame (optional)
self.grid_columnconfigure(0, weight=1)

# Top frame for buttons
self.top_frame = ctk.CTkFrame(self, fg_color="transparent")
self.top_frame.grid(row=0, column=0, sticky="nsew", padx=10, pady=10)
self.top_frame.grid_columnconfigure(0, weight=1) # ensure buttons stretch

# Main frame for dynamic content
self.main_frame = ctk.CTkFrame(self, fg_color="transparent")
self.main_frame.grid(row=1, column=0, sticky="nsew", padx=10, pady=10)
self.main_frame.grid_columnconfigure(0, weight=1)

self.main_frame.grid_rowconfigure(0, weight=1)

# Bottom frame if needed
self.bottom_frame = ctk.CTkFrame(self, fg_color="transparent")
self.bottom_frame.grid(row=2, column=0, sticky="ew", padx=10, pady=10)

# Buttons — parented to top_frame
self.newPlaylistButton = ctk.CTkButton(
self.top_frame,
text="+ Create New Playlist",
fg_color='#333333',
hover_color='#555555',
corner_radius=10,
font=('Helvetica', 16, 'bold'),
command=lambda: createNewPlaylist()
)
self.newPlaylistButton.grid(row=0, column=0, sticky="ew", pady=10, ipady=10)

self.gotoLibrary = ctk.CTkButton(
self.top_frame,
text="Library",
fg_color='#333333',
hover_color='#555555',
corner_radius=10,
font=('Helvetica', 16, 'bold'),
command=lambda: [
controller.frames[showLibrary].refresh_library(),
controller.show_frame(showLibrary)
]
)

self.gotoLibrary.grid(row=1, column=0, sticky="ew", pady=10, ipady=10)

class createWelcome(ctk.CTkToplevel):
...
class pageStart(ctk.CTkFrame):
...
class pageBasicDetails(ctk.CTkFrame):
...
class pageAddMusic(ctk.CTkFrame):
...
class createNewPlaylist(ctk.CTkToplevel):
...
def _save_new_playlist(self):
...

class showLibrary(ctk.CTkScrollableFrame):
def init(self, родительский, контроллер):
super().init(parent)
self.controller = контроллер
self.grid_rowconfigure(1, weight=1)
self.grid_columnconfigure(0, weight=1)

self.libraryLabel = ctk.CTkLabel(self, text="Library", font=('Helvetica', 36))
self.libraryLabel.grid(row=0, column=0, sticky='n', pady=10)

self.songs_frame = ctk.CTkFrame(self)
self.songs_frame.grid(row=1, column=0, sticky='nsew', padx=10, pady=5)

self.refresh_library()

def refresh_library(self):
# Clear old widgets
for widget in self.songs_frame.winfo_children():
widget.destroy()

user_data = gud.getUserData()
if type(user_data) != bool and user_data:
for idx, song in enumerate(user_data[0].get("songs", {}).values()):
ctk.CTkLabel(
self.songs_frame,
text=song["name"],
font=('Helvetica', 16),
anchor='w'
).grid(row=idx, column=0, sticky='ew', padx=5, pady=3)

else:
ctk.CTkLabel(
self.songs_frame,
text="No songs available.",
font=('Helvetica', 24)
).grid(row=0, column=0, sticky='ew', padx=5, pady=5)

class Main(ctk.CTkScrollableFrame):
def init(собственный, родительский, контроллер):
ctk.CTkScrollableFrame.init(собственный, родительский)
self.controller = controller

self.TEST_DIR = "Music"
self.userData = gud.getUserData() # type: ignore

if type(self.userData) != bool:
self.userData: dict = self.userData
self.data = self.userData[0]

self.fname = self.data['fname']
self.sname = self.data['sname']
self.songs = self.data['songs']
self.playlists = self.data['playlists']
self.settings = self.data['settings']

self.APP_MODE = str(("dark" if self.settings['darkMode'] else "light"))
self.loop = bool(True if self.settings["loop"] else False)
self.shuffle = bool(True if self.settings["shuffle"] else False)

else:
self.openCreateWelcome()

self.userData = gud.getUserData() # type: ignore

if type(self.userData) != bool:
root = self
self.destroy()
self = root

root.mainloop()

self.userData: dict = self.userData
self.data = self.userData[0]

self.fname = self.data['fname']
self.sname = self.data['sname']
self.songs = self.data['songs']
self.playlists = self.data['playlists']
self.settings = self.data['settings']

self.APP_MODE = str(("dark" if self.settings['darkMode'] == True else "light"))
self.loop = bool(True if self.settings["loop"] else False)
self.shuffle = bool(True if self.settings["shuffle"] else False)

self.APP_COLOUR = 'blue'

try:
ctk.set_appearance_mode(self.APP_MODE)
ctk.set_default_color_theme(self.APP_COLOUR)

except AttributeError:
ctk.set_appearance_mode('dark')
ctk.set_default_color_theme('blue')

print(self.winfo_width(), self.winfo_height(), sep='x')

self.initSideWindow = self.controller.initSideWindow

# Configure grid for Main frame
self.grid_rowconfigure(0, weight=0) # top label
self.grid_rowconfigure(1, weight=1) # song list or main content
self.grid_rowconfigure(2, weight=0) # bottom buttons
self.grid_columnconfigure(0, weight=1)

self.main_topframe = ctk.CTkFrame(self, fg_color='transparent')
self.main_mainFrame = ctk.CTkFrame(self, fg_color='transparent')
self.main_bottomFrame = ctk.CTkFrame(self, fg_color='transparent')

self.main_topframe.grid(row=0, column=0, sticky='n', pady=20)
self.main_mainFrame.grid(row=1, column=0, sticky='n', pady=20)
self.main_bottomFrame.grid(row=2, column=0, sticky='ew', pady=15, ipady=10)

self.main_mainFrame.grid_rowconfigure(0, weight=1)
self.main_mainFrame.grid_columnconfigure(0, weight=1)

self.main_bottomFrame.grid_columnconfigure(0, weight=1)
self.main_bottomFrame.grid_columnconfigure(1, weight=1)

def openCreateWelcome(self):
self.page_window = createWelcome(self)

def showPlaylistSongs(self, playlist_songs_ids):
# Clear previous content
for widget in self.main_mainFrame.winfo_children():
widget.destroy()

if not playlist_songs_ids:
ctk.CTkLabel(self.main_mainFrame,
text="This playlist is empty",
font=('Helvetica', 24, 'bold')).pack(pady=20)
return

for idx, song_id in enumerate(playlist_songs_ids):
song_info = self.userData[0]['songs'].get(song_id, {})
ctk.CTkLabel(
self.main_mainFrame,
text=song_info.get("name", f"Song {idx+1}"),
font=('Helvetica', 16),
anchor='w'
).pack(anchor='w', padx=10, pady=2)

class App(ctk.CTk):
def init(self, *args, **kwargs):
super().init(*args, **kwargs)
self.geometry(f"{int(self.winfo_screenwidth()*0.8)}x{int(self.winfo_screenheight()*0.6)}")

# Container frame
self.container = ctk.CTkFrame(self)
self.container.grid(row=0, column=0, sticky='nsew')
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)

# Sidebar
self.initSideWindow = createSideWindow(
master=self.container, controller=self, width=200, fg_color='transparent', corner_radius=0
)
self.initSideWindow.grid(row=0, column=0, sticky='ns')
self.container.grid_columnconfigure(0, weight=0)

# Main area
self.initMainWindow = ctk.CTkFrame(self.container, fg_color='transparent')
self.initMainWindow.grid(row=0, column=1, sticky='nsew')
self.container.grid_columnconfigure(1, weight=1)

# Frames dict
self.frames = {}
self.current_frame = None

# Add Main and Library frames
for page in (Main, showLibrary):
frame = page(parent=self.initMainWindow, controller=self)
self.frames[page] = frame
frame.place(x=0, y=0, relwidth=1, relheight=1)

self.show_frame(Main)
self._rebuild_sidebar()

def _rebuild_sidebar(self):
# Reference the main (scrollable) part of the sidebar
side_main = self.initSideWindow.main_frame

# Remove only existing playlist buttons
for widget in side_main.winfo_children():
widget.destroy()

# Safely get user data
user_data = gud.getUserData()
if not user_data or type(user_data) == bool:
return

user = user_data[0]
playlists = user.get("playlists", {})

# Rebuild playlist buttons
for pl_id, playlist in playlists.items():
pname = playlist.get("name", "Unnamed Playlist")
psongs_ids = list(playlist.get("songs", []))

# Create a playlist button
btn = ctk.CTkButton(
side_main,
text=pname,
font=('Helvetica', 14, 'bold'),
fg_color="#444444",
hover_color="#666666",
corner_radius=10,
command=self.make_playlist_callback(psongs_ids)
)

btn.grid(sticky="ew", pady=5, padx=5)

def make_playlist_callback(self, song_ids):
"""
Return a callback function that displays the songs of a playlist
in the Main frame.
"""
def callback():
main_frame = self.frames[Main]
main_frame.showPlaylistSongs(song_ids)

return callback

def _refresh_every_100ms(self):
user_data = gud.getUserData()
main_frame = self.frames[Main]
if user_data != getattr(main_frame, "userData", None):
main_frame.userData = user_data
self._rebuild_sidebar()

self.after(100, self._refresh_every_100ms)

def _rebuild_main_content(self, main_frame):
"""Refresh the main content area (library view or playlist songs)."""

self._rebuild_sidebar()
ctk.CTkLabel(main_frame, text="Library", font=('Helvetica', 36)).grid(row=0, column=0, pady=10)

user_data = main_frame.userData
if type(user_data) != bool:
for song in user_data[0]["songs"].values():
ctk.CTkLabel(
main_frame,
text=song["name"],
anchor="w",
font=('Helvetica', 16)
).grid(sticky='w', padx=10, pady=5)
else:
ctk.CTkLabel(
main_frame,
text="No songs available.",
anchor="w",
font=('Helvetica', 24)
).grid(row=1, column=0, sticky='nsew', padx=10, pady=5)

def show_frame(self, page_class):
frame = self.frames[page_class]

# Call refresh if the frame defines it
if hasattr(frame, "refresh"):
frame.refresh()

frame.lift()
self.current_frame = frame

if name == 'main':
app = App()
app.mainloop()


Подробнее здесь: https://stackoverflow.com/questions/798 ... -correctly
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Linux»