【问题标题】:Calling textvariable from function within a class Python 3 tkinter从类 Python 3 tkinter 中的函数调用 textvariable
【发布时间】:2020-04-04 20:47:17
【问题描述】:

感谢您对我的问题的任何帮助。

我将 Python 3 与 tkinter 一起使用,我在其中设置了多个页面,但是我试图在定义中调用一个类中的特定文本变量,并想知道是否有可能与我构建脚本的方式有关。

这是一个相当大的脚本,所以我不想在这里粘贴所有代码,我希望这已经足够了。

基本上这个类被称为 POIIN(tk.frame) 我正在尝试调用

class POPage(tk.Frame):
def __init__(self, parent, controller):
    tk.Frame.__init__(self, parent)

    self.entryboxes()

def entryboxes(self):
    # Entry boxes + variables
    global voucher
    voucher = IntVar()
    entry_box3 = tk.Entry(self, textvariable=voucher, width=32, bg="lightgreen")
    entry_box3.place(x=435, y=151)

我正在尝试通过在类之外执行以下操作来调用文本变量:

def do_mssql():
try:
    if int(POPage.entryboxes(voucher).get()) > int(maxN):
        voucherchktext()
    elif int(voucher.get()) < int(minN):
        voucherchktext()

    else:
        sql()
except:
    vouchermissing()

但是它似乎在调用 IntVar() 并且我没有收到任何错误消息,(Python 很新) 基本上,我只需执行 int(voucher.get()) 就可以从另一个类(页面)中提取凭证。 我当然可以重命名 textvariable 并以这种方式调用它(我不介意),但如果有任何解决方法,那就太好了。

非常感谢您的帮助!

BR,

【问题讨论】:

  • 你到底希望POPage.entryboxes(voucher).get() 做什么?
  • 抱歉不清楚,但我希望它获取文本变量值
  • 这与voucher.get() 有何不同?您似乎在多个页面之间共享此全局 voucher 对象 - 因此也在多个 tk.Entry 对象之间共享。为什么它首先需要是全球性的?
  • 这是必需的,因为我将在另一个不在类中的函数中输出。我认为是我缺乏知识限制了我在这里,我可能会以更好的方式重写它。也许我可以把整个代码上传到某个地方让你看看?
  • 如果你喜欢,你可以把整个代码贴在 pastebin 上,然后把它的链接贴在这里。不过,我不能保证我能在明天之前看到它。

标签: python class tkinter definition


【解决方案1】:

感谢您在 pastebin 上发布您的整个代码。通过查看您的代码,我可以看到您的所有类实际上都没有拥有它们创建的 tkinter 小部件的所有权。换句话说,它们没有任何实例变量。我建议彻底重新设计并摆脱所有global 变量和对象-在这种情况下,这是一种主要的代码气味,表明您的设计存在缺陷-这很好,您确实说您毕竟是初学者.我在你的代码中也看到了很多好东西!不要片面……

基本上,我建议的更改是:每个框架类都应该拥有它们创建的小部件的所有权。其中包括 tk.Labels、tk.Buttons、tk.Entrys 和 tk.IntVars 等。

这提供的主要好处是,您的框架类的任何实例都将有自己的tk.IntVar(或任何条目小部件变量,如tk.StringVar),它不需要与任何其他类共享(你称它为textvariable)。如果您考虑一下,这是有道理的:每个tk.Entry 小部件都与一个变量对象耦合,该对象跟踪用户为该条目小部件输入的数据 - 如果您只创建一个全局条目变量并与所有条目小部件共享它帧,您很容易丢失用户输入的数据 - 真的没有理由这样做。

尝试运行/玩弄以下代码 sn-p:

import tkinter as tk


class MyFrame(tk.Frame):

    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)

        self.label = tk.Label(self, text="Some Text")
        self.label.pack()

        self.entry_var = tk.IntVar()
        self.entry = tk.Entry(self, textvariable=self.entry_var, width=32)
        self.entry.pack()

        self.button = tk.Button(self, text="Print this frame's 'entry_var'", command=lambda: print(self.entry_var.get()))
        self.button.pack()


class Application(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        self.title("Title")
        self.geometry("256x256")
        self.resizable(width=False, height=False)

        self.frames = []

        for frame in MyFrame(), MyFrame():
            self.frames.append(frame)
            frame.pack()

def main():

    application = Application()
    application.mainloop()

    return 0


if __name__ == "__main__":
    import sys
    sys.exit(main())

您有一个主要的Application(在您的示例中称为Ghost),它有多个框架(我的示例只有一个框架类,但Application 有该框架类的两个实例)。每个框架实例都有一个入口小部件和一个唯一的、完全独立的和不同的对应入口变量对象。框架没有理由共享同一个入口变量对象。将小部件和条目变量对象作为其类的实例变量应该完全消除您对global 变量的使用。

在我的示例中,如果我需要从类外部访问条目小部件中的值 - 例如在 main 函数中,您会说 application.frames[0].entry_var.get() 以获取第一帧条目中的值小部件。

【讨论】:

  • 谢谢,我会试试这个,边做边学是要走的路。感谢您的意见!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多