最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

python - Phantom click and hover issue when opening a second window in my Tkinter + CustomTkinter application? What do I do? - S

programmeradmin7浏览0评论
  • Is there a way to properly isolate hover and click events so that they only apply to the currently active window?

  • Is there some class-related solution that can prevent this event contamination?

I’m encountering a phantom click and hover issue when opening a second window in my Tkinter + CustomTkinter application.

Please note: I am working with MacOS and my Python Version is 3.11.

Steps to Reproduce the Issue:

  1. Run the program.
  2. Click the "Phenotype Selection" button to open the new window.
  3. Click somewhere on the main GUI, preferably on the edge of the window.
  4. Without clicking inside the Phenotype Selection window, move your mouse over it.

What Happens:

  1. The hover effects from the main GUI's buttons get triggered even though the cursor is on the second window.
  2. It appears that hover and click events are leaking between windows.
  3. The main application (MainApp) uses overrideredirect(True), meaning it manually handles hover events, but it gets confused when another window is open.

Additional Observations:

  1. The second window does not use overrideredirect(True), and it behaves normally.
  2. However, the main GUI starts incorrectly registering hover events, even though the mouse is on the second window.
  3. We have tried multiple fixes, but nothing has worked.
import tkinter as tk
import customtkinter as ctk
from tkinterdnd2 import DND_FILES, TkinterDnD  # Use this import for drag-and-drop support

ctk.set_appearance_mode("Dark")
ctk.set_default_color_theme("blue")

class LayoutBarApp(ctk.CTkFrame):
  """ Main Layout Bar with custom buttons. """
  def __init__(self, parent):
      super().__init__(parent)
      self.pack_propagate(False)
      self.pack(side="top", fill="x")
      self.active_button = None
      self.buttons = {}

      # Create layout buttons
      self.create_layout_buttons()

  def open_phenotype_selection_window(self):
      """ Opens a new window for Phenotype Selection. """
      if hasattr(self, "phenotype_window") and self.phenotype_window.winfo_exists():
          self.phenotype_window.lift()  # Bring existing window to front
          return

      self.phenotype_window = ctk.CTkToplevel(self)  # Use CTkToplevel for consistency with CTk
      self.phenotype_window.title("Phenotype Selection")
      self.phenotype_window.geometry("400x300+400+100")  # Adjust size/position as needed
      self.phenotype_window.resizable(False, False)

      # Add a label
      label = ctk.CTkLabel(self.phenotype_window, text="Select Phenotype", font=("Arial", 16, "bold"))
      label.pack(pady=10)

      # Example: Button inside the new window
      close_button = ctk.CTkButton(self.phenotype_window, text="Close", command=self.phenotype_window.destroy)
      close_button.pack(pady=10)


  def create_layout_buttons(self):
      """ Create buttons with their icons and commands. """
      button_actions = {
          "Order Search": None,
          "Phenotype Selection": self.open_phenotype_selection_window,  # ✅ Assigned function
          "Bounding Box": None,
          "Landmark Movement": None,
          "Face Measurement": None,
      }

      for btn_text, action in button_actions.items():

          button = ctk.CTkButton(
              self,
              text=btn_text.replace(" ", "\n"),
              command=lambda b=btn_text, action=action: self.activate_button(b, action),  # ✅ Corrected lambda

              fg_color=("#3b8ed0", "#1f6aa5"),
              hover_color=("#2a75c0", "#155a8a")
          )
          button.pack(side="left", padx=(5, 0), pady=5)
          self.buttons[btn_text] = button


  def activate_button(self, button_name, action):
      """ Handles button activation (highlighting) and executes the assigned action. """

      # ✅ Get the actual root coordinates to adjust hover issues
      root_x = self.winfo_rootx()
      root_y = self.winfo_rooty()

      mouse_x = self.winfo_pointerx() - root_x
      mouse_y = self.winfo_pointery() - root_y

      print(f"Mouse Position Adjusted: ({mouse_x}, {mouse_y}), Button:{button_name} Self:{self}, Action{action}")  # ✅ Debugging hover issue

      # Reset previous button color
      if self.active_button:
          self.buttons[self.active_button].configure(
              fg_color=("#3b8ed0", "#1f6aa5"),
              hover_color=("#2a75c0", "#155a8a")
          )

      # Set new active button
      self.active_button = button_name
      self.buttons[button_name].configure(
          fg_color="green",
          hover_color="#006400"
      )
      # Execute the function if it exists
      if action:
          action()

class MainApp(TkinterDnD.Tk):  
  """ Root Tkinter App holding both Sidebar and Layout Bar. """
  def __init__(self):
      super().__init__()

      self.overrideredirect(True)  # Removes system title bar
      self.geometry("782x60+330+0")
      self.resizable(False, False)
      self.title("GUI")

      # Main Layout Bar
      self.layout_bar = LayoutBarApp(self)

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

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论