从另一个类检索变量

时间:2018-10-01 14:05:48

标签: python-3.x class tkinter

我正在使用Tkinter编程GUI。在其中一个类中,我定义了一个变量(entry_filename),并希望在另一个类中使用它。部分代码如下:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div class="drinkDisplay">
<div onclick="javascript:getSelectedItemId();">click here to get id</div>
<div class="result"></div>
  <div id='1' class='itemy'>
    <div class='textcontainer'>
      <p>Test 1<br>example 1</p>
    </div>
  </div>
  <div id='2' class='itemy'>
    <div class='textcontainer'>
      <p>Test 1<br>example 1</p>
    </div>
  </div>
  <div id='3' class='itemy'>
    <div class='textcontainer'>
      <p>Test 1<br>example 1</p>
    </div>
  </div>
  <div id='4' class='itemy'>
    <div class='textcontainer'>
      <p>Test 1<br>example 1</p>
    </div>
  </div>
  <div id='5' class='itemy'>
    <div class='textcontainer'>
      <p>Test 1<br>example 1</p>
    </div>
  </div>
</div>

Graphpage调用变量文件名,该文件名以后将用于创建图形(此处省略了部分代码)。运行代码时,将返回以下错误:
TypeError:无法创建一致的方法解析 基本框架,输入页的订单(MRO)

似乎在尝试解决更早的问题时遇到了另一个障碍,但是,如果我能够理解对此的解决方案,那么我希望我可以尝试解决进一步的问题。谢谢您的帮助

2 个答案:

答案 0 :(得分:1)

ssh是函数LoginCheck中的局部变量,因此您无法从另一个类中检索它。可以做的一件事是将ssh定义为self.ssh,以便可以通过instance_of_Loginpage.ssh对其进行访问。仅当您将Loginpage的实例传递到Graphpage的实例时,它才起作用。如果您需要从许多地方访问ssh连接,我建议创建另一个仅用于处理ssh的类(您可以使用Borg patter来实现它)。

答案 1 :(得分:0)

罪魁祸首是你不应该分享 类成员变量就是这种方式。

如果不同的班级共有一些共同点 数据,该数据可能是另一类 他们可以从中继承。

class CommonData():
    client = 100


class A(CommonData):
    def __init__(self):
        print(A.client)

class B(CommonData):
    def __init__(self):
        print(B.client)

a = A()
b = B()

CommonData.client = 300

print(a.client)
print(b.client)

在上述情况下,A的每个实例和B的每个实例 共享所有CommonData类变量,例如client。

CommonData.client = 400

class C():
    pass

您也可以使用多重继承。 将所有通用数据定义为CommonData属性 并使用CommonData作为类来保存数据,例如 在上面的示例中,不要从中创建实例:

class D(C, CommonData):
    def __init__(self):
        print(D.client)

c = C()
d = D()

一个更简单的选择是只定义 外部范围内的变量CommonData和 从任何地方使用它:

common_data = 500

class A():
    def __init__(self):
        global common_data
        print(common_data)
        common_data = 200
        # ... 

但是全局变量通常被视为程序中的一件坏事,因为由于多种原因,它们的使用可能会成为问题。

另一种方法是将变量传递给对象初始化器。 这使得实例保留其自身的值从 创造价值:

common_data = 600

class A():
    def __init__(self, data):
        self.common = data
        print(self.common)

a = A(common_data)
common_data = 0
print(a.common)

如果您运行上面的所有代码,则会打印出

100
100
300
300
400
600
600

编辑:

在这里查看我对您的答案的评论和一个简单的示例。 在这里,我选择对tkinter StringVars的两个全局引用。 字符串变量本身存在于Tk()名称空间中,例如 小部件;除了它们是全局Python名称。

import tkinter as tk
from tkinter import ttk



class Page1(tk.Toplevel):
    def __init__(self, parent, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)
        self.title('Page1')
        self.label1 = ttk.Label(self, text='Filename:')
        self.entry1 = ttk.Entry(self, textvariable=input_file1)
        self.label1.pack(side=tk.LEFT)
        self.entry1.pack()


class Page2(tk.Toplevel):
    def __init__(self, parent, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)
        self.title('Page2')
        self.label1 = ttk.Label(self, text='Filename:')
        self.entry1 = ttk.Entry(self, textvariable=input_file2)
        self.button1 = ttk.Button(self, text='Copy Here', command=copy_filename)
        self.label1.pack(side=tk.LEFT)
        self.entry1.pack(side=tk.LEFT)
        self.button1.pack()

def copy_filename():
    input_file2.set(input_file1.get())

root = tk.Tk() # has to exist for the StringVars to be created
root.iconify()
input_file1 = tk.StringVar()
input_file2 = tk.StringVar()

page1 = Page1(root)
page2 = Page2(root)
root.mainloop()

现在在下一个示例中,了解如何将stringvars转换为变量 Page1和Page2实例(不是类)的实例,使它们成为本地的 全球。然后,我被迫传递小部件page1的参考 对象放入小部件page2对象中。

这看起来更接近您的要求。

关于MRO麻烦,如果避免多重继承 它不会发生。

或者您通常使用super()

在您的情况下,错误是因为您将小部件存储在 对象/实例(在self.somename中),然后尝试 调用符合类名的窗口小部件方法。 该类中没有小部件供您使用方法。

因此,使用方法解析顺序进行的搜索失败, 因为那里没有对应的名称。

请注意,我没有使用多重继承,所以我可以 刚写了tk.Frame.而不是调用super。我喜欢 超级,因为它在文本中清楚地表明我正在调用父级 上课,但只有在有多个父母的情况下才真正需要超级 以及各种级别的子类别(通常形成菱形)。

现在是示例:

import tkinter as tk
from tkinter import ttk


class Page1(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)

        self.input_file1 = tk.StringVar()

        self.label1 = ttk.Label(self, text='Filename:')
        self.entry1 = ttk.Entry(self, textvariable=self.input_file1)
        self.label1.pack(side=tk.LEFT)
        self.entry1.pack()


class Page2(tk.Frame):
    # note the page1 reference being
    # passed to initializer and stored in a var
    # local to this instance:
    def __init__(self, parent, page1, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)

        self.page1 = page1

        self.input_file2 = tk.StringVar()

        self.label1 = ttk.Label(self, text='Filename:')
        self.entry1 = ttk.Entry(self, textvariable=self.input_file2)
        self.button1 = ttk.Button(self, text='Copy Here',
            command=self.copy_filename)
        self.label1.pack(side=tk.LEFT)
        self.entry1.pack(side=tk.LEFT)
        self.button1.pack()

    def copy_filename(self):
        # see how the page1 refernce is used to acess
        # the Page1 instance
        self.input_file2.set(page1.input_file1.get())

root = tk.Tk() # has to exist for the StringVars to be created

page1 = Page1(root)
page2 = Page2(root, page1) # pass a reference to page1 instance
page1.pack(side=tk.LEFT)
page2.pack(side=tk.LEFT)
root.mainloop()