Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!
  • Guest, before posting your code please take these rules into consideration:
    • It is required to use our BBCode feature to display your code. While within the editor click < / > or >_ and place your code within the BB Code prompt. This helps others with finding a solution by making it easier to read and easier to copy.
    • You can also use markdown to share your code. When using markdown your code will be automatically converted to BBCode. For help with markdown check out the markdown guide.
    • Don't share a wall of code. All we want is the problem area, the code related to your issue.


    To learn more about how to use our BBCode feature, please click here.

    Thank you, Code Forum.

Python I don't know why my widgets are overlapping, can you help me out?

Tim Zheng

New Coder
How to find the problem:
1. click the translate button (you can see the original GUI)
2. click the settings button
3. click the translate button again

and you can find some parts of stuff of overlapping

(btw, my project isn't finished yet, so don't need to care about other problems, thanks)

code below:
Code:
import customtkinter as ctk

import tkinter

import customtkinter

import tkinter as tk

from mdict import MDict

Opendict = customtkinter.CTk()

#Main settings___

Opendict.title("OpenDict")

Opendict.geometry("1000x600")

# 初始外观颜色

appearance_color = "dark"

theme_color = "blue"

Font = "Microsoft YaHei"

customtkinter.set_appearance_mode(str(appearance_color))

customtkinter.set_default_color_theme(str(theme_color))

#_Top bar

# Function to perform search (action when clicking the search button)

def search():

    query = search_entry.get()  # Get the input from the search entry

    print(f"Search Query: {query}")  # Print the search query (or handle search logic)

# Create an entry widget (search bar) for input

open_dict_label = ctk.CTkLabel(Opendict, text="OpenDict", font=(str(Font), 14, "bold"))

open_dict_label.pack(side="left", padx=8, pady=4, anchor=tkinter.NW)

search_entry = ctk.CTkEntry(Opendict, width=200, placeholder_text="Search here...")

search_entry.pack(side="left", padx=4, pady=5, anchor=tkinter.NW)

# Create a search button to trigger the search function

search_button = ctk.CTkButton(Opendict, width=20, text="🔍", command=search)

search_button.pack(side="left", padx=5, pady=5, anchor=tkinter.NW)



#__Left --> Right_



#————————————————————————Settings settings————————————————————————————————————

is_settings_button_clicked = False

def settings_button_clicked():

    global is_settings_button_clicked, Meaning_Bar_right

    is_settings_button_clicked = not is_settings_button_clicked

    if is_settings_button_clicked:

        Meaning_Bar_right = ctk.CTkFrame(Opendict, width=470, height=540, corner_radius=20)

        Meaning_Bar_right.place(x=520, y=40)

        setting_label = ctk.CTkLabel(Meaning_Bar_right, text="Settings", font=(str(Font), 16, "bold"), text_color="white", bg_color="transparent")

        setting_label.place(x=15, y=10)  # 放置在 Meaning_Bar_left 上方

        setting_label = ctk.CTkLabel(Meaning_Bar_right, text="Theme Color", font=(str(Font), 15), text_color="white", bg_color="transparent")

        setting_label.place(x=15, y=50)  # 放置在 Meaning_Bar_left 上方

        setting_label = ctk.CTkLabel(Meaning_Bar_right, text="Font Style", font=(str(Font), 15), text_color="white", bg_color="transparent")

        setting_label.place(x=15, y=100)  # 放置在 Meaning_Bar_left 上方

        setting_label = ctk.CTkLabel(Meaning_Bar_right, text="@2024 OpenDict by Tim Zheng", font=(str(Font), 10), text_color="grey", bg_color="transparent")

        setting_label.place(x=235, y=532, anchor=tkinter.CENTER)  # 放置在 Meaning_Bar_left 上方

        #________________________________________

        mode_options = ["dark", "light", "system"]

        # 创建下拉菜单变量

        global mode_variable

        mode_variable = ctk.StringVar(value=appearance_color)  # 默认选择与appearance_color相同的选项

        # 创建下拉菜单

        mode_dropdown = ctk.CTkOptionMenu(

            Meaning_Bar_right,

            variable=mode_variable,

            values=mode_options,

            command=lambda event: update_appearance_mode(mode_variable.get()),

        )

        mode_dropdown.place(x=115, y=50)

        #________________________________________

        font_options = ["Ariel", "Georgia", "Verdana", "Garamond"]

        # 创建下拉菜单变量

        global font_variable

        font_variable = ctk.StringVar(value=Font)  # 默认选择与appearance_color相同的选项

        # 创建下拉菜单

        font_dropdown = ctk.CTkOptionMenu(

            Meaning_Bar_right,

            variable=font_variable,

            values=font_options,

            command=lambda event: update_appearance_mode(font_variable.get()),

        )

        font_dropdown.place(x=115, y=100)

        #________________________________________

    else:

        Meaning_Bar_right = ctk.CTkFrame(Opendict, width=470, height=540, corner_radius=20)

        Meaning_Bar_right.place(x=520, y=40)

        if translate_button_clicked:

            Meaning_Bar_right.destroy()

            Meaning_Bar_right = ctk.CTkFrame(Opendict, width=470, height=540, corner_radius=20)

            Meaning_Bar_right.place(x=520, y=40)



Settings_button = ctk.CTkButton(Opendict, width=50, text="⚙️Settings", command=settings_button_clicked)

Settings_button.pack(side="right", padx=6, pady=5, anchor=tkinter.NE)

#————————————————————————dictionary settings————————————————————————————————————

Dictinaries_button = ctk.CTkButton(Opendict, width=60, text="📖Dictionaries", command=search)

Dictinaries_button.pack(side="right", padx=5, pady=5, anchor=tkinter.NE)

#————————————————————————translate settings————————————————————————————————————

is_translate_button_clicked = False  # 初始化布尔变量

def translate_button_clicked():

    global is_translate_button_clicked, Meaning_Bar_right

    is_translate_button_clicked = not is_translate_button_clicked  # 切换状态

    if is_translate_button_clicked:

        # 缩小 Meaning_Bar_right

        Meaning_Bar_right.place_forget()

        Meaning_Bar_right = ctk.CTkFrame(Opendict, width=470, height=540, corner_radius=20)

        Meaning_Bar_right.place(x=520, y=40)

      

        Meaning_Bar_right.destroy()

        Meaning_Bar_right_1 = ctk.CTkFrame(Opendict, width=470, height=230, corner_radius=20)

        Meaning_Bar_right_1.place(x=520, y=75)

        Meaning_Bar_right_2 = ctk.CTkFrame(Opendict, width=470, height=265, corner_radius=20)

        Meaning_Bar_right_2.place(x=520, y=315)

      

        Translate_API = ctk.CTkEntry(Opendict, width=200, placeholder_text="Enter your Translator API")

        Translate_API.place(x=520, y=40)

    else:

        # 恢复 Meaning_Bar_right 到原样

        Meaning_Bar_right.destroy()

        Meaning_Bar_right = ctk.CTkFrame(Opendict, width=470, height=540, corner_radius=20)

        Meaning_Bar_right.place(x=520, y=40)

Dictinaries_button = ctk.CTkButton(Opendict, width=60, text="🛃Translation", command=translate_button_clicked)

Dictinaries_button.pack(side="right", padx=5, pady=5, anchor=tkinter.NE)

#——————————————————————————页面————————————————————————————————————

Meaning_Bar_left = ctk.CTkFrame(Opendict, width=500, height=540, corner_radius=20)

Meaning_Bar_left.place(x=10, y=40)

# 添加文字标签

meaning_label = ctk.CTkLabel(Meaning_Bar_left, text="↓Meaning↓", font=(str(Font), 16, "bold"), text_color="white", bg_color="transparent")

meaning_label.place(x=15, y=10)  # 放置在 Meaning_Bar_left 上方

# 这里需要先创建 Meaning_Bar_right,因为在 translate_button_clicked 函数中会使用它

global Meaning_Bar_right

Meaning_Bar_right = ctk.CTkFrame(Opendict, width=460, height=535, corner_radius=20)

Meaning_Bar_right.place(x=520, y=40)

def update_appearance_mode(new_mode):

    global appearance_color

    appearance_color = new_mode

    customtkinter.set_appearance_mode(new_mode)

def update_font_style(new_mode):

    global Font

    Font = Font

    Opendict.update()

Opendict.mainloop()
 
Last edited by a moderator:
Please use bbtags when posting code as it will be easier to hold formatting.
I would recommend using a grid instead of place. Usually bad practice to use global.

I tried to get your code to run but there are way too many errors. Perhaps you can post an image of what the widget looks like.
 
Last edited:
This example is what I came up with understanding your code as best as I could.
This uses the ttkthemes module that can be downloaded using pip.

Python:
import tkinter as tk
from tkinter import ttk
import ttkthemes

class Window:
    ''' Window class handles display '''
    def __init__(self, parent):
        parent.columnconfigure(0, weight=1)
        parent.rowconfigure(0, weight=1)

        self.parent = parent

        # Container - holds all child widgets
        container = ttk.Frame(parent)
        container.grid(column=0, row=0, sticky='news')
        container.grid_columnconfigure(0, weight=2)

        #menframe
        menubar = ttk.LabelFrame(container, text='Menubar')
        menubar.grid(column=0, row=0, sticky='news')
        menubar.grid_columnconfigure(0, weight=0)
        menubar.grid_columnconfigure(1, weight=3)
        menubar.grid_columnconfigure(2, weight=2)
        menubar.grid_columnconfigure(3, weight=0)

        style = ttk.Style()
        
        self.themes = [theme.title() for theme in ttkthemes.THEMES]

        # This is the first theme in list. Don't know why but, it doesn't show in the menu if
        # not added here
        self.themes.insert(0, 'adapta')

        menuwidth = len(max(self.themes, key=len))

        self.myvar = tk.StringVar()
        self.myvar.set(1)
        
        self.dropdown = ttk.OptionMenu(menubar, self.myvar, *self.themes)
        self.dropdown.grid(column=0, row=0, padx=8, pady=8, sticky='ew')
        self.dropdown.configure(width=menuwidth)
    

        #Search field and button
        self.entry = ttk.Entry(menubar)
        self.entry.grid(column=2, row=0, sticky='news', pady=8)

        self.search_btn = ttk.Button(menubar, text='Search')
        self.search_btn.grid(column=4, row=0, padx=8, pady=8)


class Controller:
    def __init__(self, window):
        self.window = window

        # If ubuntu is in list use this for default
        # If not use index1 in list for default
        if 'ubuntu' in ttkthemes.THEMES:
            self.window.myvar.set('ubuntu')
            theme = 'ubuntu'
        else:
            theme = ttkthemes.THEMES[0]
            self.window.myvar.set(theme)


        # Configure the window theme
        self.window.parent.configure(theme=theme)
        
        # Detect if any changes in the dropdown box and call settheme function
        self.window.myvar.trace('w', self.settheme)


    
    def settheme(self, var, index, mode):
        ''' Method for changing window theme '''
        theme = self.window.myvar.get().lower()
        self.window.parent.configure(theme=theme)


if __name__ == '__main__':
    root = ttkthemes.ThemedTk()
    root.geometry('1280x740')
    controller = Controller(Window(root))
    root.mainloop()
 
Last edited:
It sounds like the overlap issue may be happening due to multiple frames or widgets stacking on top of each other when you toggle the "translate" and "settings" buttons. Here’s a breakdown of what might be happening and a potential solution:

Possible Issues:​

  1. Widget Overlap: When the translate button is clicked, you seem to add new frames (like Meaning_Bar_right_1 and Meaning_Bar_right_2) without fully removing or hiding other frames (like Meaning_Bar_right).
  2. Widget Removal: Meaning_Bar_right.destroy() is used, but if you later reuse it, it may need to be reinitialized every time, which could lead to unexpected results.
  3. Global Variables: Meaning_Bar_right and other widgets are reused across different functions, so toggling their visibility may cause conflicts.

Suggested Adjustments:​

  1. Use place_forget() Instead of destroy(): When hiding frames, use place_forget() to make them invisible rather than destroy(), especially if you plan to bring them back later. This way, the frames remain accessible in memory.
  2. Conditional Checks: Add checks within each button's function to make sure that any previously added frames are properly hidden or removed before adding new ones.
  3. Frame Management: Use a single Meaning_Bar_right frame and clear its content before adding new widgets, instead of creating new frames.

Revised Example Code for Button Functionality​

Here’s how you might update the code to handle the frame toggling more effectively:

Code:
def settings_button_clicked():
    global is_settings_button_clicked, Meaning_Bar_right
    is_settings_button_clicked = not is_settings_button_clicked
    
    # Hide any existing frames before creating the settings view
    if is_translate_button_clicked:
        Meaning_Bar_right.place_forget()
    
    if is_settings_button_clicked:
        Meaning_Bar_right.place(x=520, y=40)
        # Add your settings widgets here...
    else:
        Meaning_Bar_right.place_forget()

def translate_button_clicked():
    global is_translate_button_clicked, Meaning_Bar_right
    is_translate_button_clicked = not is_translate_button_clicked
    
    # Hide the settings frame if open
    if is_settings_button_clicked:
        Meaning_Bar_right.place_forget()
        
    if is_translate_button_clicked:
        Meaning_Bar_right.place(x=520, y=40)
        # Add your translate widgets here...
    else:
        Meaning_Bar_right.place_forget()

By using place_forget(), you’ll prevent overlap by removing frames from the interface without destroying them, which should help manage the layout better. You can add widgets for settings or translation within the respective conditional blocks to display them as needed.
 

New Threads

Latest posts

Buy us a coffee!

Back
Top Bottom