1

Python 3.1、tkinter/ttk

ウィジェットにリンクされた 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()
4

2 に答える 2

3

問題は、メソッドと という名前の変数の両方があることですcounter。ボタンをクリックすると、関数が呼び出されないため、変数は設定されません。ボタンを作成した時点で、tkinter はそれをself.counterコマンドではなく変数と見なします。

この特定の問題の解決策は、関数または変数の名前を変更することです。その後、期待どおりに動作するはずです。

「あまりにも多くの自己」についての質問に答えるには、参照しているオブジェクトがオブジェクトの特定のインスタンス内のどこでも使用できる必要があることを Python が認識できるように、self を使用する必要があります。したがって、変数が定義されている関数の外部で変数を参照する場合は、これらすべての自己が必要です。

メソッドの定義における self については、それらも必要です。を実行するとobject.method()、Python はオブジェクトへの参照をメソッドの最初の引数として自動的に送信するため、メソッドはどのメソッドが処理されているかを具体的に認識できます。

「self」の使用について詳しく知りたい場合は、self に関連する特定の質問がここにあります。self の目的は何ですか?

于 2013-09-12T17:38:28.217 に答える
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()

アップデート:

しかし、2 つのクラス (最初のクラスはやや無意味なインターフェイスにすぎません) でこれを行うと主張する場合は、次のようにします。

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 など) を使用する必要はありません。インスタンス化されたデータを格納しています。

私が使用したもう 1 つのことはlambda本格的な関数定義ではなく式です。現在の値を取得し、それに 1 を加えて、新しい値として保存することだけが目的だからです。

そして、私のバージョンでは、クラスは元のクラスのMainサブクラスです。そのため、メソッド内でメソッドtkinter.Tkを呼び出します。__init__Main__init__

于 2013-09-12T16:26:17.900 に答える