Not able to modify and configure instance variables from within my init method but still in same class. Python Tkinter

huangapple go评论81阅读模式
英文:

Not able to modify and configure instance variables from within my init method but still in same class. Python Tkinter

问题

I'm here to assist with the translation. It seems you want a translation for the provided code snippet. Here is the translated code:

我正在为一个课程项目编写一个快速程序我对tkinter相当陌生但大多数问题我都能找到答案然而现在我陷入困境当新窗口弹出时我想禁用小部件上的按钮然后在窗口关闭时重新激活它们这是一个相当简单的概念根据我所读的应该很容易实现然而我仍在学习类结构以及面向对象编程的概念我在我的主窗口类的init方法中设置了这些按钮

然后我在同一类中定义了按钮命令方法一切运行良好但当我尝试从同一类中定义的配置方法中禁用按钮时该方法无法识别我创建的按钮变量我有一种感觉这是因为它们只是实例变量没有在实例外部存储所以我需要知道如何初始化这些按钮然后访问它们的变量以执行操作

我尝试将它们移到类变量中但那不会设置按钮我还尝试更改或删除前缀不指望它会起作用它也确实没有起作用)。我尝试了网上找到的一切但我陷入了困境目前已经注释掉了禁用选项直到我解决它)。完整的代码可以在GitHub上找到https://github.com/mgentile77/DnD5e.git

```python
class Horde_Maker:
    # 主窗口类,所有其他窗口都来自这里
    def __init__(self, root):
        # 初始化主窗口并启动程序
        self.app = root
        # 此部分创建弹出窗口的大小和位置
        width = 300
        height = 200
        screen_wid = root.winfo_screenwidth()
        screen_hei = root.winfo_screenheight()
        x = (screen_wid/2) - (width/2)
        y = (screen_hei/2) - (height/2)
        self.app.title("Horde Maker")
        self.app.geometry("%dx%d+%d+%d" % (width, height, x, y))
        self.app.protocol("WM_DELETE_WINDOW", self.disable_Xclose)
        # 开始布局窗口小部件
        self.set_up()
        
    def set_up(self):
        # 为此类设置窗口小部件    
        self.frame_header = ttk.Frame()  # 图像框架
        self.frame_header.pack()
        
        self.frame_start = ttk.Frame()  # 开始欢迎和指令框架
        self.frame_start.pack()
        ttk.Label(self.frame_start, text="欢迎来到").pack()
        ttk.Label(self.frame_start, text="HORDE MAKER").pack()
        ttk.Label(self.frame_start, text="选择您的路径").pack()
        
        self.frame_buttons = ttk.Frame()  # 按钮和弹出按钮的框架
        self.frame_buttons.pack()
        but_horde = ttk.Button(self.frame_buttons, text="Horde Maker", command=self.hordebutton)
        but_horde.grid(row=0, column=0)
        
        but_char = ttk.Button(self.frame_buttons, text="Character Builder", command=self.characterbutton)
        but_char.grid(row=0, column=1)
        ttk.Button(self.frame_buttons, text='退出', command=lambda: exit()).grid(row=1, column=0, columnspan=2)

    # 开始按钮功能中使用的类方法
    def hordebutton(self):  # 打开Horde窗口
        self.hord_button = Horde()
        # self.disable_but()
        
    def characterbutton(self):  # 打开Character窗口
        self.char_button = Character()
        # self.disable_but()

    # 创建其他窗口的父类指令
    def clear_frame(self, frame):  # 在退出时销毁子窗口
        for widgets in frame.winfo_children():
            widgets.destroy() 

    def disable_Xclose(self):  # 通过使用角落X按钮防止关闭窗口
        pass
    
    # @staticmethod
    # def disable_but():
    #     but_horde.config(state=DISABLED)
    #     but_char.config(state=DISABLED)
    
    # @staticmethod
    # def enable_but():
    #     but_horde.config(state=NORMAL)
    #     but_char.config(state=NORMAL)
英文:

I am writing a quick program for a class project. I am fairly new to tkinter and most problems I have been able to find answers for. However, now I am stuck. I want to disable buttons on my widget when a new window pops and then reactivate them when the windows close. Pretty simple concept, and from what I read should be easy to do. However, I am still learning class structures and struggling with the idea of object-oriented programming. I set up my buttons in the init method for the class on my main window.

Then I defined the button command method inside the same class. Everything works great, but when I try to disable the buttons from a config method defined in the same class, the method doesn't recognize the button variables I created. I have a feeling this is because they are only instance variables and have no memory outside the instance. So I need to know how to initialize the buttons and then access theirBrief look at my code and how things are set-up currently variables to force action on them.

I have tried moving them to a class Variable, but that doesn't set the buttons up. I have also tried changing or removing prefixes (didn't expect it to work and it didn't) I have tried everything I have found online, but I am stuck. (I commented out the disable options for now until I get it to work) full code available on github https://github.com/mgentile77/DnD5e.git

class Horde_Maker:
#Main Window class all other windows come from here
def __init__(self,root):
#Initializes the main window and starts program
self.app = root
#This sections creates window size and location on pop up 
width = 300
height = 200
screen_wid = root.winfo_screenwidth()
screen_hei = root.winfo_screenheight()
x = (screen_wid/2) - (width/2)
y = (screen_hei/2) - (height/2)
self.app.title("Horde Maker")
self.app.geometry("%dx%d+%d+%d" % (width, height, x, y))
self.app.protocol("WM_DELETE_WINDOW", self.disable_Xclose)
#Begins layout of window widgets
self.set_up()
def set_up(self):
#sets up window widgets for this class    
self.frame_header = ttk.Frame()#Frame for image
self.frame_header.pack()
self.frame_start = ttk.Frame()#Frame for start welcome and instructions
self.frame_start.pack()
ttk.Label(self.frame_start, text = "Welcome To The").pack()
ttk.Label(self.frame_start, text = "HORDE MAKER").pack()
ttk.Label(self.frame_start, text = "Choose Your Path").pack()
self.frame_buttons = ttk.Frame()#Frame for buttons and pops buttons
self.frame_buttons.pack()
but_horde = ttk.Button(self.frame_buttons, text = "Horde Maker", command = self.hordebutton)
but_horde.grid(row = 0, column = 0)
but_char = ttk.Button(self.frame_buttons, text = "Character Builder", command = self.characterbutton)
but_char.grid(row = 0, column = 1)
ttk.Button(self.frame_buttons, text = 'Exit', command = lambda : exit()).grid(row = 1, column = 0, columnspan = 2)
#Begins Class methods used in functions of of buttons
def hordebutton(self):#opens Horde window
self.hord_button = Horde()
# self.disable_but()
def characterbutton(self):#opens Character Window
self.char_button = Character()
# self.disable_but()
#Creates parent class instructions for other windows    
def clear_frame(self,frame):#Destroys child window on exit 
for widgets in frame.winfo_children():
widgets.destroy() 
def disable_Xclose(self):#prevents closing the window by using corner X
pass
# @staticmethod
# def disable_but():
#     but_horde.config(state = DISABLED)
#     but_char.config(state = DISABLED)
# @staticmethod
# def enable_but():
#     but_horde.config(state = NORMAL)
#     but_char.config(state = NORMAL)

答案1

得分: 1

You need to use instance variables instead of local variables if those buttons are accessed outside the function where they are created.

Also, a static method of a class cannot access instance variables of that class. Use a normal class method instead.

To access those instance variables from another class, you can pass the instance of the class to the other class.

class Horde_Maker:
    ...

    def set_up(self):
        ...
        # use instance variables instead
        self.but_horde = ttk.Button(self.frame_buttons, text="Horde Maker", command=self.hordebutton)
        self.but_horde.grid(row=0, column=0)

        self.but_char = ttk.Button(self.frame_buttons, text="Character Builder", command=self.characterbutton)
        self.but_char.grid(row=0, column=1)
        ...

    def hordebutton(self): # opens Horde window
        self.disable_but()
        self.hord_button = Horde(self)  # pass an instance to class Horde

    def characterbutton(self): # opens Character Window
        self.disable_but()
        self.char_button = Character(self) # pass an instance to class Character
        ...

    # change to a normal class method
    def disable_but(self):
        self.but_horde.config(state=DISABLED)
        self.but_char.config(state=DISABLED)

    def enable_but(self):
        self.but_horde.config(state=NORMAL)
        self.but_char.config(state=NORMAL)

class Character(Horde_Maker):
    ...

    def __init__(self, app):
        self.app = app
        ...

    ...

    def leave2(self):
        self.app.enable_but()
        ...

    ...

class Horde(Horde_Maker):
    def __init(self, app):
        self.app = app
        ...

    def leave1(self):
        self.app.enable_but()
        ...
英文:

You need to use instance variables instead of local variables if those buttons are accessed outside the function where they are created.

Also static method of a class cannot access instance variables of that class. Use normal class method instead.

To access those instance variables from other class, you can pass the instance of the class to other class.

class Horde_Maker:
    ...

    def set_up(self):
        ...
        # use instance variables instead
        self.but_horde = ttk.Button(self.frame_buttons, text="Horde Maker", command=self.hordebutton)
        self.but_horde.grid(row=0, column=0)

        self.but_char = ttk.Button(self.frame_buttons, text="Character Builder", command=self.characterbutton)
        self.but_char.grid(row = 0, column = 1)
        ...

    def hordebutton(self):#opens Horde window
        self.disable_but()
        self.hord_button = Horde(self)  # pass instance to class Horde

    def characterbutton(self):#opens Character Window
        self.disable_but()
        self.char_button = Character(self) # pass instance to class Character

    ...

    # change to normal class method
    def disable_but(self):
        self.but_horde.config(state=DISABLED)
        self.but_char.config(state=DISABLED)

    def enable_but(self):
        self.but_horde.config(state=NORMAL)
        self.but_horde.config(state=NORMAL)

class Character(Horde_Maker):
    ...

    def __init__(self, app):
        self.app = app
        ...

    ...

    def leave2(self):
        self.app.enable_but()
        ...

    ...

class Horde(Horde_Maker):
    def __init__(self, app):
        self.app = app
        ...

    def leave1(self):
        self.app.enable_but()
        ...

    ...

答案2

得分: 0

谢谢大家的帮助。这确实帮助我发现了我的错误根本原因。问题出在我组织类的方式以及尝试创建新的层次链上。我试图创建自己的父类,并在其子类内部打开新窗口。这意味着我将对象传递给了正在调用其他对象执行工作并将结果返回给我的对象以便将结果返回给我的另一个对象的对象。我应该意识到我的类是继承自tk父类的子类,新的init语句需要传递给父tk类。一旦我重新组织了我的类以遵循这个层次结构,一切都运行得很完美,我获得了我程序所需的功能。我仍然有很多要学,但我感到自信我开始逐渐理解。请告诉我您对这个解释有什么看法。

英文:

Thank you, everyone, for the assistance. It did help me discover the root cause of my mistake. It was how I organized my classes and attempted to create a new hierarchy chain. I tried to create my own parent class and open new windows from within their own child class. This means I was passing objects to my objects that were calling other objects to do the work and returning the results to my object to return the result to another one of my objects. I should have realized that my classes were child classes from the tk parent class, and new init statements needed to be passed to the parent tk classes. Once I reorganized my classes to follow this hierarchy, everything worked perfectly, and I gained the functionality I wanted for my program. I still have a lot to learn, but I feel confident that I am beginning to catch on. Please let me know what you think of this explanation.

huangapple
  • 本文由 发表于 2023年5月11日 02:57:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/76221769.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定