CTkScrollableDropdown icon indicating copy to clipboard operation
CTkScrollableDropdown copied to clipboard

CTkScrollableDropdownFrame place_dropdown bug

Open teijiIshida opened this issue 1 year ago • 1 comments

I was testing both CTkScrollableDropdown and CTkScrollableDropdownFrame. CTkScrollableDropdownFrame is faster than CTkScrollableDropdown, so I decide to use it. However, CTkScrollableDropdownFrame has a bug with place_dropdown. If I have my CTkOptionMenu on top of a fixed frame, then its placement is correct. But if the CTkOptionMenu is on a non-fixed frame, then the dropdown placement is incorrect (see picture below). If you need additional info, let me know.

top_frame (fixed): place correctly 2024-07-24 14_50_12-Vulcan py - TGMAIN - Visual Studio Code

main_frame (non-fixed): place wrong bug

This is the relevant code provided by your CTkDesigner app.

    def switch_page(self, page) -> None:
        pages: list[ctk.CTkFrame] = [self.Page_1, self.Page_2, self.Page_3, self.Page_4]

        for i in pages:
            i.pack_forget()
        
        page.pack(expand=True, fill='both')

        fixed_widgets: list[ctk.CTkFrame] = [self.top_frame]
        for widget in fixed_widgets:
            widget.lift()
            widget.place(x=widget.winfo_x(), y=widget.winfo_y())

teijiIshida avatar Jul 24 '24 19:07 teijiIshida

I figured out the real issue. The place_down method only determines the correct y position if the widget (CTkOptionMenu) is in the main window. If the widget is in a frame, then its y position won't be correct. I've modified the place_down code to check the widget's parent and set its position accordingly, which seems to work (it doesn't account for self.y but I don't use it). You may need to improve the code if you plan to use it.

parent and attach

def place_dropdown(self):
    self.x_pos = self.attach.winfo_x() if self.x is None else self.x + self.attach.winfo_rootx()
    self.y_pos = self.attach.winfo_y() + self.attach.winfo_reqheight() + 5 if self.y is None else self.y + self.attach.winfo_rooty()
    self.width_new = self.attach.winfo_width() - 45 + self.corner if self.width is None else self.width

    # Determine the parent widget of self.attach
    parent_name = self.attach.winfo_parent()
    parent_widget = self.nametowidget(parent_name)

    # Check if the parent widget is a frame
    if isinstance(parent_widget, customtkinter.CTkFrame):
        self.x_pos = parent_widget.winfo_x() + self.attach.winfo_x()
        self.y_pos = parent_widget.winfo_y() + self.attach.winfo_y() + self.attach.winfo_reqheight() + 5

    if self.resize:
        if self.button_num <= 5:
            self.height_new = self.button_height * self.button_num + 55
        else:
            self.height_new = self.button_height * self.button_num + 35
        if self.height_new > self.height:
            self.height_new = self.height

    self.frame.configure(width=self.width_new, height=self.height_new)
    self.frame._scrollbar.configure(height=self.height_new)
    self.place(x=self.x_pos, y=self.y_pos)

    if sys.platform.startswith("darwin"):
        self.dummy_entry.pack()
        self.after(100, self.dummy_entry.pack_forget())

    self.lift()
    self.attach.focus()

teijiIshida avatar Jul 27 '24 02:07 teijiIshida