在Python中调用自定义对象的Main方法

2024-10-01 17:25:56 发布

您现在位置:Python中文网/ 问答频道 /正文

当你使用一个对象作为参数时,我试图修正一些与对象返回的内容相关的问题。你知道吗

例如,我有一个自定义对象,我想用它作为另一个tkinter小部件的父对象,所以我需要返回一个tkinter对象,将新的tkinter对象放入我的自定义对象中,但是我的自定义对象返回的是自定义类的对象。你知道吗

我可以用代码更好地解释这一点:

class CustomFrame(object):
    def __init__(self,**args):
        #code that works

        #The next is an external object that have a variable that I need to call externally.
        #The variable is "interior"
        self.externalobject = anotherobject('random')

cfr1 = CustomFrame()

label1 = Label(cfr1)

现在我想用“self.externalobject.interior内部“作为label1的父级 但我想让它变得友好,只是叫“cfr1”而不是“cfr1”self.externalobject.interior内部““

我知道,如果我使用调用方法并返回所需的值,那么如果我将“cfr1”作为函数传递,它将起作用,但我希望使它尽可能具有python特性。你知道吗

所以我需要知道是否有其他特殊的方法或东西来修改它返回的内容。你知道吗

编辑: 所以,这是我使用的代码的一部分:

这是垂直滚动框的代码(不是我的代码)。你知道吗

class VerticalScrolledFrame(Frame):
    """A pure Tkinter scrollable frame that actually works!
    * Use the 'interior' attribute to place widgets inside the scrollable frame
    * Construct and pack/place/grid normally
    * This frame only allows vertical scrolling

    """
    def __init__(self, parent, bg, *args, **kw):
        Frame.__init__(self, parent, *args, **kw)            

        # create a canvas object and a vertical scrollbar for scrolling it
        vscrollbar = Scrollbar(self, orient=VERTICAL)
        canvas = Canvas(self, bd=0, highlightthickness=0,
                        yscrollcommand=vscrollbar.set,bg=bg)
        vscrollbar.config(command=canvas.yview)
        canvas.pack(side=LEFT, fill=BOTH, expand=TRUE)

        # reset the view
        canvas.xview_moveto(0)
        canvas.yview_moveto(0)

        # create a frame inside the canvas which will be scrolled with it
        self.interior = interior = Frame(canvas,bg=bg)
        interior_id = canvas.create_window(0, 0, window=interior,
                                           anchor=NW)

        a = Frame(self.interior,height=10,bg=dynamicBackground())
        a.pack()

        def canvasscroll(event):
            canvas.yview('scroll',int(-1*(event.delta/120)), "units")

        def _configure_canvas(event):
            a.configure(height=10)
            a.update()
            mylist = interior.winfo_children()
            for i in mylist:
                lasty=i.winfo_height()+i.winfo_y()
            a.configure(height=lasty)
            if interior.winfo_reqwidth() != canvas.winfo_width():
                # update the inner frame's width to fill the canvas
                canvas.itemconfigure(interior_id, width=canvas.winfo_width())
            if canvas.winfo_height()<lasty:
                vscrollbar.pack(fill=Y, side=RIGHT, expand=FALSE)
                canvas.config(scrollregion=(0,0,0,lasty))
                canvas.bind_all("<MouseWheel>", canvasscroll)
            else:
                canvas.unbind_all("<MouseWheel>")
                try:
                    vscrollbar.pack_forget()
                except:
                    pass
                canvas.config(scrollregion=(0,0,0,0))


        canvas.bind('<Configure>', _configure_canvas)

这是我自定义对象的代码:

class UtilityPanel(object):
    def __init__(self,parent='*',title='Main Title',state='normal',bg='red'):
        super().__init__()
        if parent != '*':
            self.parent=parent
        else:
            raise TypeError('You must specify a parent for this widget.')
        self.title=title

        global subpanels

        if len(subpanels) == 0:
            self.panelid = 'sp-1'
            subpanels.append('sp-1')
        else:
            self.panelid = 'sp-'+str(int(subpanels[-1].split('-')[1])+1)
            subpanels.append(self.panelid)

        self.panel = VerticalScrolledFrame(self.parent,bg=bg,width=600,height=200,name=self.panelid)

    def __call__(self,name):
        return(self.panel.interior)

    def pack(self):
        self.panel.place(x=300)
        global activepanel
        activepanel = self.panelid

所以,如果我像label1 = Label(cfr1.panel.interior)那样传递参数,它就可以工作了,但是我想让它只传递cfr1作为参数。你知道吗


Tags: the对象代码selfinitdefframepack
3条回答

您正在尝试隐式地将一种类型的对象强制转换为另一种类型。你知道吗

如果你想成为“Python”,回想起来

>>> import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
...

含蓄地做事会引起麻烦。你知道吗

我认为使用call魔术函数来获得所需的属性,或者开始查看属性和装饰器没有什么错。你知道吗

这里有一个完整的魔法方法列表here

我想我理解OP的问题。它们无法使用框架作为标签的容器,这是因为它们缺少super(),需要从框架继承。你知道吗

更改此项:

class CustomFrame(object):
    def __init__(self,**args):

对此:

class CustomFrame(Frame):
    def __init__(self,**args):
        super().__init__()

你应该能够使用客户框架作为你的标签容器。你知道吗

根据您的评论,请尝试以下方法:

class CustomFrame(anotherobject):
    def __init__(self,**args):
        super().__init__()

这应该继承该对象的所有方法和属性。你知道吗

如果您创建了自己的tk.Label自定义子类,基本上可以为您解包,那么您就可以实现您想要的。你知道吗

(免责声明:我从未使用过tkinter,因此我无法判断它是否在该框架的上下文中有效。这个例子仅仅是为了演示我在这里试图概述的概念。)

class CustomLabel(tk.Label):

    def __init__(self, master, **options):
        if isinstance(master, CustomFrame):
            master = master.externalobject.interior
        super().__init__(master=master, **options)

这样你就可以使用CustomLabel(cfr1)。你知道吗

然而,我强烈支持@doctorlove在他们的回答中传达的信息。IMHO,最具python风格的方法应该是Label(cfr1.externalobject.interior),您建议的方法是使用__call__CustomFrame内的属性,它提供了externalobject.interior的快捷方式:

@property
def interior(self):
    return self.externalobject.interior

你会像这样使用Label(crf1.interior)

相关问题 更多 >

    热门问题