Problem początkującego tkinter

0

Hejka, jestem nowy i piszę sobie program 'kolko krzyzyk', chcialbym dodac do tego clase zeby potem projekt rozwinac. Mam problem ze jak robie cos takiego to wyskakuje mi blad - > interakcja0 = Button(win, text='O',

NameError: name 'win' is not defined

Wiem, ze kazde klikniecie w 'Button' zamyka okienko, to jest zrobione zamierzenie.
Kod do programu wygląda następująco - https://pastebin.com/B3MEtG5s. Proszę o rady!

1
  1. Wszystko bez wcięcia nie jest w klasie.
  2. Do win odwołasz się tylko przez self.win.
0

Dziękuje za odzew. Dobra juz sformatowalem do definicji resztę. Hmm, tak to powinno poprawnie wyglądac? https://pastebin.pl/view/775c43a8 -

Ten kod na razie nie ruszy z miejsca. Poniżej zostawiam listę uwag, które powinny pomóc:

  1. Nie przyjmować win jako argument w init, ponieważ tworzysz win za pomocą Tk().
  2. gemetry nie wołaj na self, ale na self.win, ponieważ metoda geometry należy do obiektu win
  3. Kod z wszystkimi zmiennymi interakcja lepiej przerzuć do init, a w kolko_i_krzyzyk zostaw tylko wywołania do sprzątania okna. O ile ta akcja na tym etapie ma faktycznie to robić.
  4. Przy bindowaniu użyj odwołania do metody poprzez self, inaczej python nie rozpozna nazwy.
  5. Na końcu nie możesz użyć win.mainloop(), musisz pierw utworzyć obiekt na podstawie klasy okienko. Najszybciej (chociaż nie najlepiej) uzyskasz to pisząc:```
okno = okienko()
okno.win.mainloop()
0

Tak to mogłoby mniej więcej wyglądać:

import tkinter as tk
from functools import partial

class Okienko:
    def __init__(self):
        self.win = tk.Tk()
        self.win.title('Kolko i krzyzyk')
        self.win.geometry('300x400')

        interakcja0 = tk.Button(self.win, text='O', font=('Courier', 25, 'bold'), background='blue')
        interakcja0.bind('<Button-1>', partial(self.buttonListener, "interakcja0")) # sposob z partial()+bind
        interakcja0.grid(column=1, row=2)

        interakcja = tk.Button(self.win, text='O', font=('Courier', 25, 'bold'), background='blue',
            command = partial(self.buttonCommand, "interakcja")) # partial() + command
        interakcja.grid(column=2, row=2)

        interakcja2 = tk.Button(self.win, text='O', font=('Courier', 25, 'bold'), background='blue')
        interakcja2.bind('<Button-1>', lambda event, msg="interakcja2": self.buttonListener(msg, event)) # z lambda
        interakcja2.grid(column=3, row=2)

        # cut cut cut

    def mainloop(self):
        self.win.mainloop()

    def buttonCommand(self, msg):
        print(f'ButtonCommand: msg={msg}')

    def buttonListener(self,  message, event):
        print(f'buttonlistener: event={event}, msg={message}')


okno = Okienko()
okno.mainloop() 
  1. Nie importuj wszystkiego z tkinter bo tam pełno jednoznakowych stałych
  2. Klasa Okienko w konstruktorze powinna zainicjować tkinter i zbudować wszystkie widgety
  3. Button ma parametr "command" do którego można przypisać callback ale "bind" też wystarczy.
  4. callbacki wrapujemy poprzez partial() albo z lambdą, wtedy można przekazać ekstra parametr informujący jaki przycisk go wywołał

1 użytkowników online, w tym zalogowanych: 0, gości: 1