在 Python(tkinter)中从类的外部更改类的私有属性(标签)

     2023-02-25     237

关键词:

【中文标题】在 Python(tkinter)中从类的外部更改类的私有属性(标签)【英文标题】:Changing private attributes (labels) of a Class from outside of it in Python (tkinter) 【发布时间】:2021-08-13 07:26:29 【问题描述】:

我在 Python 中使用 tkinter 制作了一个 GUI,我创建了一个名为“Window”的类来管理整个会话期间 GUI 中的所有创建、运行和更改。 我不知道我是否让这太复杂了,但我正在尝试构建一个方法,所以我只能从“Window”类中更改标签,并且因为有很多标签,我想做类似的东西下一个代码(这是一个最小的可重现示例):

from tkinter import *

class Window:
    def __init__(self, wind):
        self.__window = wind
        self.__window.geometry("200x100")
        self.__window.title("Title")

        self.__label_1 = Label(self.__window, text="Label 1 text")
        self.__label_1.pack()

        self.__button_1 = Button(self.__window, text="Change", command=function)
        self.__button_1.pack()

    def change_label(self, label, text): #this 'label' is the name of the label I want to change
        self.label["text"] = text        #here I try to use it as the attibute's name


def function():
    myWindow.change_label("__label_1", "New text")


if __name__=='__main__':
    wind = Tk()
    myWindow = Window(wind)
    wind.mainloop()

我面临的问题显然是:AttributeError, 'Window' object has no attribute 'label'。

有没有办法制作我想要制作的东西?将我要更改的标签名称发送给方法,然后接收它并将其视为属性名称?

或者我应该将标签声明为公共标签并从“Window”类之外更改它?

问题是标签很多,我不希望他们被错误地改变,所以我想“简化”改变的过程,但也许我把它弄得太复杂了。

提前感谢您的回复。

【问题讨论】:

您可以使用实例字典,例如self.__labels = ,来保存标签:self.__labels["__label_1"] = self.__label_1。然后使用这个字典来更新change_label()里面需要的标签。 谢谢@acw1668 我对 Python 还很陌生,所以我对“实例字典”感到困惑,我刚刚读了一些东西,但我还是不明白,我无法实现你的解决方案.您的意思是将标签的所有文本值存储在字典中并直接更改这些值吗?但是如何刷新 GUI 以使标签发生变化? 我的意思是类型为 dictionary 的类的实例变量,就像我之前评论中的示例:self.__labels = self.__labels 是实例变量,它的类型是dictionary Python 没有私有属性 这是双下划线名称修改。这与 private 不同,Python 没有任何访问修饰符 @juanpa.arrivillaga "__label_1" 只是一个字符串,用作字典中存储或引用标签的键。 【参考方案1】:

如果您想使用字符串访问小部件,您需要通过name 选项提供一个唯一名称。为了更容易访问,最好使用字典来存储小部件,使用它们的名称作为键。

以下是根据您的修改的示例:

from tkinter import *

class Window:
    def __init__(self, wind):
        self.__window = wind
        self.__window.geometry("200x100")
        self.__window.title("Title")

        self.__widgets =  # dictionary to hold the created widgets

        # use whatever "name" you want but it must be unique
        self.create(Label, text="Label 1 text", name="label_1")
        self.create(Button, text="Change", command=function, name="button_change")

    def create(self, widget, **kw):
        w = widget(self.__window, **kw)
        w.pack()
        name = kw.get("name", str(w)) # use implicitly created name if "name" option is not given
        self.__widgets[name] = w
        return name

    def change(self, name, **kw):
        self.__widgets[name].config(**kw)


def function():
    # access the widget using the unique name
    myWindow.change("label_1", text="New text", font="Arial 24 bold")


if __name__=='__main__':
    wind = Tk()
    myWindow = Window(wind)
    wind.mainloop()

【讨论】:

这正是我想做的,非常感谢!【参考方案2】:

这里有两个基本问题。 Python 没有私有属性。 Python 没有 any 访问修饰符。您在这里使用的是 双下划线名称修饰。这与私有相同。它只是将名称更改为 _MyClass__my_attribute 以防止子类中的意外名称冲突,它仍然可以从外部完全访问:

>>> class Foo:
...     def __init__(self):
...         self.__bar = 42
...
>>> foo = Foo()
>>> foo._Foo__bar
42

表示不属于公共 API 的变量的惯用方式是使用 单下划线,例如self._bar = 42,这可能是您应该在这里使用的

现在,这种方法永远行不通了:

def change_label(self, label, text): #this 'label' is the name of the label I want to change
    self.label["text"] = text        #here I try to use it as the attibute's name

你想要的方式。要使用字符串修改属性,请使用getattrsetattr

>>> class Foo: pass
...
>>> foo = Foo()
>>> setattr(foo, 'bar', 42)
>>> foo.bar
42
>>> getattr(foo, 'bar')
42

【讨论】:

如何在颤动中从类(小部件外部)打开屏幕

】如何在颤动中从类(小部件外部)打开屏幕【英文标题】:Howtoopenascreenfromaclass(outsideawidget)influtter【发布时间】:2021-03-0100:35:05【问题描述】:所以,我的lab_widget有一个普通按钮,它从另一个名为not_plugin的文件中调用一个函... 查看详情

react中从类重构为功能钩子组件

】react中从类重构为功能钩子组件【英文标题】:Reconstructingfromclasstofunctionalhookcomponentinreact【发布时间】:2020-10-1504:29:37【问题描述】:只是想将我的应用程序从基于类的组件重新设计为基于功能挂钩的组件,并被这个回调setSta... 查看详情

python - 如何在python tkinter的for循环中从列表中创建多个复选框

】python-如何在pythontkinter的for循环中从列表中创建多个复选框【英文标题】:HowdoIcreatemultiplecheckboxesfromalistinaforloopinpythontkinter【发布时间】:2012-01-2202:50:50【问题描述】:我有一个可变长度的列表,并想为列表中的每个条目创建... 查看详情

在 C# 中从类中声明一个数组

】在C#中从类中声明一个数组【英文标题】:DeclaringanArrayfromaClassinC#【发布时间】:2020-03-0220:25:42【问题描述】:我想创建一个由我用类定义的"Highscore"对象组成的数组。当我尝试设置或读取特定数组内容的值时,我总是收到NullR... 查看详情

如何在主方法中从类中调用构造函数

】如何在主方法中从类中调用构造函数【英文标题】:Howtocallaconstructorfromaclass,inmainmethod【发布时间】:2013-08-2719:35:58【问题描述】:我知道这可能是一个超级简单的问题,但我似乎一辈子都搞不明白。正如标题所述,我只想在M... 查看详情

在java中从类路径加载文本文件资源

finalURLresource=this.getClass().getClassLoader().getResource(path);List<String>lines=IOUtils.readLines((InputStream)resource.getContent()); 查看详情

mule 在流程中从类路径中读取单个文件

】mule在流程中从类路径中读取单个文件【英文标题】:mulereadsinglefilefromclasspathduringflow【发布时间】:2012-10-2314:20:44【问题描述】:有没有一种简单的方法来配置Flow以一次从类路径中读取单个文件?我不需要轮询文件。我只需... 查看详情

在python中从icloud导入类

】在python中从icloud导入类【英文标题】:importingclassfromicloudinpython【发布时间】:2020-06-0902:02:15【问题描述】:我从万维网下载了一个包含类的python程序。我已将其存储在“iCloud/Document/Work/CodeLibrary/program.py”中。它包含我要导入... 查看详情

为啥我不能在 Mac 上使用 python 更改 tkinter 按钮的背景颜色?

】为啥我不能在Mac上使用python更改tkinter按钮的背景颜色?【英文标题】:whyIcan\'tchangebackgroundcolorofatkinterbuttonusingpythononaMac?为什么我不能在Mac上使用python更改tkinter按钮的背景颜色?【发布时间】:2022-01-1022:47:15【问题描述】:... 查看详情

如何在 Kivy 中从 python 代码更改屏幕

】如何在Kivy中从python代码更改屏幕【英文标题】:HowtochangescreensfrompythoncodeinKivy【发布时间】:2021-05-2420:54:15【问题描述】:所以我正在为我的第一个严肃的kivy应用程序制作一个功能齐全的登录屏幕,我希望能够在用户按下按... 查看详情

如何在python中每隔几秒在tkinter窗口中更改一行文本[重复]

】如何在python中每隔几秒在tkinter窗口中更改一行文本[重复]【英文标题】:Howtochangealineoftextinatkinterwindoweveryfewsecondsinpython[duplicate]【发布时间】:2019-12-2917:43:48【问题描述】:我试图在tkinter窗口中每隔几秒显示一个字典中的随... 查看详情

如何使用 python 在 tkinter 中更改按钮和框架的字体和大小?

】如何使用python在tkinter中更改按钮和框架的字体和大小?【英文标题】:Howtochangefontandsizeofbuttonsandframeintkinterusingpython?【发布时间】:2014-01-0212:22:15【问题描述】:这是我用来在tkinter中生成一个简单的文本框和一个按钮的代码... 查看详情

spring - 从类的静态字段中的属性文件中读取属性值

】spring-从类的静态字段中的属性文件中读取属性值【英文标题】:spring-readpropertyvaluefrompropertiesfileinstaticfieldofclass【发布时间】:2014-08-3004:57:04【问题描述】:我有一个实用程序类,其中我有一种方法需要用户名和密码才能连接... 查看详情

python,从类外部访问小部件项(代码片段)

我有一个自动生成的代码,它生成一个GUI,里面有各种小部件。其中一个小部件是ScrolledListBox。代码的一部分如下所示:classNew_Toplevel_1:def__init__(self,top=None):self.Scrolledlistbox4.configure(background="white")self.Scrolledlistbox4.configure(font= 查看详情

在 Python 3 中使用 tkinter 更改单选按钮的背景颜色

】在Python3中使用tkinter更改单选按钮的背景颜色【英文标题】:ChangingthebackgroundcolorofaradiobuttonwithtkinterinPython3【发布时间】:2016-09-1101:42:50【问题描述】:我在使用ttk在Python3中处理的GUI中添加了几个单选按钮,但它们周围有一个... 查看详情

在 Tkinter 中从 Web 中提取数据时制作加载动画

】在Tkinter中从Web中提取数据时制作加载动画【英文标题】:MakingaloadinganimationwhenpullingdatafromthewebinTkinter【发布时间】:2021-11-2203:11:35【问题描述】:我从互联网上提取数据并将其显示在画布上。在获取数据的过程中经过了一点... 查看详情

按下按钮后可以更改菜单栏文本吗? (Python,tkinter)

】按下按钮后可以更改菜单栏文本吗?(Python,tkinter)【英文标题】:CanIchangethemenubartextafterpressabutton?(Python,tkinter)【发布时间】:2021-10-0318:03:07【问题描述】:我一个月前开始使用python,并且正在练习不同的东西。现在我正在... 查看详情

在 Python 中获取 Tkinter 窗口之外的鼠标事件

】在Python中获取Tkinter窗口之外的鼠标事件【英文标题】:GetmouseeventsoutsideofTkinterwindowinPython【发布时间】:2015-12-2219:04:23【问题描述】:我正在编写一个连接到设计软件的程序,例如外部插件,然后监视鼠标移动和事件。它将根... 查看详情