Борьба с проблемами пользовательского интерфейсаPython

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Борьба с проблемами пользовательского интерфейса

Сообщение Anonymous »

Я хочу иметь возможность изменять размер моего виджета/окна с помощью двойных стрелок в стиле окна и изменять его размер. Я хочу иметь возможность изменять высоту и ширину, перетаскивая края каждого окна по отдельности, чтобы настроить их. Буду очень признателен за любую помощь по улучшению этого сценария и предложения по его улучшению.
Вот мой сценарий
import tkinter as tk
from tkinter import ttk, messagebox, filedialog
from yt_dlp import YoutubeDL
import vlc
import os
import random
import json
import threading
from PIL import Image, ImageTk

class YouTubeJukebox(tk.Tk):
def __init__(self):
super().__init__()

self.title("YouTube Jukebox by Littch")

# Detect screen width and height
screen_width = self.winfo_screenwidth()
screen_height = self.winfo_screenheight()

# Set geometry to maximize the window
self.geometry(f"{screen_width}x{screen_height}")

# Load background image
self.bg_image = Image.open(r"C:\Users\Jack\Desktop\dj-8562307.jpg")
self.bg_image = self.bg_image.resize((screen_width, screen_height), Image.LANCZOS)
self.bg_photo = ImageTk.PhotoImage(self.bg_image)

# Create a canvas and set the background image
self.canvas = tk.Canvas(self, width=screen_width, height=screen_height)
self.canvas.pack(fill="both", expand=True)
self.canvas.create_image(0, 0, image=self.bg_photo, anchor="nw")

# VLC Instance and Player Setup
self.vlc_instance = vlc.Instance()
self.player = self.vlc_instance.media_player_new()
self.player.event_manager().event_attach(vlc.EventType.MediaPlayerEndReached, self.on_song_end)

# Styling
style = ttk.Style(self)
style.configure('TButton', font=('Arial', 7), padding=5)
style.map('TButton', foreground=[('pressed', 'white'), ('active', 'white')],
background=[('pressed', '#3498DB'), ('active', '#3498DB')])

self.playlist_id_entry_style = {"bg": "#ECF0F1", "fg": "#34495E", "insertbackground": "#34495E"}
self.playlist_id_label_style = {"bg": "#2C3E50", "fg": "#FFFFFF"}

# Add widgets to the canvas
self.label = tk.Label(self, text="Enter YouTube Playlist ID:", **self.playlist_id_label_style)
self.label_window = self.canvas.create_window(screen_width//2, 50, anchor="center", window=self.label)

self.playlist_id_entry = tk.Entry(self, width=50, **self.playlist_id_entry_style)
self.entry_window = self.canvas.create_window(screen_width//2, 100, anchor="center", window=self.playlist_id_entry)

self.load_button = ttk.Button(self, text="Load Playlist", command=self.load_playlist)
self.load_button_window = self.canvas.create_window(screen_width//2, 150, anchor="center", window=self.load_button)

self.listbox = tk.Listbox(self, width=80, height=15, bg="#424242", fg="#FFFFFF", selectbackground="#FF5722")
self.listbox_window = self.canvas.create_window(screen_width//2, 300, anchor="center", window=self.listbox)

self.controls_frame = tk.Frame(self, bg="#212121")
self.controls_frame_window = self.canvas.create_window(screen_width//2, 450, anchor="center", window=self.controls_frame)

button_style = {'width': 6, 'height': 1}

self.play_button = ttk.Button(self.controls_frame, text="Play", command=self.play_selected)
self.play_button.pack(side=tk.LEFT, padx=5, pady=5)

self.pause_button = ttk.Button(self.controls_frame, text="Pause", command=self.pause_audio)
self.pause_button.pack(side=tk.LEFT, padx=5, pady=5)

self.play_all_button = ttk.Button(self.controls_frame, text="Play All", command=self.play_all)
self.play_all_button.pack(side=tk.LEFT, padx=5, pady=5)

self.skip_back_button = ttk.Button(self.controls_frame, text="Skip Back", command=self.skip_back)
self.skip_back_button.pack(side=tk.LEFT, padx=5, pady=5)

self.skip_forward_button = ttk.Button(self.controls_frame, text="Skip Forward", command=self.skip_forward)
self.skip_forward_button.pack(side=tk.LEFT, padx=5, pady=5)

self.shuffle_button = ttk.Button(self.controls_frame, text="Shuffle", command=self.shuffle_playlist)
self.shuffle_button.pack(side=tk.LEFT, padx=5, pady=5)

self.save_button = ttk.Button(self.controls_frame, text="Save Playlist", command=self.save_playlist)
self.save_button.pack(side=tk.LEFT, padx=5, pady=5)

self.load_playlist_button = ttk.Button(self.controls_frame, text="Load Playlist", command=self.load_saved_playlist)
self.load_playlist_button.pack(side=tk.LEFT, padx=5, pady=5)

self.volume_label = tk.Label(self, text="Volume:", fg="#FFFFFF", bg="#212121")
self.volume_label_window = self.canvas.create_window(200, 500, anchor="center", window=self.volume_label)

self.volume_slider = tk.Scale(self, from_=0, to=100, orient=tk.HORIZONTAL, command=self.set_volume, length=300)
self.volume_slider.set(50)
self.volume_slider_window = self.canvas.create_window(screen_width//2, 550, anchor="center", window=self.volume_slider)

self.equalizer_frame = tk.Frame(self, bg="#212121")
self.equalizer_frame_window = self.canvas.create_window(screen_width//2, 600, anchor="center", window=self.equalizer_frame)

self.equalizer = vlc.AudioEqualizer()
self.create_equalizer_controls()

self.playlist = None
self.current_index = None
self.audio_urls = []
self.media_list = None
self.media_player = None

self.last_playlists_file = "last_playlists.json"
self.last_playlists = []

# Bindings for moving and resizing
self.bind_events()

def bind_events(self):
for widget in [self.label, self.playlist_id_entry, self.load_button, self.listbox, self.controls_frame, self.volume_label, self.volume_slider, self.equalizer_frame]:
widget.bind("", self.on_widget_click)
widget.bind("", self.on_drag)
widget.bind("", self.on_release)
widget.bind("", self.on_enter)
widget.bind("", self.on_leave)

self.drag_data = {"x": 0, "y": 0, "widget": None}
self.resize_data = {"resizing": False, "widget": None, "direction": None}

def on_widget_click(self, event):
widget = event.widget
self.drag_data["widget"] = widget
self.drag_data["x"] = event.x
self.drag_data["y"] = event.y
if self.resize_data["resizing"]:
self.resize_data["widget"] = widget

def on_drag(self, event):
widget = self.drag_data["widget"]
if widget and not self.resize_data["resizing"]:
x = widget.winfo_x() + event.x - self.drag_data["x"]
y = widget.winfo_y() + event.y - self.drag_data["y"]
widget.place(x=x, y=y)
elif self.resize_data["resizing"]:
self.resize_widget(event)

def on_release(self, event):
self.drag_data["widget"] = None
self.resize_data["resizing"] = False

def on_enter(self, event):
widget = event.widget
widget.update_idletasks()
bbox = widget.winfo_geometry().split('+')[0].split('x')
width = int(bbox[0])
height = int(bbox[1])

if abs(event.x - width) < 5 or abs(event.y - height) < 5:
self.canvas.config(cursor="sizing")
self.resize_data["resizing"] = True
else:
self.canvas.config(cursor="")

def on_leave(self, event):
self.canvas.config(cursor="")

def resize_widget(self, event):
widget = self.resize_data["widget"]
widget.update_idletasks()
width = widget.winfo_width()
height = widget.winfo_height()

if abs(event.x - width) < 5:
widget.config(width=event.x)
elif abs(event.y - height) < 5:
widget.config(height=event.y)

def load_playlist(self):
def load_playlist_async():
try:
playlist_id = self.playlist_id_entry.get().split('&')[0]
if not playlist_id:
messagebox.showerror("Error", "Please enter a valid playlist ID")
return

playlist_url = f"https://www.youtube.com/playlist?list={playlist_id}"
self.playlist = self.get_playlist_videos(playlist_url)

self.listbox.delete(0, tk.END)
for title in [video['title'] for video in self.playlist]:
self.listbox.insert(tk.END, title)

self.current_index = 0
except Exception as e:
print(f"Error loading playlist: {e}")
messagebox.showerror("Error", f"Failed to load playlist: {e}")

threading.Thread(target=load_playlist_async).start()

def get_playlist_videos(self, playlist_url):
ydl_opts = {
'extract_flat': True,
'quiet': True,
'force_generic_extractor': True
}
with YoutubeDL(ydl_opts) as ydl:
result = ydl.extract_info(playlist_url, download=False)
if 'entries' in result:
return result['entries']
else:
return []

def play_all(self):
def play_all_async():
try:
if not self.playlist:
messagebox.showerror("Error", "Please load a playlist first")
return
self.current_index = 0
self.play_current_index()
except Exception as e:
print(f"Error in play_all: {e}")
threading.Thread(target=play_all_async).start()

def play_selected(self):
def play_selected_async():
try:
if not self.playlist:
messagebox.showerror("Error", "Please load a playlist")
return
selected_index = self.listbox.curselection()
if selected_index:
self.current_index = selected_index[0]
self.play_current_index()
except Exception as e:
print(f"Error in play_selected: {e}")
threading.Thread(target=play_selected_async).start()

def play_current_index(self):
def play_current_index_async():
try:
if self.current_index is None or self.current_index >= len(self.playlist):
messagebox.showerror("Error", "Please select a valid video")
return
video_url = f"https://www.youtube.com/watch?v={self.playlist[self.current_index]['id']}"
audio_url = self.get_best_audio_url(video_url)
media = self.vlc_instance.media_new(audio_url)
self.player.set_media(media)
self.set_volume(self.volume_slider.get())
self.player.play()
self.highlight_current_song()
except Exception as e:
print(f"Error in play_current_index: {e}")

threading.Thread(target=play_current_index_async).start()

def get_best_audio_url(self, video_url):
ydl_opts = {
'format': 'bestaudio',
'quiet': True
}
with YoutubeDL(ydl_opts) as ydl:
info_dict = ydl.extract_info(video_url, download=False)
return info_dict['url']

def highlight_current_song(self):
try:
self.listbox.select_clear(0, tk.END)
self.listbox.select_set(self.current_index)
self.listbox.activate(self.current_index)
except Exception as e:
print(f"Error in highlight_current_song: {e}")

def pause_audio(self):
try:
if self.player.is_playing():
self.player.pause()
except Exception as e:
print(f"Error in pause_audio: {e}")

def on_song_end(self, event):
self.current_index += 1
if self.current_index < len(self.playlist):
self.play_current_index()

def skip_forward(self):
try:
if self.current_index is not None:
self.current_index = (self.current_index + 1) % len(self.playlist)
self.play_current_index()
except Exception as e:
print(f"Error in skip_forward: {e}")

def skip_back(self):
try:
if self.current_index is not None:
self.current_index = (self.current_index - 1) % len(self.playlist)
self.play_current_index()
except Exception as e:
print(f"Error in skip_back: {e}")

def shuffle_playlist(self):
try:
if self.playlist:
random.shuffle(self.playlist)
self.listbox.delete(0, tk.END)
for video in self.playlist:
self.listbox.insert(tk.END, video['title'])
self.current_index = 0
except Exception as e:
print(f"Error in shuffle_playlist: {e}")

def set_volume(self, volume):
try:
self.player.audio_set_volume(int(volume))
except Exception as e:
print(f"Error in set_volume: {e}")

def save_playlist(self):
try:
playlist_id = self.playlist_id_entry.get().split('&')[0]
self.load_last_playlists()
if playlist_id and playlist_id not in self.last_playlists:
self.last_playlists.append(playlist_id)
with open(self.last_playlists_file, "w") as file:
json.dump(self.last_playlists, file)
messagebox.showinfo("Success", "Playlist saved successfully")
else:
messagebox.showinfo("Info", "Playlist is already saved")
except Exception as e:
print(f"Error in save_playlist: {e}")

def load_last_playlists(self):
try:
if os.path.exists(self.last_playlists_file):
with open(self.last_playlists_file, "r") as file:
self.last_playlists = json.load(file)
else:
self.last_playlists = []
except Exception as e:
print(f"Error in load_last_playlists: {e}")

def load_saved_playlist(self):
try:
self.load_last_playlists()
if not self.last_playlists:
messagebox.showinfo("Info", "No saved playlists found")
return

playlist_id = random.choice(self.last_playlists)
self.playlist_id_entry.delete(0, tk.END)
self.playlist_id_entry.insert(0, playlist_id)
self.load_playlist()
except Exception as e:
print(f"Error in load_saved_playlist: {e}")

def create_equalizer_controls(self):
labels = ["60Hz", "170Hz", "310Hz", "600Hz", "1kHz", "3kHz", "6kHz", "12kHz", "14kHz", "16kHz"]
for i, label in enumerate(labels):
lbl = tk.Label(self.equalizer_frame, text=label, fg="#FFFFFF", bg="#212121")
lbl.grid(row=0, column=i, padx=2, pady=2)

scale = tk.Scale(self.equalizer_frame, from_=-20, to=20, orient=tk.HORIZONTAL, length=70, command=lambda val, idx=i: self.set_equalizer_band(idx, val))
scale.grid(row=1, column=i, padx=2, pady=2)

def set_equalizer_band(self, band, value):
try:
self.equalizer.set_amp_at_index(float(value), band)
self.player.set_equalizer(self.equalizer)
except Exception as e:
print(f"Error setting equalizer band: {e}")

if __name__ == "__main__":
app = YouTubeJukebox()
app.mainloop()



Подробнее здесь: https://stackoverflow.com/questions/785 ... -ui-issues
Реклама
Ответить Пред. темаСлед. тема

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

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

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

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

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

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