Задать вопрос
Ответы пользователя по тегу Tkinter
  • Как сделать кастомный заголовок окна в Tkinter?

    @mr_secret
    Основываясь на коде, представленном здесь и здесь, мне удалось составить работающий пример.
    Для данного примера реализованы:
    1. Отключение дефолтного заголовка окна
    2. Отображение иконки программы в панели задач
    3. Возможность открытия окна через панель задач
    4. Возможность двигать окно
    5. Возможность изменять размер окна

    Недостатки данного примера:
    1. длящееся примерно долю секунды отображение вспомогательного окна (хотя если формально - главного) при разворачивании окна через панель задач
    2. Отсутствие изображения содержимого окна при наведении мыши на иконку на панели задач
    3. Окно, если не свернуто, всегда отображается строго поверх других окон, что отличает его от обычных окон


    678f95bee1ec1622947023.png

    код:
    from tkinter import *
    from tkinter import font
    
    
    class NewRoot(Tk):
        def __init__(self):
            Tk.__init__(self)
    
    
    class MyMain(Toplevel):
        def __init__(self, master):
            Toplevel.__init__(self, master)
            self.overrideredirect(True)
            self.attributes('-topmost', 1)
            self.bind('<ButtonRelease-3>', self.on_close)  #right-click to get out
            # region geometry method
            self.set_geometry_on_center()
            # endregion
    
    
            # region Чтобы можно было двигать окно
            self.main_frm = Frame(master=self, bg='#232428')
            self.main_frm.pack(fill=BOTH, expand=True)
            self.main_frm.bind("<B1-Motion>", self.move)
            # endregion
            custom_font = font.Font(family='Impact', size=16)
            # region Кнопка закрытия окна
            Button(self.main_frm, text='x', bg='#3F3F3F', fg='white', activebackground='#C70039',
                   activeforeground='white', bd=0, highlightthickness=0, command=root.destroy, font=custom_font)\
                .pack(side='right', anchor=NE, padx=5)
            # endregion
            # region Заголовок
            header_label = Label(master=self.main_frm, text='Заголовок', font=custom_font, fg='#FFFFFF', bg='#3F3F3F')
            header_label.pack(pady=5)
            # endregion
            # region Чтобы можно было изменять размер
            self.resize_lbl = Label(master=self.main_frm, bg='#3F3F3F', fg='white', activebackground='#C70039',
                                    activeforeground='white', bd=0, highlightthickness=0,  text='resize', font=custom_font)
            self.resize_lbl.pack(anchor=E)
            self.resize_lbl.bind("<B1-Motion>", self.resize)
            # endregion
            # region Чтобы можно было свернуть
            self.minimize_lbl = Button(master=self.main_frm, bg='#3F3F3F', fg='white', activebackground='#C70039',
                                     activeforeground='white', bd=0, highlightthickness=0,  text='Свернуть', font=custom_font,
                                     command=self.minimize)
            self.minimize_lbl.pack(anchor=E)
            self.minimize_lbl.bind("<B1-Motion>", self.resize)
            # endregion
    
        def on_close(self, event) -> None:
            self.master.destroy()
    
        def set_geometry_on_center(self) -> None:  # Placing the window in the center of the screen
            rx = self.winfo_screenwidth()
            ry = self.winfo_screenheight()
            x = int((rx / 2) - (500 / 2))
            y = int((ry / 2) - (500 / 2))
            self.geometry(f"500x500+{x}+{y}")
    
        def resize(self, event) -> None:
            x = self.winfo_pointerx() - self.winfo_rootx()
            y = self.winfo_pointery() - self.winfo_rooty()
            if x > 0:
                fx = self.winfo_rootx()
                fy = self.winfo_rooty() + y
                ht = self.winfo_height() - y
                if ht > 0:
                    self.geometry(f"{x}x{ht}+{fx}+{fy}")
    
        def move(self, event) -> None:
            fx = root.winfo_pointerx() - 250
            fy = root.winfo_pointery() - 10
            self.geometry(f"{self.winfo_width()}x{self.winfo_height()}+{fx}+{fy}")
    
        def minimize(self):  # свернуть
            self.state('withdrawn')
    
    
    def func(event):
        app.state('normal')
        root.iconify()
    
    
    if __name__ == '__main__':
    
        root = NewRoot()
        root.lower()
        root.iconify()
    
        app = MyMain(root)
        root.bind("<Map>", func)
    
        app.mainloop()
    Ответ написан