Инициировать события Tkinter из другого класса в Python - PullRequest
0 голосов
/ 03 декабря 2018

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

Моя текущая проблема заключается в попытке вызвать событие из другого класса.Простая версия проблемы такова:

from tkinter import *

class Area:
    def __init__(self):
        self.can = Canvas(width=100, height=100, bg="green")
        self.can.pack(in_=window)
        self.can.bind("<Button-3>", self.test)
        self.square = self.can.create_rectangle(25, 25, 75, 75)

    def test(self, event):
        self.can.delete("all")

class Trigger:
    def __init__(self):
        self.button = Button(text="click me", command=?)
        self.button.pack(in_=window)

window = Tk()
Area()
Trigger()
window.mainloop()

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

Проблема в том, что я не могу понять, что нужно иметь в качестве команды для кнопки.

Я пытался command=Area.test, но затем я получаю "

TypeError: test (), пропущенный 2 обязательных позиционных аргумента:" self "и" event ""

Я пробовал command=Area.test(Area, "event") и command=Area.test(self, "event"), но они возвращают:

AttributeError: тип объекта 'Area' не имеет атрибута 'can'

и

AttributeError: тип объекта 'Area' не имеет атрибута 'can'

Я также попытался Area().test("event), который не дал ошибки, но дал мне 2 экземплярахолста, один с квадратом и один без.Кнопка ничего не делала тогда.

Посмотрел наследование, поэтому я попробовал это, поместив Area в качестве наследования на класс Trigger, затем выполните command=self.test("event") Но потом получил:

AttributeError:У объекта 'Trigger' нет атрибута 'can'

Итак, у меня нет идей ... Я неправильно выполняю часть __init__?

1 Ответ

0 голосов
/ 03 декабря 2018

Во-первых, если вы хотите использовать функцию как в качестве цели события, так и в качестве значения атрибута command, вы должны сделать аргумент event необязательным.Вы можете сделать это, присвоив ему значение по умолчанию None:

def test(self, event=None):
    self.can.delete("all")

Во-вторых, объекту Trigger должен быть присвоен экземпляр объекта Area, чтобы он мог вызывать методы вэтот объект.Есть несколько способов сделать это, но самый простой - передать его при создании объекта.Это означает, что вам нужно изменить Trigger.__init__ для принятия параметра, а затем передать его при создании объекта.

Вот как можно изменить метод __init__:

class Trigger:
    def __init__(self, area):
        self.button = Button(text="click me", command=area.test)
        self.button.pack(in_=window)

Как передать объект Area объекту Trigger:

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