【问题标题】:Python Tkinter custom msgbox fails during importPython Tkinter 自定义 msgbox 在导入期间失败
【发布时间】:2017-05-04 22:49:01
【问题描述】:

我正在尝试创建一个自定义文本输入框,该框在中心有一个文本输入字段,并且可以返回用户的输入。我特别想制作可以在其他程序中导入和重用的东西。我当前的迭代使用一个“inputdialog”类,当它在它自己的 .py 文件中时,它可以很好地获取输入,但是如果我尝试将模块导入另一个脚本,“ok”按钮似乎什么都不做,而“x ”按钮在关闭弹出窗口后抛出“ImportError: cannot import name 'inputdialog'”错误。

以下是我目前作为独立脚本运行的代码:

from tkinter import *

class inputdialog:
    def __init__(self):
        self.value = None
        self.root = Tk()
        self.root.withdraw()
        self.top = Toplevel(self.root)


        Label(self.top, text="Value").pack()
        self.e = Entry(self.top)
        self.e.pack(padx=5)

        b = Button(self.top, text="OK", command=self.ok)
        b.pack(pady=5, padx=5, side="right")
        self.root.mainloop()

    def ok(self):
        self.value = self.e.get()
        self.root.destroy()

if __name__ == "__main__":
    test = inputdialog()
    print(test.value)

以下是我将此模块导入另一个程序的方法,该程序目前不工作:

if __name__ == "__main__":
    # These two lines below are needed to make sure that "askopenfilename"
    # doesn't show it's top level tkinter window
    root = Tk()
    root.withdraw()
    entdbemp = askopenfilename(title="Please select a file: ")

    # Here is my non-working module call
    master = inputdialog()
    print(master.value)

为什么我的“确定”按钮在导入时会停止工作?有什么办法可以修复我的代码以允许导入它?有没有更好的方法来尝试使用 tkinter 制作可导入的文本输入模块?

【问题讨论】:

  • 一个问题是您正在创建Tk 的两个实例。 Tkinter 被设计为只有一个 Tk 实例。

标签: python tkinter import


【解决方案1】:

问题与导入无关。问题是在您的第二个示例中,您两次调用Tk():每个文件中一次。此外,当您调用“destroy”时,您只是从屏幕上删除了 GUI,并没有退出主循环。

要完成这项工作,您需要在 inputdialog 类中删除创建根的行,在启动类后将 mainloop() 调用移动到一个点,然后为顶层窗口调用 quit 方法(不是根窗口):

from tkinter import *
class inputdialog:
    def __init__(self, master=None):
        self.value = None
        self.top = Toplevel(master)

        Label(self.top, text="Value").pack()
        self.e = Entry(self.top)
        self.e.pack(padx=5)

        b = Button(self.top, text="OK", command=self.ok)
        b.pack(pady=5, padx=5, side="right")

    def ok(self):
        self.value = self.e.get()
        self.top.quit()

if __name__ == "__main__":
    root = Tk()
    root.withdraw()
    master = inputdialog(root)
    root.mainloop()
    print(master.value)

如果你想要整洁和适当:与其创建一个包含不同类的类,在 OOP 和 GUI 中,我们更喜欢创建一个子类:

import tkinter as tk

class inputdialog(tk.Toplevel):
    def __init__(self, master=None):
        tk.Toplevel.__init__(self, master)

        self.value = None

        tk.Label(self, text="Value").pack()
        self.e = tk.Entry(self)
        self.e.pack(padx=5)

        b = tk.Button(self, text="OK", command=self.ok)
        b.pack(pady=5, padx=5, side="right")

    def ok(self):
        self.value = self.e.get()
        self.quit()

if __name__ == "__main__":
    root = tk.Tk()
    root.withdraw()
    master = inputdialog(root)
    root.mainloop()
    print(master.value)

此外,通配符导入 (from module import *) 很丑陋并且不符合 PEP8;不要使用它们。

顺便说一句,easygui 包已经完成了这一切;您可能只想安装和使用它。

【讨论】:

  • 谢谢!我回家后会试试这个。我不做大量的oop,将来会记得做一个子类。我认为双 Tk()s 可能是一个问题,但不知道如何减轻它。至于通配符导入,我从一个仓促的示例中获取了基本代码并且从未修复它(抱歉!)
  • 嘿@Novel,我复制了你上面的代码,但同样的问题仍然存在,但后来我把你的代码复制到了我的另一台电脑上,它运行良好。很奇怪。我将把它标记为已回答,因为它似乎有效;我想我的环境出了点问题。
猜你喜欢
  • 1970-01-01
  • 2013-02-07
  • 2013-02-10
  • 2017-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-27
相关资源
最近更新 更多