如果单击覆盖重定向窗口并移动它(窗口),如何获得更好的窗口位置? [英] how to get a better window postion, if I click on an overrideredirectted window and move it (windows)?

查看:24
本文介绍了如果单击覆盖重定向窗口并移动它(窗口),如何获得更好的窗口位置?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我点击窗口时(在我的例子中,当我点击 self.top_frameself.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.

要使窗口不可拖动,请将 .draggable 更改为 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-Tabing to it.

这篇关于如果单击覆盖重定向窗口并移动它(窗口),如何获得更好的窗口位置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆