tkinter event.x выполняет другую функцию - PullRequest
0 голосов
/ 07 ноября 2019

У меня есть функция, которая помогает мне прокрутить холст нажатием левой кнопки и перемещением. Все работает хорошо.

Но когда я добавил другую функцию (допустим, это func B, я не пишу здесь код func B, потому что он довольно большой и имеет некоторые зависимости, которые нужно выполнить), который использует exent.x и y - после выполнения они автоматически выполняются в функции выше и в результате перетаскивают мой экран в начало холста. Я попытался создать другую функцию (удаленный func B) и использовать там event.x и y и получил ту же проблему.

Если я удаляю одну из функций, которая использует event.x и y всепрекрасно работает, но если я напишу 2 функции, которые используют event.x и y, они перетаскивают мой экран неправильно.

Как я могу использовать event.x и y без их выполнения в других функциях, которыеиспользуйте event.x и y?

РЕДАКТИРОВАТЬ 2:

* Добавлен минимальный код

    from tkinter import *

class Main(Frame):
    def __init__(self, main):
        Frame.__init__(self, main)
        self.canvas_width = 64000
        self.canvas_height = 64000
        main.columnconfigure(0, weight=1)
        main.rowconfigure(0, weight=1)

        # Execute all functions
        self.center_menu()
        self.grid(self.canvas)

        # Right click menu
        self.rmenu = Menu(self.canvas_frame, tearoff=0, takefocus=0)
        self.rmenu.add_command(label='Create zone', command=self.create_zone_first_step)
        self.canvas.bind("<ButtonPress-3>", self.popup)

        # Bind
        self.canvas.bind("<ButtonPress-1>", self.scroll_start)
        self.canvas.bind("<B1-Motion>", self.scroll_move)
        self.canvas.bind("<Button-1>", self.create_zone)
    # End of init function.

    def center_menu(self):
        self.canvas_frame = Frame(main, relief='groove')
        self.canvas_frame.pack(side=LEFT)
        self.canvas_frame.pack_propagate(True)
        self.canvas = Canvas(self.canvas_frame, bg='bisque', width=750, height=750,highlightthickness=1)
        self.canvas.pack()
        self.canvas.addtag_all("main_canvas_tag")

    def popup(self, event):
        self.rmenu.tk_popup(event.x_root + 24, event.y_root - 14, entry="0")
        self.coords_1 = [event.x, event.y]


    def create_zone_first_step(self):
        self.from_x = self.coords_1[0]
        self.from_y = self.coords_1[1]
        # for checking
        self.FIRST_COORDS_CREATED = True


    def create_zone(self, event):
        if self.FIRST_COORDS_CREATED == True:
            self.zone = self.canvas.create_rectangle(self.from_x, self.from_y, event.x, event.y)
            self.FIRST_COORDS_CREATED = False

    def grid(self, canvas):
        for l in range(0, self.canvas_width, 10):
            canvas.create_line([(l, 0), (l, self.canvas_width)], fill='#d9d9d9')
        for l in range(0, self.canvas_height, 10):
            canvas.create_line([(0, l), (self.canvas_height, l)], fill='#d9d9d9')

    def scroll_start(self, event):
        self.canvas.scan_mark(event.x, event.y)

    def scroll_move(self, event):
        self.canvas.scan_dragto(event.x, event.y, gain=1)


if __name__ == '__main__':
    main = Tk()
    main.state('zoomed') # open window in full screen
    main.title('My insane warehouse')
    # Eliciting classes
    Main(main)
    main.mainloop()

описание функций:

  1. «Центр меню» - это рамка с холстом
  2. Grid - это рисование сетки на холсте.
  3. Scroll функции помогают пользователю перетаскивать холст, щелкая и перемещая мышь.
  4. create_zone_first_step запоминает координаты, по которым пользователь нажимал при появлении всплывающего окна.
  5. create_zone создаетпрямоугольник при щелчке левой кнопкой мыши где-нибудь

Что нужно сделать, чтобы увидеть проблему:

  1. Откройте окно и щелкните правой кнопкой мыши на холсте, «добавьте зону» и щелкните где-нибудь на холсте (без перетаскивания холста!). Он работает нормально и создает прямоугольник (зону)

  2. Но если вы перетащите холст, он переместит вас "в начало холста". Если мы удалим функцию scroll_ functions или create_zone, она не переместит экран «в начало»

И проблема заключается в том, что мне нужно создать прямоугольник таким образом, но это неуместноДвижение экрана мешает мне понять мою идею.

Извините за мои «недооцененные» объяснения.

1 Ответ

0 голосов
/ 08 ноября 2019

Проблема (или, по крайней мере, часть проблемы) заключается в том, что вы пытаетесь связать две разные функции с одним событием. <ButtonPress-1> и <Button-1> - это одно и то же событие. Таким образом, когда вы делаете self.canvas.bind("<Button-1>", self.create_zone), это удаляет исходную привязку и заменяет ее новой привязкой.

Это можно легко продемонстрировать с помощью следующего кода:

import tkinter as tk
root = tk.Tk()
def callback1(event):
    print("callback 1")
def callback2(event):
    print("callback 2")
root.bind("<ButtonPress-1>", callback1)
root.bind("<Button-1>", callback2)
root.mainloop()

Когда вы запускаетеПриведенный выше код и щелкнув в окне, вы увидите, что когда-либо вызывается только callback2.

Вместо того, чтобы пытаться выполнить две отдельные привязки, вам нужно иметь одну привязку к функции, которая достаточно умназнать, когда он должен вызывать scroll_start и когда он должен вызывать create_zone.

Другим решением было бы временно назначить привязку, когда вы находитесь в режиме «создания зоны», а затем вернуться назадв противном случае к привязке «начало прокрутки».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...