【问题标题】:using classes to create checkboxes in tktinter python使用类在 tkinter python 中创建复选框
【发布时间】:2020-08-24 11:18:03
【问题描述】:

我试图使用类在 tktinter python 中创建多个复选框,但由于某种原因复选框没有显示,这是我得到的错误 AttributeError: 'crop' object has no attribute 'tk' 这是我的代码

from tkinter import *
from tkinter.ttk import *
import tkinter as tk  # python 3
screen = Tk()

class crop:

    def __init__(self,sizename,sizevar,onvar):
        sizevar= StringVar
        self.tk.Checkbutton(screen, text=sizename, variable=sizevar, onvalue=onvar, offvalue='no')
        self.pack()


def main():
    first = crop('2.5','twofive','twofiveon')
    second = crop('3','three','threeon')
screen.mainloop()    
main()

提前感谢您的帮助。

【问题讨论】:

    标签: python oop tkinter widget tk


    【解决方案1】:

    您的代码有几处问题。

    首先,您需要在调用main 之后调用mainloop,而不是之前。

    其次,sizevar= StringVar 必须是sizevar= StringVar()

    第三——这是引发错误的那一行——你试图调用self.tk.Checkbutton,但你的crop对象没有定义一个名为tk的属性。我不完全确定你想要完成什么,但我猜你只是想调用 tk checkbutton 这意味着代码应该是tk.Checkbutton(...)

    下一个问题是 self.pack() - selfcrop 对象。它不是一个小部件,因此它没有 pack 方法。看来您的意图是打包checkbutton,因此您需要保存对checkbutton的引用,然后在其上调用pack(例如:self.cb = tk.Checkbutton(...); self.cb.pack()

    另一个问题是您要导入两次 tkinter。你应该只做一次。您需要同时删除 from tkinter import *from tkinter.ttk import *。然后,在引用 tkinter 和 ttk 对象时,使用tk.ttk. 作为前缀。

    最后一个问题是您没有遵循PEP8 准则,这使其他程序员更难理解您的代码。具体来说,crop 需要是Crop

    将所有这些放在一起,您的代码应该1如下所示:

    import tkinter as tk
    from tkinter import ttk
    
    screen = tk.Tk()
    
    class Crop:
    
        def __init__(self,sizename,sizevar,onvar):
            sizevar= tk.StringVar()
            self.cb = tk.Checkbutton(screen, text=sizename, variable=sizevar, onvalue=onvar, offvalue='no')
            self.cb.pack()
    
    
    def main():
        first = Crop('2.5','twofive','twofiveon')
        second = Crop('3','three','threeon')
    
    main()
    screen.mainloop()
    

    1 我说 应该 因为不是 100% 清楚你想做什么。由于您最初进行导入的方式,不清楚您是打算使用 Checkbutton 小部件的 ttk 版本还是 tk 版本。这是导入 tkinter 时通配符导入不好的原因之一。如果你想使用 ttk 复选按钮,你需要把那一行改成这样:

    self.cb = ttk.Checkbutton
    

    【讨论】:

    • 哇,非常感谢,这是一个非常好的解释,老实说,我不知道 tk 和 Ttk 之间的区别,我只是在关注我正在看的教程,但是谢谢
    【解决方案2】:

    您需要执行以下操作:

      def __init__(self,sizename,sizevar,onvar):
            global screen # or pass it as __init__ parameter
            sizevar= StringVar
            b= tk.Checkbutton(screen, text=sizename, variable=sizevar, onvalue=onvar, offvalue='no')
            b.pack()
    

    【讨论】:

    • 这只是取消了类的使用,我需要使用类来缩短我的代码,因为我将制作 20 个复选框,不过感谢您的帮助
    • 不,它没有。您需要确定要从每个作物实例中检索的内容,并将其作为类的属性,例如 self.sizevar = StringVar
    • 我很困惑,你能告诉我完整的代码吗?谢谢
    • 没有必要将screen 声明为全局的,因为他们不会尝试修改变量。全局变量在函数内部是可读的,而无需声明它们是全局的。宣布这可能是一个好习惯,但这并不能回答 OP 的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-24
    • 1970-01-01
    相关资源
    最近更新 更多