How to stop window jitter

Viewed 463

I have a window that sizes itself when you click and drag the mouse. The problem is the right side of the window jumps around when dragging from right to left. This issue only happens in Windows not Linux I'm not sure about MaxOS because I don't have access to a machine that runs it.It would be good to know though! Does anyone know how to fix this?

UPDATE: I have updated the code according to what "jizhihaoSAMA" suggested below and now it works fine in Windows and Linux not sure about MacOS still!

import tkinter as tk
import tkinter.ttk as ttk
import tkinter.font as tkfont

from sys import platform


class Selector(tk.Toplevel):
    def __init__(self, parent, **kwargs):
        super().__init__(parent, **kwargs)
        self.geometry('0x0+0+0')
        self.overrideredirect(True)

        if platform == 'linux':
            self.wait_visibility(self)

        self.wm_attributes('-alpha', 0.2)
        self.wm_attributes("-topmost", True)

        self.config(bg='#00aaff')
        self.update()
        self.lift()

        self.linespace = self.master.linespace
        self.heading_padding = parent.style.lookup('Treeview.Heading', 'padding')
        self.theme = parent.style.theme_use()
        self.style = parent.style

    def select(self, _):
        widget = self.focus_get()
        master = widget.winfo_toplevel()
        if widget == master:
            return

        padding = 0 if not isinstance(widget, ttk.Treeview) else \
            int(str(self.style.lookup('Treeview.Heading', 'padding')[0]))
        tv_padding = padding*2 if isinstance(widget, ttk.Treeview) else 0

        border_width = 3 if self.theme == 'default' else 6
        linespace = self.linespace if isinstance(widget, ttk.Treeview) else 0

        x, y = master.winfo_pointerxy()
        root_x = widget.winfo_rootx()
        root_y = widget.winfo_rooty()+linespace+tv_padding+border_width
        wdg_width = widget.winfo_width()
        wdg_height = widget.winfo_height()-linespace-tv_padding-border_width

        if x < root_x:
            x = root_x
        elif x > root_x + widget.winfo_width():
            x = root_x + wdg_width

        if y < root_y:
            y = root_y
        elif y > root_y + wdg_height:
            y = root_y + wdg_height

        origin_x = widget.origin_x if x > widget.origin_x else x
        origin_y = widget.origin_y if y > widget.origin_y else y
        self.geometry(f'{abs(x-widget.origin_x)}x{abs(y-widget.origin_y)}+{origin_x}+{origin_y}')


class App(tk.Tk):
    def __init__(self):
        super().__init__()
        self.rowconfigure(0, weight=1)
        self.rowconfigure(1, weight=1)
        self.columnconfigure(0, weight=1)
        self.columnconfigure(1, weight=1)
        self.title('Selector Demo')

        font = tkfont.nametofont('TkDefaultFont')
        self.linespace = font.metrics('linespace')

        self.style = ttk.Style()
        self.style.theme_use('clam')
        self.style.configure('Treeview.Heading', padding=5)
        self.style.configure('Treeview', rowheight=self.linespace+7)

        self.selector = Selector(self)

        var = tk.StringVar()
        var.set(('List Item 1', 'List Item 2', 'List Item 3', 'List Item 4', 'List Item 5'))
        self.lb = tk.Listbox(self, listvariable=var, selectmode=tk.EXTENDED, width=50, height=15)
        self.lb.grid(padx=20, pady=20, row=0, column=0)

        tree = ttk.Treeview(self)
        tree["columns"] = ("one", "two", "three")
        tree.column("#0", width=120, minwidth=3, stretch=tk.NO)
        tree.column("one", width=150, minwidth=3, stretch=tk.NO)
        tree.column("two", width=80, minwidth=3)
        tree.column("three", width=80, minwidth=50, stretch=tk.NO)

        tree.heading("#0", text="Name", anchor=tk.W)
        tree.heading("one", text="Date modified", anchor=tk.W)
        tree.heading("two", text="Type", anchor=tk.W)
        tree.heading("three", text="Size", anchor=tk.W)
        # Level 1
        folder1 = tree.insert("", 1, text="Folder 1", open=1, values=("23-Jun-17 11:05", "File folder", ""))
        tree.insert("", 2, text="text_file.txt", values=("23-Jun-17 11:25", "TXT file", "1 KB"))
        # # Level 2
        tree.insert(folder1, "end", text="photo1.png", values=("23-Jun-17 11:28", "PNG file", "2.6 KB"))
        tree.insert(folder1, "end", text="photo2.png", values=("23-Jun-17 11:29", "PNG file", "3.2 KB"))
        tree.insert(folder1, "end", text="photo3.png", values=("23-Jun-17 11:30", "PNG file", "3.1 KB"))
        tree.grid(padx=20, pady=20, row=0, column=1)

        self.tb = tk.Text(self, height=10)
        self.tb.grid(pady=(0, 20), columnspan=2)
        self.tb.insert(tk.END, "Just a text Widget\nin two lines\n")
        self.tb.cursor = self.tb.cget('cursor')

        self.bind('<Button-1>', self.button_press)
        self.bind('<ButtonRelease-1>', self.button_release)

    def button_press(self, event):
        wdg = event.widget
        wdg.focus_set()
        if isinstance(wdg, tk.Text):
            wdg.config(cursor='arrow')
        self.selector.geometry('0x0+0+0')
        wdg.origin_x, wdg.origin_y = wdg.winfo_pointerxy()
        self.bind('<Motion>', self.selector.select)

    def button_release(self, event):
        wdg = event.widget
        if isinstance(wdg, tk.Text) and hasattr(wdg,  'cursor'):
            wdg.config(cursor=wdg.cursor)
        self.selector.geometry('0x0+0+0')
        self.unbind('<Motion>')


def main():
    app = App()
    app.mainloop()


if __name__ == '__main__':
    main()
0 Answers
Related