【问题标题】:Tkinter - Using a Button command in a class to call a function from another classTkinter - 在一个类中使用 Button 命令从另一个类调用函数
【发布时间】:2018-08-26 18:49:54
【问题描述】:

我的程序正在使用 First 类中的按钮来触发 Second 类中的功能。但是,当按钮被按下时,它需要我包含一个 self 参数,所以我如何通过使用此处建议的静态方法 (Python 3 Tkinter - How to call a function from another class) 或使用其他替代方法来调用其他函数。

如果你能建议我如何在第二课中使用那个 StringVar,这对我来说会更容易,问候。

我认为应该修改的唯一部分代码:

self.traceButton=Button(self.main_inner_frame,text="Trace",command=Second.printSecondLine())

二等代码:

class Second(First):
    # @staticmethod
    def __init__(self,master):
        super().__init__(master)

    def printSecondLine(self):
        content = self.traceEntry.get()
        print(content)

如果您需要完整代码:

from tkinter import *
class First(Frame):
    def __init__(self,master):
        super().__init__()
        master.minsize(width=755, height=520)
        master.maxsize(width=755, height=520)
        Grid.config(self)

        # Run all function in [First Class]
        self.widget_size()
        #self.getTEXT()

    def widget_size(self):

        # Define a small frame for it
        self.main_inner_frame = LabelFrame(self,text="Tracing Method",height= 120,width =355)
        self.main_inner_frame.grid(row= 0, column=0)
        self.main_inner_frame.grid_propagate(0)

        # Create a button for it [When trace click it will show the text in the entry on terminal]
        self.traceButton = Button(self.main_inner_frame, text="Trace",command=Second.printSecondLine())
        self.traceButton.grid(row = 0, column = 1, sticky = W)

        # Create a entry box for the user
        # use a string variable tvar
        tvar = StringVar()
        self.traceEntry = Entry(self.main_inner_frame,textvariable=tvar,width=30)
        self.traceEntry.grid(row = 0, column = 2, sticky = W)

    # def getTEXT(self):
        # content = self.traceEntry.get()
        # print(content)

class Second(First):
    # @staticmethod
    def __init__(self,master):
        super().__init__(master)

    def printSecondLine(self):
        content = self.traceEntry.get()
        print(content)
        return content

if __name__ == '__main__':
    root = Tk()
    root.title("Good System")
    TIF = First(root)
    root.mainloop()

预期结果 当用户按下按钮时,条目将获取文本并显示在终端中。

【问题讨论】:

  • printSecondLine() 移动到First 并摆脱毫无意义的Second。然后command=self.printSecondLine
  • 对于这个功能确认是没有意义的。但是我有一个巨大的类,它确认将存储在另一个文件中,如果我解决了这个最小化程序,我可以在我的大程序中做以下事情: 在第二类中,我将使用跟踪所有 Windows 用户活动历史记录,因此,这部分我将只用来从文件对话框目录中获取 XXX 文本,我已经知道如何做到这一点,只需要从另一个类中获取,对我来说应该没问题。如果没有意义,我不会创建它来帮助我解决程序中更大的问题......希望你能理解。谢谢
  • 如果我按照你的建议,简单的程序是可以的。但是我的第一个程序已经是一个收集证据的主界面,所以我没有必要将复杂的代码放在一个已经有这么多代码的文件中,我这样做只是为了清洁代码。
  • 你可以有一个Second 类,但在First 中有printSecondLine (顺便说一下,给一切更好、更有意义的名字)。如果printSecondLine 所做的一切都与First 有关,那么为什么printSecondLine 应该在Second 中尚不清楚。
  • 这是我的完整系统代码:wuahts3 是我的主要 python。 drive.google.com/open?id=1Mk9Y39oCYWvrtBxd4_dxiBsfd5RTyWID 举个大例子:windows 证据的所有跟踪过程都将在另一个类中进行,里面有一个功能需要在用户按下主文件(wuahts3)中的跟踪按钮时打开文件对话框目录,将来将是一个按钮来自不同班级的不止一个功能如果我只需要从二等舱获得该功能以实现我的目标,您能帮我吗? (基于我的小例子,我确定有正确的方法吗?

标签: python function class tkinter


【解决方案1】:

已解决。我做了一些事情来让你的代码按照你想要的规范工作:

  1. 在 printSecondLine() 方法上方添加了@staticmethod。
  2. 从 printSecondLine() 参数列表中删除了 self。
  3. 让 printSecondLine() 接受名为 value 的参数。
  4. 删减并重写了 printSecondLine() 方法的主体,使其按预期运行。
  5. 在 Button 配置中使用了 lambda 表达式,以便轻松传递数据。
  6. 将 tvar 作为 lambda 表达式的参数,因为这是您要传递给 printSecondLine() 的参数
  7. 将 tvar 和 Entry 代码放在 Button 代码上方。按其他顺序可能没问题。但我认为最好将 tvar 放在上面,因为您在从 Button 访问它之前先声明它。

无论如何,它有效。您将数据输入条目,单击按钮,数据将进入控制台。您可能希望编写在单击按钮后清除 Entry 字段的代码。但这是一个不同的话题,并不难做到。

from tkinter import *

class First(Frame):
    def __init__(self,master):
        super().__init__()
        master.minsize(width=755, height=520)
        master.maxsize(width=755, height=520)
        Grid.config(self)

        # Run all function in [First Class]
        self.widget_size()


    def widget_size(self):

        # Define a small frame for it
        self.main_inner_frame = LabelFrame(self,text="Tracing Method",height= 120,width =355)
        self.main_inner_frame.grid(row= 0, column=0)
        self.main_inner_frame.grid_propagate(0)

        # Create a entry box for the user
        # use a string variable tvar
        tvar = StringVar()
        self.traceEntry = Entry(self.main_inner_frame,textvariable=tvar,width=30)
        self.traceEntry.grid(row = 0, column = 2, sticky = W)

        # Create a button for it [When trace click it will show the text in the entry on terminal]
        self.traceButton = Button(self.main_inner_frame, text="Trace",command=lambda: Second.printSecondLine(tvar))
        self.traceButton.grid(row = 0, column = 1, sticky = W)


class Second(First):
    @staticmethod
    def __init__(self,master):
        super().__init__(master)

    @staticmethod
    def printSecondLine(value):
        print(value.get())


if __name__ == '__main__':
    root = Tk()
    root.title("Good System")
    TIF = First(root)
    root.mainloop()

【讨论】:

    【解决方案2】:

    创建按钮时,您不能将 command= 设置为使用括号“()”,除非像这样使用 lambda。

    self.traceButton = Button(self.main_inner_frame,text="Trace",
    command= lambda: Second.printSecondLine())
    

    但这也应该有效:

     self.traceButton = Button(self.main_inner_frame, text="Trace",command=Second.printSecondLine)
    

    【讨论】:

    • 是的,使用 command=Second.printSecondLine,它显示类型错误:缺少 1 个必需的位置参数:'self'
    猜你喜欢
    • 1970-01-01
    • 2017-01-28
    • 2013-03-13
    • 1970-01-01
    • 1970-01-01
    • 2018-03-19
    • 2017-08-10
    • 2018-07-30
    • 1970-01-01
    相关资源
    最近更新 更多