Problem początkującego tkinter

Odpowiedz Nowy wątek
2020-02-06 22:42

Rejestracja: 3 miesiące temu

Ostatnio: 4 dni temu

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!

edytowany 1x, ostatnio: MyNameIsJeff, 2020-02-06 22:47

Pozostało 580 znaków

2020-02-06 23:12

Rejestracja: 16 lat temu

Ostatnio: 1 godzina temu

1
  1. Wszystko bez wcięcia nie jest w klasie.
  2. Do win odwołasz się tylko przez self.win.
Dziękuje za odzew. Dobra juz sformatowalem do definicji resztę. Hmm, tak to powinno poprawnie wyglądac? https://pastebin.pl/view/775c43a8 - MyNameIsJeff 2020-02-06 23:30

Pozostało 580 znaków

2020-02-09 20:26

Rejestracja: 2 lata temu

Ostatnio: 11 godzin temu

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()

Pozostało 580 znaków

2020-02-14 00:12

Rejestracja: 1 rok temu

Ostatnio: 1 dzień temu

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ł

Pozostało 580 znaków

Odpowiedz

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