如果单击覆盖重定向窗口并移动它(窗口),如何获得更好的窗口位置? [英] how to get a better window postion, if I click on an overrideredirectted window and move it (windows)?
问题描述
当我点击窗口时(在我的例子中,当我点击 self.top_frame
和 self.app_name
),移动它时,窗口位置更改为0 x 和 y 坐标.所以如果我想移动窗口,窗口会移动到右侧.我可以修复它,以便窗口不会移动到右侧(或从我的光标处)?
When I click on the window (in my case, when I click on self.top_frame
and self.app_name
), to move it, the window postion changes to 0 x and y coordinates. So if I want to move the window, the window moves to the right side.
Can I fix it, so that the window doesn't move to the right side (or from my cursor)?
from tkinter import *
from tkinter import ttk
#from controls import call_back
#import random
class MainWindow:
def __init__(self):
# lists
# color list [0] frame main bg [1] navibar [2] border color [3] status bar [4] Description Font
self.color_lst = ["#363e4a", "#1d2128", "#8b9ebf", "#2b303b", "#45505f"]
# button list [0] Home [1] Keyboard [2] Music [3] Timer [4] Setting Bar [5] exit [6] minimize
self.btn_list = ["\u2263","\u2328","\u266B","\u23F1","\u2348","\u26CC","\u268A"]
# control list [0] [1] [2] [3] [4] move setting bar
self.controls = ["","","","",self.setting_move]
# window settings, background, transparent, geometry
self.root = Tk()
self.root.geometry("1150x800")
self.root.minsize(400, 400)
self.root.overrideredirect(1) # <------------
self.root.resizable(True, True)
# create a background frame (border)
self.background_frame = Frame(self.root, bg=self.color_lst[2])
self.background_frame.pack(expand=YES, fill=BOTH)
# create a background frame
self.background = Frame(self.background_frame, bg=self.color_lst[0])
self.background.pack(expand=YES, fill=BOTH, padx=1, pady=1)
# navigation bar
self.navi_bar = Frame(self.background, bg=self.color_lst[1])
self.navi_bar.pack(side="left", fill=Y, ipadx=40)
# setting bar
self.setting_bar = Frame(self.background, bg=self.color_lst[2])
self.setting_bar.pack(side="left", fill=Y, ipadx=0)
# top frame
self.top_frame = Frame(self.background, bg=self.color_lst[1])
self.top_frame.pack(fill=X)
self.top_frame.bind("<B1-Motion>", self.call_back) # <--------------
self.top_frame.bind("<Map>", lambda event: self.show_window(event))
# create label description in the top frame
self.top_description = Label(self.top_frame,anchor=W, padx=20, bg=self.color_lst[3], fg=self.color_lst[4], text="Application Description")
self.top_description.pack(side="bottom", anchor=SW, expand=YES, fill=X)
# exit buttton
self.exit_btn = Button(self.top_frame, bg=self.color_lst[1], fg=self.color_lst[2], text=self.btn_list[5], font=("Bahnschrift", 16), bd=0, command=self.root.destroy)
self.exit_btn.pack(side="right", anchor=E, ipadx=10)
# minimize buttton
self.minimize_btn = Button(self.top_frame, bg=self.color_lst[1], fg=self.color_lst[2], text=self.btn_list[6], font=("Bahnschrift", 16), bd=0, command=self.minimize_window)
self.minimize_btn.pack(side="right", anchor=E, ipadx=10)
# Application name
self.app_name = Label(self.top_frame,anchor=W, padx=20, bg=self.color_lst[1], fg=self.color_lst[2], font=("Bahnschrift", 14), text="Application Name")
self.app_name.pack(side="right", anchor=E, expand=YES, fill=X)
self.app_name.bind("<B1-Motion>", self.call_back) # <------------
# background for different frames
self.frames = Frame(self.background, bg=self.color_lst[0])
self.frames.pack(expand=YES, fill=BOTH, side="top")
# bottom status bar
self.bottom_bar = Label(self.background,anchor=W, padx=20, bg=self.color_lst[3], fg=self.color_lst[4], text="Application Description")
self.bottom_bar.pack(fill=X, side="bottom", ipady=2)
# resize grip
self.resize_grip = ttk.Sizegrip(self.bottom_bar)
#self.resize_grip.
self.resize_grip.pack(side="right")
self.resize_grip.bind("<B1-Motion>", self.grip_resize)
# button statement to move setting bar
self.btn_SETTINGS = False
# buttons in the navigation bar
y=0
for index in range(5):
self.btn = Button(self.navi_bar, bg=self.color_lst[1], fg=self.color_lst[2], text=self.btn_list[index], font=("Bahnschrift", 20), bd=0)
self.btn.configure(command=self.controls[index])
self.btn.place(x=0, y=y, relwidth=1, height=64)
y +=64
# function to move the setting bar
def setting_move(self):
self.x = 0
if self.btn_SETTINGS == False:
for x in range(10):
self.setting_bar.pack_configure(ipadx=self.x)
self.btn.configure(text="\u2347")
self.setting_bar.after(20)
self.setting_bar.update_idletasks()
self.x += 10
self.btn_SETTINGS = True
else:
self.setting_bar.pack_configure(ipadx=0)
self.btn.configure(text="\u2348")
self.btn_SETTINGS = False
# better graphics
def grip_resize(self, event):
self.root.update_idletasks()
# minimize the window
def minimize_window(self):
self.root.overrideredirect(0)
self.root.iconify()
# show the window
def show_window(self, event):
self.root.overrideredirect(1)
#self.root.deiconify()
# function to move the whole window (on top frame clicked) # <------------
def call_back(self, event):
self.root.geometry("+{0}+{1}".format(event.x_root,event.y_root))# <--------------
if __name__ == "__main__":
app = MainWindow()
mainloop()
我为函数及其绑定位置设置了一些箭头
,以便您可以更好地找到它,以了解我的意思.
I set some arrows
to the function and where it's binded, that you can find it better, to see what I mean.
推荐答案
试试这个:
import tkinter as tk
class DraggableWindow(tk.Tk):
def __init__(self):
self.draggable = True
super().__init__()
self._offsetx = 0
self._offsety = 0
self.bind("<Button-1>", self.clickwin)
self.bind("<B1-Motion>", self.dragwin)
def topmost(self):
self.attributes("-topmost", True)
try:
self.attributes("-type", "splash") # Linux
except:
self.overrideredirect(True) # Windows
def dragwin(self, event):
if self.draggable:
x = self.winfo_pointerx() - self._offsetx
y = self.winfo_pointery() - self._offsety
self.geometry("+%d+%d" % (x, y))
def clickwin(self, event):
if self.draggable:
self._offsetx = event.widget.winfo_rootx() - self.winfo_rootx() + event.x
self._offsety = event.widget.winfo_rooty() - self.winfo_rooty() + event.y
root = DraggableWindow()
root.mainloop()
我很久以前做了这个 - 忘记了它是如何工作的细节.当我再次发现它是如何工作的时,我会用解释更新它.
I made this a long time ago - forgot the details on how it works. I will update this with an explanation when I find out how it works again.
要使窗口不可拖动,请将
更改为 False
.您可能还想查看this.它支持调整大小和Alt-Tab
.
To make the window undraggable change <DraggableWindow>.draggable
to False
. You might also want to look at this. It supports resizing and Alt-Tab
ing to it.
这篇关于如果单击覆盖重定向窗口并移动它(窗口),如何获得更好的窗口位置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!