怎么`tkinter。 Spinbox()的行为取决于传递给`textvariable`的值的类型

时间:2014-12-14 08:12:06

标签: python tkinter

一直试图接受Python(3.4),这是我在Stack Overflow上的第一篇文章。 我对textvariable小部件构造函数中的tkinter.Spinbox()选项的行为有疑问。

以下代码正常运作。它是6个旋转盒的布局,有3对旋转盒(每对并排)。假设一对中的每个旋转框彼此独立,即当一个变化时,它不会影响另一个。

配对A收到textvariable参数作为StringVar()类型(例如var = StringVar()

对B接收他们的textvariable参数作为在引号之间声明的字符串(例如var = '0'

对C接收textvariable参数作为integer类型(例如var = 0

注意:我想发布生成窗口的截屏,但页面上写着"您需要至少10个声望来发布图片" ...其中我显然没有此刻......

我想了解为什么对C的成员似乎是"非独立的"彼此的? - >改变一个,另一个跟随改变相同。

textvariabletkinter.Spinbox()参数的解释对于不同类型的值的分配有何不同?

以下是我的代码:

from tkinter import *

class spinModuleStrA():
    ''' spinModuleNum() - Spinbox taking textvariable as <StringVar() value> '''
    def __init__(self, master, moduleName):
        self.root = master
        self.moduleName = moduleName
        self.root.grid()
        self.var = StringVar()
        self.var.set('r')

        self.label1 = Label(self.root, text=self.moduleName, bg=self.root["bg"])
        self.label1.pack(expand = True)

        self.spinBox1 = Spinbox(self.root ,from_=0, to=100, width=10, textvariable=self.var)
        self.spinBox1.pack(expand = True)


class spinModuleStrB():
    ''' spinModuleNum() - Spinbox taking textvariable as <'' string value> '''
    def __init__(self, master, moduleName):
        self.root = master
        self.moduleName = moduleName
        self.root.grid()
        self.var = ''

        self.label1 = Label(self.root, text=self.moduleName, bg=self.root["bg"])
        self.label1.pack(expand = True)

        self.spinBox1 = Spinbox(self.root ,from_=0, to=100, width=10, textvariable=self.var)
        self.spinBox1.pack(expand = True)


class spinModuleNum():
    ''' spinModuleNum() - Spinbox taking textvariable as <numerical value> '''
    def __init__(self, master, moduleName):
        self.root = master
        self.moduleName = moduleName
        self.root.grid()
        self.var = 0

        self.label1 = Label(self.root, text=self.moduleName, bg=self.root["bg"])
        self.label1.pack(expand = True)

        self.spinBox1 = Spinbox(self.root ,from_=0, to=100, width=10, textvariable=self.var)
        self.spinBox1.pack(expand = True)


class app():
    def __init__(self):
        self.root = Tk()
        self.root.geometry('300x300+500+200')
        for i in range(2): # number of columns
            self.root.columnconfigure(i, weight=1)

        for i in range(3): # number of rows
            self.root.rowconfigure(i, weight=1)

        self.frame1 = Frame(self.root, bg='#f55')
        self.frame1.grid(row=0, column=0, padx=10, pady=10, sticky=W+E+N+S)
        self.module1 = spinModuleStrA(self.frame1, "Spin <StringVar()> A")

        self.frame2 = Frame(self.root, bg='#faa')
        self.frame2.grid(row=0, column=1, padx=10, pady=10, sticky=W+E+N+S)
        self.module2 = spinModuleStrA(self.frame2, "Spin <StringVar() B>")

        self.frame3 = Frame(self.root, bg='#5f5')
        self.frame3.grid(row=1, column=0, padx=10, pady=10, sticky=W+E+N+S)
        self.module3 = spinModuleStrB(self.frame3, "Spin <''> A")

        self.frame4 = Frame(self.root, bg='#5fa')
        self.frame4.grid(row=1, column=1, padx=10, pady=10, sticky=W+E+N+S)
        self.module4 = spinModuleStrB(self.frame4, "Spin <''> B")

        self.frame5 = Frame(self.root, bg='#55f')
        self.frame5.grid(row=2, column=0, padx=10, pady=10, sticky=W+E+N+S)
        self.module5 = spinModuleNum(self.frame5, "Spin <numerical> A")


        self.frame6 = Frame(self.root, bg='#5af')
        self.frame6.grid(row=2, column=1, padx=10, pady=10, sticky=W+E+N+S)
        self.module6 = spinModuleNum(self.frame6, "Spin <numerical> B")

app1 = app()

2 个答案:

答案 0 :(得分:1)

原因无关紧要。将字符串或整数传递给textvariable选项是不正确的用法。虽然它有时会起作用(取决于你如何定义“工作”),但它是不正确的。 textvariable需要tkinter提供的一个特殊变量类。如果不使用其中之一,根本没有定义textvariable属性。

然而,要回答具体问题:

对A 每个都获得一个唯一的textvariable,因此它按预期工作。底层的tcl / tk引擎为每个实例获取一个唯一的字符串,这就是为什么这两个实例是独立的。

对B 有效地获取 no textvariable,因为您指定了空字符串。对于底层的tcl / tk引擎,在这种情况下,空字符串等同于python的None。如果您使用非空字符串(例如:'')而不是'w00t',则会注意到与对C相同的行为。这是因为每个spinbox都获得一个具有相同名称的变量,对底层tcl / tk引擎来说意味着它们是相同的文本变量并因此绑定在一起。

对C 使用常数0(零)。因为它是一个常量,所以两个小部件有效地获得相同的文本变量,因为最终这个参数成为tcl / tk变量的名称。由于两个纺签箱的名称相同,因此它们捆绑在一起。

答案 1 :(得分:0)

哈哈......我猜B对毕竟不会起作用。我没有使用非空的双引号字符串测试它。

从您放置它的方式来看,当将任何非StringVar()类型的值传递给Spinbox的textvariable时,该值基本上被解释为“名称”或我将其描述为{{ 1}}到一个内存位置,它将值存储在相关的spinbox的文本条目中。

在我通过以下方式再次测试脚本之后,似乎就是这种情况:

  1. 添加新的课程定义pointer

  2. 修改class spinModuleStrC()

  3. class spinModuleStrB()

  4. 添加更多行代码

    =============================================== ================

    1. 以下是新课程class app()的代码(让我们将其与新的“配对D”联系起来):

    2. spinModuleStrC()
      1. class spinModuleStrC(): ''' spinModuleNum() - Spinbox taking textvariable as <'' string value> ''' def __init__(self, master, moduleName): self.root = master self.moduleName = moduleName self.root.grid() # tested this with 'r' and then with 'p' (anything different from 'r') self.var = 'r' self.label1 = Label(self.root, text=self.moduleName, bg=self.root["bg"]) self.label1.pack(expand = True) self.spinBox1 = Spinbox(self.root ,from_=0, to=100, width=10, textvariable=self.var) self.spinBox1.pack(expand = True) 的修改: 我将class spinModuleStrB()更改为self.var = ''

      2. self.var = 'r'

      3. 的修改

        3A。将class app()循环从配置3行修改为4

        for

        3B。将新代码附加到 for i in range(4): # number of rows self.root.rowconfigure(i, weight=1)

        的末尾
        class app()

        从观察开始,当我在 self.frame7 = Frame(self.root, bg='#5f5') self.frame7.grid(row=3, column=0, padx=10, pady=10, sticky=W+E+N+S) self.module7 = spinModuleStrC(self.frame7, "Spin <'p'> A") self.frame8 = Frame(self.root, bg='#5fa') self.frame8.grid(row=3, column=1, padx=10, pady=10, sticky=W+E+N+S) self.module8 = spinModuleStrC(self.frame8, "Spin <'p'> B") 中使用self.var = 'p'时,对D中的旋转框将相互跟随,而不会与其他对A,B和C相互干扰。

        但是,当我在spinModuleStrC()中使用self.var = 'r'时 - 与新spinModuleStrC()类似,对B和对D中的旋转框将相互跟随...显示spinModuleStrB() - 与传递给pointer的非StringVar()类型值中的行为...

        嗯......也许这种“非正式”行为可以被利用