Кнопки заставляют мышь в верхнем левом углу окна при перетаскивании

Я настроил базовый код, который создает перетаскиваемое окно tkinter overrideredirect, но когда я добавляю свои собственные настраиваемые кнопки, окно не перетаскивается кнопками, а вместо этого щелкает мышью в верхнем левом углу и перетаскивает окно оттуда.

#Imports
import sqlite3,tkinter
#Connects to the database
with sqlite3.connect("apc.db") as db:
    cursor = db.cursor()

#Interface Class
class login_UI(tkinter.Tk):
    #Main Interface Function
    def __init__(self, master=None):
        tkinter.Tk.__init__(self, master)
        self.title("Apex Companion")
        self.geometry()
        self.geometry("250x400")
        self.overrideredirect(True)
        self.config(bg = "#1e1e1e")
        #Tob Bar Frame
        tb = tkinter.Frame(self,height=20,width=250,bg = "#0f0f0f")
        tb.pack_propagate(False)
        #Top Bar Text
        tb_text = tkinter.Label(tb, text = "Apex Companion",bg = "#0f0f0f",fg = "#b4b4b4")
        tb_text.config(font=("Trebuchet",10, "bold"))
        #Top Bar Close
        tb_close = tkinter.Button(tb, height=2, width=3,
                                  text = "✕", bg = "#0f0f0f", fg = "#ffffff",
                                  activebackground = "#c94343",activeforeground = "#ffffff",
                                  command=self.destroy, bd=0)
        #Top Bar Minimize
        tb_min = tkinter.Button(tb, height=2, width=2,
                                text = "—", bg = "#0f0f0f",fg = "#ffffff"
                                ,bd=0,activeforeground = "#ff4e1d",activebackground = "#0f0f0f")
        #Top Bar Logo
        self.tb_img = tkinter.PhotoImage(file = "logo_apc.gif")
        tb_logo = tkinter.Label(tb,image=self.tb_img,bd=0,justify=tkinter.RIGHT)


        #Top Bar Packing
        tb.pack()
        tb_close.pack(side=tkinter.RIGHT)
        tb_min.pack(side=tkinter.RIGHT)
        tb_logo.pack(side=tkinter.LEFT)
        tb_text.pack()

        #Make Window Draggable
        self._offsetx = 200
        self._offsety = 200
        self.bind('<Button-1>', self.clickwin)
        self.bind('<B1-Motion>', self.dragwin)
    #Window Dragging Events
    def dragwin(self,event):
        x = self.winfo_pointerx() - self._offsetx
        y = self.winfo_pointery() - self._offsety
        self.geometry('+{x}+{y}'.format(x=x,y=y))

    def clickwin(self,event):
        self._offsetx = event.x_root
        self._offsety = event.y_root

    def login_db(self,event):
        print("E")
#Initilize the Interface
login_UI = login_UI()
login_UI.mainloop()

Я обновил код, чтобы отобразить весь файл. Надеюсь, это должно помочь.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
45
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

когда вы нажимаете кнопку, то event.x,event.y указывает положение относительно верхнего левого угла Button, а не верхнего левого угла окна, поэтому позже это дает неверные результаты.

это дает правильное смещение

def clickwin(self, event):
    self._offsetx = self.winfo_pointerx() - self.winfo_rootx()
    self._offsety = self.winfo_pointery() - self.winfo_rooty()

Теперь я могу двигаться, даже перетаскивая кнопку, но перетаскивание кнопки позже вызывает другую проблему - когда я перестаю перетаскивать, кнопка ловит щелчок, и окно закрывается :)


Полный код

import tkinter

class Win(tkinter.Tk):

    def __init__(self, master=None):
        tkinter.Tk.__init__(self, master)

        #self.geometry()
        self.geometry("250x400")
        self.overrideredirect(True)
        self.config(bg = "#1e1e1e")

        #Tob Bar Frame
        tb = tkinter.Frame(self, height=20, width=250, bg = "#0f0f0f")
        tb.pack_propagate(False)
        tb.pack()

        #Top Bar Close
        tb_close = tkinter.Button(tb, height=2, width=3,
                                  text = "✕", bg = "#0f0f0f", fg = "#ffffff",
                                  activebackground = "#c94343",activeforeground = "#ffffff",
                                  command=self.destroy, bd=0)
        tb_close.pack()

        #Make Window Draggable
        self._offsetx = 0
        self._offsety = 0
        self.bind('<B1-Motion>', self.dragwin)
        self.bind('<Button-1>', self.clickwin)

    #Window Dragging Events
    def dragwin(self,event):
        x = self.winfo_pointerx() - self._offsetx
        y = self.winfo_pointery() - self._offsety
        self.geometry('+{x}+{y}'.format(x=x,y=y))

    def clickwin(self, event):
        self._offsetx = self.winfo_pointerx() - self.winfo_rootx()
        self._offsety = self.winfo_pointery() - self.winfo_rooty()
        print('1.', event.x, event.y)
        print('2.', event.x_root, event.y_root)
        print('3.', self._offsetx, self._offsety)

root = Win()
root.mainloop()

С первым набором кода окно будет работать нормально, как и предполагалось, при первом перетаскивании, но затем любое другое перетаскивание после этого отбрасывает окно обратно в верхний левый угол экрана и перетаскивает его из того места, где первоначально щелкнула мышь. второй код, кажется, не работает и просто вызывает ошибки. Я отредактирую свой пост, чтобы отобразить полный код.

Maverick Davidson 09.04.2019 00:23

хорошо, я вижу проблему - вторая версия работает правильно, но она должна быть self вместо root - я назначил ваш класс root

furas 09.04.2019 00:31

Другие вопросы по теме