使用Tkinter移动自定义标题栏窗口,而无需从左上角移动

Aleks K.

大家,新年快乐,

因此,我对Python还是陌生的,甚至对Tkinter也不陌生。我正在尝试为我的UI创建自定义标题栏,到目前为止,我已经使用一些文章和视频了。问题在于,当创建“自定义标题”栏并尝试移动窗口时,它会从左上角移动,从而“传送”窗口。

查看此内容:线程对我的问题有答案,但我无法使它正常工作。

所以这是代码:

from Tkinter import *

root = Tk()
# turns off title bar, geometry
root.overrideredirect(True)
# set new geometry
root.geometry('400x100+200+200')
# set background color of title bar
back_ground = "#2c2c2c"

# set background of window
content_color = "#ffffff"
# make a frame for the title bar
title_bar = Frame(root, bg=back_ground, relief='raised', bd=1, 
highlightcolor=back_ground,highlightthickness=0)

# put a close button on the title bar
close_button = Button(title_bar, text='x',  command=root.destroy,bg=back_ground, padx=5, pady=2, 
activebackground="red", bd=0,    font="bold", fg='white',        activeforeground="white", 
highlightthickness=0)
# window title
title_window = "Title Name"
title_name = Label(title_bar, text=title_window, bg=back_ground, fg="white")
# a canvas for the main area of the window
window = Canvas(root, bg="white", highlightthickness=0)

# pack the widgets
title_bar.pack(expand=1, fill=X)
title_name.pack(side=LEFT)
close_button.pack(side=RIGHT)
window.pack(expand=1, fill=BOTH)
x_axis = None
y_axis = None
# bind title bar motion to the move window function

xwin = root.winfo_x()
ywin = root.winfo_y()

def get_pos(event):

    global xwin
    global ywin

    xwin = xwin - event.x_root
    ywin = ywin - event.y_root

def move_window(event):
    root.geometry(f'+{event.x_root - xwin}+{event.y_root}')

def change_on_hovering(event):
    global close_button
    close_button['bg'] = 'red'

def return_to_normal_state(event):
   global close_button
   close_button['bg'] = back_ground

title_bar.bind("<B1-Motion>", move_window)
title_bar.bind("<Button-1>", get_pos)
close_button.bind('<Enter>', change_on_hovering)
close_button.bind('<Leave>', return_to_normal_state)
root.mainloop()

在此版本中,它与上面的线程显示的内容有些不同,因为我一直以其他方式接收错误。问题在于,现在该窗口会传送到一个新位置,而我无法使其正常工作。

先感谢您!

简单

我使用时代码对我有用

def get_pos(event):

    global xwin
    global ywin

    xwin = event.x
    ywin = event.y

而你忘ywin

def move_window(event):
    root.geometry(f'+{event.x_root - xwin}+{event.y_root - ywin}')

编辑:

完整的工作代码和重新组织的代码。

在Python 3上进行了测试,因此我不得不使用tkinter代替Tkinter

PEP 8-Python代码样式指南

#from tkinter import *  # PEP8: `import *` is not preferred
import tkinter as tk

# --- classes ---

# empty

# --- functions ---

def get_pos(event):
    global xwin
    global ywin

    xwin = event.x
    ywin = event.y

def move_window(event):
    root.geometry(f'+{event.x_root - xwin}+{event.y_root - ywin}')

def change_on_hovering(event):
    close_button['bg'] = 'red'

def return_to_normal_state(event):
    close_button['bg'] = back_ground

# --- main ---

# set background color of title bar
back_ground = "#2c2c2c"
# set background of window
content_color = "#ffffff"

# ---

root = tk.Tk()
# turns off title bar, geometry
root.overrideredirect(True)

# set new geometry
root.geometry('400x100+200+200')

# make a frame for the title bar
title_bar = tk.Frame(root, bg=back_ground, relief='raised', bd=1, 
                     highlightcolor=back_ground, 
                     highlightthickness=0)

# put a close button on the title bar
close_button = tk.Button(title_bar, text='x', bg=back_ground, padx=5, pady=2, 
                         bd=0, font="bold", fg='white',
                         activebackground="red",
                         activeforeground="white", 
                         highlightthickness=0, 
                         command=root.destroy)
                         
# window title
title_window = "Title Name"
title_name = tk.Label(title_bar, text=title_window, bg=back_ground, fg="white")

# a canvas for the main area of the window
window = tk.Canvas(root, bg="white", highlightthickness=0)

# pack the widgets
title_bar.pack(expand=True, fill='x')
title_name.pack(side='left')
close_button.pack(side='right')
window.pack(expand=True, fill='both')

# bind title bar motion to the move window function
title_bar.bind("<B1-Motion>", move_window)
title_bar.bind("<Button-1>", get_pos)
close_button.bind('<Enter>', change_on_hovering)
close_button.bind('<Leave>', return_to_normal_state)

root.mainloop()

编辑:

同时,我创建了使用类的版本-这样我就可以轻松添加更多按钮。
它也可以在移动时更改标题栏的颜色和文本。

在此处输入图片说明

import tkinter as tk

# --- constants --- (UPPER_CASE_NAMES)

# title bar colors
TITLE_FOREGROUND = "white"
TITLE_BACKGROUND = "#2c2c2c"
TITLE_BACKGROUND_HOVER = "green"

BUTTON_FOREGROUND = "white"
BUTTON_BACKGROUND = TITLE_BACKGROUND
BUTTON_FOREGROUND_HOVER = BUTTON_FOREGROUND
BUTTON_BACKGROUND_HOVER = 'red'

# window colors
WINDOW_BACKGROUND = "white"
WINDOW_FOREGROUND = "black"

# --- classes --- (CamelCaseNames)

class MyButton(tk.Button):

    def __init__(self, master, text='x', command=None, **kwargs):
        super().__init__(master, bd=0, font="bold", padx=5, pady=2, 
                         fg=BUTTON_FOREGROUND, 
                         bg=BUTTON_BACKGROUND,
                         activebackground=BUTTON_BACKGROUND_HOVER,
                         activeforeground=BUTTON_FOREGROUND_HOVER, 
                         highlightthickness=0, 
                         text=text,
                         command=command)

        self.bind('<Enter>', self.on_enter)
        self.bind('<Leave>', self.on_leave)

    def on_enter(self, event):
        self['bg'] = BUTTON_BACKGROUND_HOVER

    def on_leave(self, event):
        self['bg'] = BUTTON_BACKGROUND

class MyTitleBar(tk.Frame):

    def __init__(self, master, *args, **kwargs):
        super().__init__(master, relief='raised', bd=1, 
                         bg=TITLE_BACKGROUND,
                         highlightcolor=TITLE_BACKGROUND, 
                         highlightthickness=0)

        self.title_label = tk.Label(self, 
                                    bg=TITLE_BACKGROUND, 
                                    fg=TITLE_FOREGROUND)
                                    
        self.set_title("Title Name")

        self.close_button = MyButton(self, text='x', command=master.destroy)
        self.minimize_button = MyButton(self, text='-', command=self.on_minimize)
        self.other_button = MyButton(self, text='#', command=self.on_other)
                         
        self.pack(expand=True, fill='x')
        self.title_label.pack(side='left')
        self.close_button.pack(side='right')
        self.minimize_button.pack(side='right')
        self.other_button.pack(side='right')

        self.bind("<ButtonPress-1>", self.on_press)
        self.bind("<ButtonRelease-1>", self.on_release)
        self.bind("<B1-Motion>", self.on_move)
        
    def set_title(self, title):
        self.title = title
        self.title_label['text'] = title
        
    def on_press(self, event):
        self.xwin = event.x
        self.ywin = event.y
        self.set_title("Title Name - ... I'm moving! ...")
        self['bg'] = 'green'
        self.title_label['bg'] = TITLE_BACKGROUND_HOVER

    def on_release(self, event):
        self.set_title("Title Name")
        self['bg'] = TITLE_BACKGROUND
        self.title_label['bg'] = TITLE_BACKGROUND
        
    def on_move(self, event):
        x = event.x_root - self.xwin
        y = event.y_root - self.ywin
        self.master.geometry(f'+{x}+{y}')
        
    def on_minimize(self):
        print('TODO: minimize')
                
    def on_other(self):
        print('TODO: other')

# --- functions ---

# empty

# --- main ---

root = tk.Tk()
# turns off title bar, geometry
root.overrideredirect(True)

# set new geometry
root.geometry('400x100+200+200')

title_bar = MyTitleBar(root) 
#title_bar.pack()  # it is inside `TitleBar.__init__()`

# a canvas for the main area of the window
window = tk.Canvas(root, bg=WINDOW_BACKGROUND, highlightthickness=0)

# pack the widgets
window.pack(expand=True, fill='both')

root.mainloop()

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在JFrame上自定义标题栏?

如何使用现有的自定义主题隐藏XML活动的标题栏

最大化时从顶部拖动自定义窗口标题栏不起作用

Mahapps自定义标题栏颜色

如何自定义电子应用程序的窗口标题栏?

使用自定义标题栏获取类似gnome-3的窗口

使用自定义功能模拟移动窗口

在Electron JS应用程序中使用自定义标题栏

Ubuntu菜单重叠标题栏时如何移动窗口

检查自定义工具提示的左上角是否在范围内

在自定义标题栏上设置标题文本

Android:使用“自定义ListAdapter”视图在“自定义标题栏”中未显示标题

自定义图片作为标题栏中的图标

NSWindow标题栏自定义

如何更改多个活动的自定义窗口标题栏及其图标

Android标题栏自定义视图不拉伸

Matplotlib:将原点移动到左上角

获取双重自定义标题栏

自定义视图仅显示在左上角

在无标题栏的MFC C ++中移动窗口?

在我的自定义标题栏出现之前显示的默认标题栏

为什么角半径仅应用于自定义视图的左上角和右上角?

Vanilla Javascript - 使用 onclick 左上角的值向上或向下移动节点

如何使textarea从左上角移动

如何使用 WindowChrome 在 WPF 自定义标题栏上显示默认按钮

导航栏品牌标志在折叠时向下移动,我希望它保持在左上角

在 PyQt5 中使用自定义标题栏移动窗口的问题

如何在不删除标题栏的情况下禁用 Tkinter 窗口的移动

Highcharts:将 yaxis 标签移动到图表的左上角