2013-09-12 3 views
0

Python 3.1, Tkinter/TTKпеременная Tkinter в другом классе

я написал что-то очень простое, чтобы попытаться понять, как переменные Tkinter, привязанный к виджетам могут быть сохранены в другом классе в виджете. Код ниже.

Вопросы:

1) почему не изменить, нажав на кнопку ярлык?

2) Мне нужно довольно много самолюбия? Могут ли переменные внутри каждого метода работать без себя. с самого начала?

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

from tkinter import * 
from tkinter.ttk import * 

root = Tk() 

class Store: 

    def __init__(self): 
     self.v = IntVar() 
     self.v.set(0) 

    def set(self, v): 
     self.v.set(v) 

class Main: 

    def __init__(self): 

     self.counter = 0 

     self.label = Label(root, textvariable = a.v) 
     self.label.pack() 

     self.button = Button(root, command = self.counter, text = '+1') 
     self.button.pack() 

    def counter(self): 

     self.counter = self.counter + 1 
     a.set(self.counter) 

a = Store() 
b = Main() 

root.mainloop() 

ответ

2

Если бы я тебя, я сделаю это:

import tkinter 

root = tkinter.Tk() 
var = tkinter.IntVar() 

label = tkinter.Label(root, textvariable=var) 
button = tkinter.Button(root, command=lambda: var.set(var.get() + 1), text='+1') 

label.pack() 
button.pack() 

root.mainloop() 

UPDATE:

Но если вы настаиваете на том, чтобы сделать это с двумя классами (где первый класс - это только несколько бессмысленно интерфейс), то я хотел бы сделать это:

import tkinter 

class Store: 
    def __init__(self): 
     self.variable = tkinter.IntVar() 

    def add(self, value): 
     var = self.variable 
     var.set(var.get() + value) 
     return var.get() 

class Main(tkinter.Tk): 
    def __init__(self, *args, **kwargs): 
     tkinter.Tk.__init__(self, *args, **kwargs) 
     var = Store() 
     self.label = tkinter.Label(self, textvariable=var.variable) 
     self.button = tkinter.Button(self, command=lambda: var.add(1), text='+1') 
     self.label.pack() 
     self.button.pack() 


root = Main() 
root.mainloop() 

Как вы можете заметить, я в оба раза get() и set() методы IntVar (в вашей версии я делаю это через интерфейс Store мы), поэтому вам не нужно использовать новую переменную (например, self.counter), потому что созданная нами переменная хранит данные.

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

И в моей версии, Main класс является подклассом оригинального tkinter.Tk класса - вот почему я называю это __init__ метод внутри __init__ метода Main «s.

+0

Ваш ответ не кажется, ответить на вопрос, который был задан. В вопросе конкретно задаются вопросы о нескольких классах. Кроме того, вы добавили код без каких-либо объяснений. Если кто-то просто изучает Tkinter, им будет сложно понять, что вы сделали по-другому, чтобы решить проблему. –

+0

Я исправил свой ответ, хотя @BryanOakley Я не думаю, что мне нужно объяснить мою короткую версию, так как единственное * magic *, которое у нее есть, - это выражение lambda, которое не является tkinter, а проблема Python * , Во всяком случае, верните мои реплики :) –

+0

объяснение необходимо, даже для коротких ответов, при ответе на вопросы неопытных людей. Как еще они могут знать, что решение проблемы (или нет) - использование лямбда или удаление классов или тот факт, что вы используете или не используете «я» или что-то еще полностью? Они не знают об этом, поэтому, когда вы просто даете им несколько строк кода, они вполне могут заключить, что классы не должны использоваться с tkinter, хотя это не тот момент, который вы пытались сделать. –

2

Ваша проблема заключается в том, что у вас есть как метод, так и переменная с именем counter. Когда вы нажимаете кнопку, ваша функция не вызывается, поэтому переменная не устанавливается. В то время, когда вы создаете кнопку, tkinter считает, что self.counter является переменной, а не командой.

Решение этой проблемы заключается в переименовании либо функции, либо переменной. Затем он должен работать так, как вы ожидаете.

Чтобы ответить на вопрос «слишком много самоубийств»: вам нужно использовать self, чтобы python знал, что объект, на который вы ссылаетесь, должен быть доступен везде внутри определенного экземпляра объекта. Итак, да, вам нужны все эти «я», если вы хотите ссылаться на переменные за пределами функции, в которой они определены.

Что касается себя в определении метода, то это тоже необходимо. Когда вы делаете object.method(), python автоматически отправит ссылку на объект в качестве первого аргумента методу, чтобы метод точно знал, на какой метод воздействуют.

Если вы хотите узнать больше об использовании «я», есть конкретный вопрос, связанный с личностью здесь: What is the purpose of self?

+0

Я не думаю, что этот ответ полезен в способе обучения * практического * и * чистого * кода ... –

+0

@PeterVaro: это выглядит как ответный нисходящий поток для меня, хотя меня действительно не волнует репутация. Вы правы, что это не особенно полезно для изучения практического и чистого кода, но это не то, что было задано. Пользователь специально спросил, почему нажатие кнопки в данном коде не сработало, и я ответил на это. Я считаю, что неискренне сказать, что это не очень полезный ответ, и может дать OP впечатление, что мой ответ как-то не прав, даже если он правильно излагает актуальную проблему с кодом. –

+0

Так же, как мой @Bryan Oakley! Как только вы удалите -1 из моего ответа, я сделаю то же самое от вас. Я также не забочусь о повторениях, но поскольку мой ответ работает (обе версии) и правильные, чистые и практичные, я не знаю, почему вы дали мне -1 в первую очередь, а не предупреждение в комментарии , или что-то в этом роде. –

Смежные вопросы