Kann mir jemand helfen, herauszufinden, wie ich ein Menü-Widget dort anzeigen kann, wo sich eine Schaltfläche befindet?
Ich arbeite an einer Anwendung, die mithilfe von yt-dlp Videos aus dem Internet herunterlädt (ich befürworte keine Piraterie, möchte das nur klarstellen). Jeder Download innerhalb einer Liste verfügt über eine Schaltfläche, die ein Menü öffnet. Allerdings wird jedes Mal, wenn ich auf diese Schaltfläche klicke, das Menü in der oberen linken Ecke meines Bildschirms geöffnet und nicht dort, wo sich die Schaltfläche befindet.
from tkinter import *
from tkinter import ttk
from swiperdl.utils.gui import get_icon, load_image_tkinter
class DownloadItem(ttk.Frame):
"""Class for a displayed download item"""
def __init__(self, master=None, title: str = "", dl_path: str = "", url: str = "", status: str = "", progress: dict = None) -> None:
super().__init__(master)
self.title = StringVar()
self.title.set(title)
self.window_coords: dict = {
"x": 0,
"y": 0
}
self.dl_path = dl_path
self.url = url
self.status = status
self.status_text = StringVar()
self.progress_bytes = IntVar()
self.progress_bytes.set(progress.get("bytes", 0))
self.progress_total = progress.get("total", 100)
self.setup_widgets()
def setup_widgets(self) -> None:
self.title_display = ttk.Label(self, textvariable=self.title)
self.status_display = ttk.Label(self, textvariable=self.status_text)
self.progress_bar = ttk.Progressbar(self, orient="horizontal", length=200, mode="determinate", variable=self.progress_bytes, maximum=self.progress_total)
self.info_button = ttk.Button(self, text="...", command=self.open_info_menu)
self.title_display.pack(side="left", anchor="center", padx=50)
self.status_display.pack(side="left", anchor="center", padx=50)
self.progress_bar.pack(side="left", anchor="center", padx=50)
self.info_button.pack(side="right", anchor="center", padx=50)
self.info_menu = Menu(self.info_button)
self.info_menu.add_command(label="Open with associated application")
self.info_menu.add_command(label="Open download link")
self.info_menu.add_command(label="View output")
self.info_menu.add_command(label="Cancel download")
self.info_menu.add_command(label="Remove from list")
def open_info_menu(self) -> None:
self.info_menu.tk_popup(self.window_coords["x"], self.window_coords["y"])
class MainWindow(Tk):
"""Class for the main window GUI."""
def __init__(self) -> None:
super().__init__()
# Basic window settings
self.title("SwiperDL")
self.icon = load_image_tkinter(get_icon("swiperdl"))
self.wm_iconphoto(True, self.icon)
self.geometry("1480x800")
self.protocol("WM_DELETE_WINDOW", self.close)
# A list of predefined formats to choose from.
self.formats = [
...
]
# A list of downloads to be displayed.
# Just a sample, I won't use this in production.
self.downloads = [
{
"title": "Me at the zoo.mp4",
"dl_path": "/home//Me at the zoo.mp4",
"status": "downloading",
"url": "https://www.youtube.com/watch?v=jNQXAC9IVRw",
"progress": {
"bytes": 0,
"total": 100
}
}
]
self.detect_clipboard = StringVar() # Configuration for automatic clipboard detection.
self.selected_format = StringVar() # Holds the selected format to download using the backend.
self.selected_format.set(self.formats[0])
# Start creating the widgets
self.create_menu()
self.create_widgets()
def create_widgets(self) -> None:
self.main_frame = ttk.Frame(self)
self.main_frame.pack(anchor="center", side="top", expand=True, fill="both")
self.toolbar = ttk.Frame(self.main_frame)
self.toolbar.pack(side="top", anchor="n", fill="x", ipady=20)
self.toolbar_left_spacer = ttk.Frame(self.toolbar, height=1)
self.toolbar_left_spacer.pack(side="left", anchor="w", expand=True, fill="y")
self.url_bar = ttk.Frame(self.toolbar, height=125)
self.clipboard_toggle_icon = load_image_tkinter(get_icon("clipboard_enabled"))
self.clipboard_toggle = ttk.Button(self.url_bar, text="Toggle Clipboard", image=self.clipboard_toggle_icon)
self.clipboard_toggle.pack(side="left", anchor="w")
self.default_text = StringVar()
self.default_text.set("Enter URL or search query here")
self.url_field = ttk.Entry(self.url_bar, textvariable=self.default_text)
self.url_field.pack(side="right", anchor="e", fill="x", padx=50, ipadx=86)
self.url_bar.pack(side="left", anchor="center", expand=False, ipadx=10)
self.basic_config_frame = ttk.Frame(self.toolbar, height=125)
self.basic_config_frame.pack(side="left", anchor="e")
self.format_selection_box = ttk.Combobox(self.basic_config_frame, textvariable=self.selected_format, value=self.formats)
self.format_selection_box.pack(side="left", anchor="w", padx=25)
self.cookies_icon = load_image_tkinter(get_icon("cookies"))
self.cookies_from_browser_toggle = ttk.Button(self.basic_config_frame, text="Use browser cookies", image=self.cookies_icon)
self.cookies_from_browser_toggle.pack(side="left", anchor="e")
self.metadata_icon = load_image_tkinter(get_icon("metadata_enabled"))
self.extract_metadata_toggle = ttk.Button(self.basic_config_frame, text="Extract metadata", image=self.metadata_icon)
self.extract_metadata_toggle.pack(side="left", anchor="e")
self.settings_icon = load_image_tkinter(get_icon("settings"))
self.toolbar_settings_shortcut = ttk.Button(self.basic_config_frame, text="Open settings", image=self.settings_icon)
self.toolbar_settings_shortcut.pack(side="left", anchor="e")
self.toolbar_right_spacer = ttk.Frame(self.toolbar, height=1)
self.toolbar_right_spacer.pack(side="right", anchor="e", expand=True, fill="y")
self.toolbar_separator = ttk.Separator(self.main_frame, orient="horizontal")
self.toolbar_separator.pack(side="top", anchor="n", fill="x")
self.centre_frame = ttk.Frame(self.main_frame)
self.centre_frame.pack(side="top", anchor="center", expand=True, fill="both")
self.download_view_frame = ttk.Frame(self.centre_frame)
self.download_view_frame.pack(side="top", anchor="center", expand=True, fill="both")
for dl in self.downloads:
self.download = DownloadItem(self.download_view_frame, dl.get("title", ""), dl.get("dl_path", ""), dl.get("url", ""), dl.get("status", ""), dl.get("progress", {"bytes": 0, "total": 0}))
self.download.pack(side="top", anchor="n", fill="x")
def create_menu(self) -> None:
# This is to make sure the menu stays in place.
self.option_add("*tearOff", FALSE)
self.menubar = Menu()
self['menu'] = self.menubar
# Menu for doing stuff with the program
self.appmenu = Menu(self.menubar)
self.appmenu.add_command(label="Add download")
self.appmenu.add_checkbutton(label="Clipboard detection", variable=self.detect_clipboard,
onvalue=1, offvalue=0)
self.appmenu.add_separator()
self.appmenu.add_command(label="Open settings")
self.appmenu.add_separator()
self.appmenu.add_command(label="Quit", command=self.close)
self.menubar.add_cascade(label="SwiperDL", menu=self.appmenu)
# Menu for getting information about the program
self.aboutmenu = Menu(self.menubar)
self.aboutmenu.add_command(label="About SwiperDL")
self.aboutmenu.add_separator()
self.aboutmenu.add_command(label="Support")
self.aboutmenu.add_command(label="Website")
self.aboutmenu.add_command(label="GitHub")
self.aboutmenu.add_command(label="PyPI.org")
self.menubar.add_cascade(label="About", menu=self.aboutmenu)
def open(self) -> None:
self.mainloop()
def close(self) -> None:
self.destroy()
Wenn mir jemand einen Rat geben könnte, wäre ich sehr dankbar!
Vielen Dank
EDIT: Der Code funktioniert jetzt wie erwartet dank https://stackoverflow.com/a/79865318.
Kann mir jemand helfen, herauszufinden, wie ich ein Menü-Widget dort anzeigen kann, wo sich eine Schaltfläche befindet? Ich arbeite an einer Anwendung, die mithilfe von yt-dlp Videos aus dem Internet herunterlädt (ich befürworte keine Piraterie, möchte das nur klarstellen). Jeder Download innerhalb einer Liste verfügt über eine Schaltfläche, die ein Menü öffnet. Allerdings wird jedes Mal, wenn ich auf diese Schaltfläche klicke, das Menü in der oberen linken Ecke meines Bildschirms geöffnet und nicht dort, wo sich die Schaltfläche befindet. [code]from tkinter import * from tkinter import ttk
from swiperdl.utils.gui import get_icon, load_image_tkinter
class MainWindow(Tk): """Class for the main window GUI.""" def __init__(self) -> None: super().__init__() # Basic window settings self.title("SwiperDL") self.icon = load_image_tkinter(get_icon("swiperdl")) self.wm_iconphoto(True, self.icon) self.geometry("1480x800") self.protocol("WM_DELETE_WINDOW", self.close)
# A list of predefined formats to choose from. self.formats = [ ... ]
# A list of downloads to be displayed. # Just a sample, I won't use this in production. self.downloads = [ { "title": "Me at the zoo.mp4", "dl_path": "/home//Me at the zoo.mp4", "status": "downloading", "url": "https://www.youtube.com/watch?v=jNQXAC9IVRw", "progress": { "bytes": 0, "total": 100 } } ]
self.detect_clipboard = StringVar() # Configuration for automatic clipboard detection. self.selected_format = StringVar() # Holds the selected format to download using the backend. self.selected_format.set(self.formats[0])
# Start creating the widgets self.create_menu() self.create_widgets()
def create_menu(self) -> None: # This is to make sure the menu stays in place. self.option_add("*tearOff", FALSE)
self.menubar = Menu() self['menu'] = self.menubar
# Menu for doing stuff with the program self.appmenu = Menu(self.menubar) self.appmenu.add_command(label="Add download") self.appmenu.add_checkbutton(label="Clipboard detection", variable=self.detect_clipboard, onvalue=1, offvalue=0) self.appmenu.add_separator() self.appmenu.add_command(label="Open settings") self.appmenu.add_separator() self.appmenu.add_command(label="Quit", command=self.close) self.menubar.add_cascade(label="SwiperDL", menu=self.appmenu)
# Menu for getting information about the program self.aboutmenu = Menu(self.menubar) self.aboutmenu.add_command(label="About SwiperDL") self.aboutmenu.add_separator() self.aboutmenu.add_command(label="Support") self.aboutmenu.add_command(label="Website") self.aboutmenu.add_command(label="GitHub") self.aboutmenu.add_command(label="PyPI.org") self.menubar.add_cascade(label="About", menu=self.aboutmenu)
def open(self) -> None: self.mainloop()
def close(self) -> None: self.destroy() [/code] Wenn mir jemand einen Rat geben könnte, wäre ich sehr dankbar! :) Vielen Dank EDIT: Der Code funktioniert jetzt wie erwartet dank https://stackoverflow.com/a/79865318.
Ich habe die PIP-Installation für Twilio gemacht und das Terminal hat den größten Teil der Installation durchgeführt, aber am Ende gab es mir im Installationsfehlercode:
ERROR: Could not install...
Ich versuche, eine Szene mit Open3D mit O3D.visualization.Rendering.Offscreenrenderer
zu rendern. EGL headless mode enabled.
FEngine (64 bits) created at 0x2fa3d850 (threading is enabled)
EGL(1.5)...
Unangenehm, qvariant { test }. canconvert () true zurück. Aber ich kann diese Funktion in einer Vorlagenklasse nicht verwenden, wenn ich den Typ nicht kenne.
Ich versuche, ein Bild in einem Tkinter-Fenster anzuzeigen. Das ist mir in der Vergangenheit gelungen, aber irgendwie scheitert mein aktueller Versuch auf Schritt und Tritt. Hoffentlich kann mir...