Wirror 发表于 2021-7-9 21:08:25

tkinter: 函数中Tk()一个对象为什么在Application类中不能quit()?好像是作用域的问题

本帖最后由 Wirror 于 2021-7-9 21:12 编辑

class Application_ui(Frame):
    #这个类仅实现界面生成功能,具体事件处理代码在子类Application中。
    def __init__(self, master=None):
      Frame.__init__(self, master)
      self.master.title('Form3')
      self.master.geometry('399x111')
      self.master.resizable(0,0)
      self.createWidgets()

    def createWidgets(self):
      self.top = self.winfo_toplevel()

      self.style = Style()

      self.orderVar = StringVar(value='')
      self.order = Entry(self.top, textvariable=self.orderVar, font=('宋体',9))
      self.order.place(relx=0.261, rely=0.36, relwidth=0.464, relheight=0.225)

      self.style.configure('Label1.TLabel',anchor='w', font=('宋体',9))
      self.Label1 = Label(self.top, text='口令', style='Label1.TLabel')
      self.Label1.place(relx=0.08, rely=0.432, relwidth=0.143, relheight=0.225)

      self.style.configure('Command1.TButton',font=('宋体',9))
      self.Command1 = Button(self.top, text='进入', command=self.Command1_Cmd, style='Command1.TButton')
      self.Command1.place(relx=0.782, rely=0.36, relwidth=0.183, relheight=0.225)


class Application(Application_ui):
    #这个类实现具体的事件处理回调函数。界面生成代码在Application_ui中。
    def __init__(self, master=None):
      Application_ui.__init__(self, master)

    def Command1_Cmd(self, event=None):

      if self.order.get() == '12345':
            ruler_window.quit()
      else:
            pass


def gotoruler():
    ruler_window = Tk()
    ruler_window.attributes("-topmost", -1)
    Application(ruler_window).mainloop()

Twilight6 发表于 2021-7-9 21:13:03



试试在 if 条件前面试着加上 print(self.order.get()) 调试下代码打印结果 是否符合 if 条件

另外是否有报错?有报错尽量附带报错信息~

Wirror 发表于 2021-7-9 21:15:26

get的结果是12345

Twilight6 发表于 2021-7-9 21:13
试试在 if 条件前面试着加上 print(self.order.get()) 调试下代码打印结果 是否符合 if 条件

另外是 ...

Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\tkinter\__init__.py", line 1883, in __call__
    return self.func(*args)
File "C:\Users\Administrator\PycharmProjects\pythonProject\管理软件\ruler.py", line 60, in Command1_Cmd
    ruler_window.quit()
NameError: name 'ruler_window' is not defined

Twilight6 发表于 2021-7-9 21:20:37

本帖最后由 Twilight6 于 2021-7-9 21:21 编辑

Wirror 发表于 2021-7-9 21:15
Exception in Tkinter callback
Traceback (most recent call last):
File "C:%users\Administrato ...


报错是说 ruler_window 未定义, ruler_window 是函数内的局部变量,所以你把代码

ruler_window.quit()

改成这样试试看:

Application_ui.quit()

Wirror 发表于 2021-7-9 21:26:34

Twilight6 发表于 2021-7-9 21:20
报错是说 ruler_window 未定义, ruler_window 是函数内的局部变量,所以你把代码




TypeError: quit() missing 1 required positional argument: 'self'
少了个参数,如果用self.quit()呢?

Wirror 发表于 2021-7-9 21:27:09

Wirror 发表于 2021-7-9 21:26
TypeError: quit() missing 1 required positional argument: 'self'
少了个参数,如果用self.quit()呢 ...

用self.quit()窗口并没有关闭

Twilight6 发表于 2021-7-9 21:28:05

Wirror 发表于 2021-7-9 21:26
TypeError: quit() missing 1 required positional argument: 'self'
少了个参数,如果用self.quit()呢 ...



看下你完整报错,带上前面几行,你的代码不完整,我不能实时调试,那么报错就尽量发完整些~

Wirror 发表于 2021-7-9 21:28:43

Twilight6 发表于 2021-7-9 21:28
看下你完整报错,带上前面几行

Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\tkinter\__init__.py", line 1883, in __call__
    return self.func(*args)
File "C:\Users\Administrator\PycharmProjects\pythonProject\管理软件\ruler.py", line 60, in Command1_Cmd
    Application_ui.quit()
TypeError: quit() missing 1 required positional argument: 'self'

Twilight6 发表于 2021-7-9 21:31:31

Wirror 发表于 2021-7-9 21:28
Exception in Tkinter callback
Traceback (most recent call last):
File "C:%users\Administrator\ ...



报错附近,代码缩进是不是有些问题,你拷贝发我看看

Wirror 发表于 2021-7-9 21:32:52

Twilight6 发表于 2021-7-9 21:31
报错附近,代码缩进是不是有些问题,你拷贝发我看看

#!/usr/bin/env python
#-*- coding:utf-8 -*-
from modify import *
import os, sys
try:
    from tkinter import *
except ImportError:#Python 2.x
    PythonVersion = 2
    from Tkinter import *
    from tkFont import Font
    from ttk import *
    #Usage:showinfo/warning/error,askquestion/okcancel/yesno/retrycancel
    from tkMessageBox import *
    #Usage:f=tkFileDialog.askopenfilename(initialdir='E:/Python')
    #import tkFileDialog
    #import tkSimpleDialog
else:#Python 3.x
    PythonVersion = 3
    from tkinter.font import Font
    from tkinter.ttk import *
    from tkinter.messagebox import *
    #import tkinter.filedialog as tkFileDialog
    #import tkinter.simpledialog as tkSimpleDialog    #askstring()

class Application_ui(Frame):
    #这个类仅实现界面生成功能,具体事件处理代码在子类Application中。
    def __init__(self, master=None):
      Frame.__init__(self, master)
      self.master.title('Form3')
      self.master.geometry('399x111')
      self.master.resizable(0,0)
      self.createWidgets()

    def createWidgets(self):
      self.top = self.winfo_toplevel()

      self.style = Style()

      self.orderVar = StringVar(value='')
      self.order = Entry(self.top, textvariable=self.orderVar, font=('宋体',9))
      self.order.place(relx=0.261, rely=0.36, relwidth=0.464, relheight=0.225)

      self.style.configure('Label1.TLabel',anchor='w', font=('宋体',9))
      self.Label1 = Label(self.top, text='口令', style='Label1.TLabel')
      self.Label1.place(relx=0.08, rely=0.432, relwidth=0.143, relheight=0.225)

      self.style.configure('Command1.TButton',font=('宋体',9))
      self.Command1 = Button(self.top, text='进入', command=self.Command1_Cmd, style='Command1.TButton')
      self.Command1.place(relx=0.782, rely=0.36, relwidth=0.183, relheight=0.225)


class Application(Application_ui):
    #这个类实现具体的事件处理回调函数。界面生成代码在Application_ui中。
    def __init__(self, master=None):
      Application_ui.__init__(self, master)

    def Command1_Cmd(self, event=None):

      if self.order.get() == '12345':
            Application_ui.quit()
            starter()
      else:
            pass


def gotoruler():
    ruler_window = Tk()
    ruler_window.attributes("-topmost", -1)
    Application(ruler_window).mainloop()

Twilight6 发表于 2021-7-9 21:37:27

Wirror 发表于 2021-7-9 21:32
#!/usr/bin/env python
#-*- coding:utf-8 -*-
from modify import *




试试这里改成这样:

class Application(Application_ui):
    #这个类实现具体的事件处理回调函数。界面生成代码在Application_ui中。
    def __init__(self, master=None):
      Application_ui.__init__(self, master)
      self.master = master

    def Command1_Cmd(self, event=None):

      if self.order.get() == '12345':
            self.master.quit()
            starter()
      else:
            pass


Wirror 发表于 2021-7-9 21:41:03

本帖最后由 Wirror 于 2021-7-9 21:46 编辑

Twilight6 发表于 2021-7-9 21:37
试试这里改成这样:

窗口还是没关掉

Twilight6 发表于 2021-7-9 21:53:14

Wirror 发表于 2021-7-9 21:41
窗口还是没关掉



搞不懂了,呃

Wirror 发表于 2021-7-9 22:00:42

本帖最后由 Wirror 于 2021-7-9 22:03 编辑

Twilight6 发表于 2021-7-9 21:53
搞不懂了,呃

我还有一个文件如果在主函数里Tk()一个对象窗口就可以在Application类里quit掉
#!/usr/bin/env python
#-*- coding:utf-8 -*-
from people import *
from Main_Window import *
from tkinter import *
import tkinter.messagebox
import os, sys
try:
    from tkinter import *
except ImportError:#Python 2.x
    PythonVersion = 2
    from Tkinter import *
    from tkFont import Font
    from ttk import *
    #Usage:showinfo/warning/error,askquestion/okcancel/yesno/retrycancel
    from tkMessageBox import *
    #Usage:f=tkFileDialog.askopenfilename(initialdir='E:/Python')
    #import tkFileDialog
    #import tkSimpleDialog
else:#Python 3.x
    PythonVersion = 3
    from tkinter.font import Font
    from tkinter.ttk import *
    from tkinter.messagebox import *
    #import tkinter.filedialog as tkFileDialog
    #import tkinter.simpledialog as tkSimpleDialog    #askstring()

class Application_ui(Frame):
    #这个类仅实现界面生成功能,具体事件处理代码在子类Application中。
    def __init__(self, master=None):
      Frame.__init__(self, master)
      self.master.title('登录')
      self.master.geometry('900x471')
      self.master.resizable(0,0)
      self.createWidgets()

    def createWidgets(self):
      self.top = self.winfo_toplevel()

      self.style = Style()

      self.style.configure('Quit.TButton',font=('宋体',9))
      self.Quit = Button(self.top, text='退出', command=self.Quit_Cmd, style='Quit.TButton')
      self.Quit.place(relx=0.764, rely=0.696, relwidth=0.126, relheight=0.087)

      self.style.configure('Ok.TButton',font=('宋体',9))
      self.Ok = Button(self.top, text='登录', command=self.Ok_Cmd, style='Ok.TButton')
      self.Ok.place(relx=0.613, rely=0.696, relwidth=0.126, relheight=0.087)

      self.PassWordVar = StringVar(value='')
      self.PassWord = Entry(self.top, show='*', textvariable=self.PassWordVar, font=('宋体',9))
      self.PassWord.place(relx=0.596, rely=0.425, relwidth=0.339, relheight=0.07)

      self.WorkNumberVar = StringVar(value='')
      self.WorkNumber = Entry(self.top, textvariable=self.WorkNumberVar, font=('宋体',9))
      self.WorkNumber.place(relx=0.596, rely=0.306, relwidth=0.339, relheight=0.07)

      self.style.configure('Label2.TLabel',anchor='center', background='#3399FF', font=('宋体',14))
      self.Label2 = Label(self.top, text='', style='Label2.TLabel')
      self.Label2.place(relx=0.329, rely=0.934, relwidth=0.294, relheight=0.053)

      self.style.configure('Label1.TLabel',anchor='center', foreground='#FF8000', background='#00FFFF', font=('宋体',48))
      self.Label1 = Label(self.top, text='', style='Label1.TLabel')
      self.Label1.place(relx=0.142, rely=0.374, relwidth=0.196, relheight=0.221)

      self.style.configure('L3.TLabel',anchor='w', font=('宋体',18))
      self.L3 = Label(self.top, text='工号', style='L3.TLabel')
      self.L3.place(relx=0.516, rely=0.306, relwidth=0.072, relheight=0.07)

      self.style.configure('Label3.TLabel',anchor='w', font=('宋体',18))
      self.Label3 = Label(self.top, text='密码', style='Label3.TLabel')
      self.Label3.place(relx=0.516, rely=0.425, relwidth=0.072, relheight=0.07)

      self.style.configure('set.TButton',font=('宋体',9))
      self.set = Button(self.top, text='注册用户', command=self.set_Cmd, style='set.TButton')
      self.set.place(relx=0.853, rely=0.849, relwidth=0.108, relheight=0.046)
class Application(Application_ui):
    #这个类实现具体的事件处理回调函数。界面生成代码在Application_ui中。
    def __init__(self, master=None):
      Application_ui.__init__(self, master)

    def Quit_Cmd(self, event=None):
      top.quit()
    def show(self, event=None):
      top.update()
      top.deiconify()
    def Ok_Cmd(self, event=None):
      if self.PassWord.get() == '12345':
            top.withdraw()# 这里可以正常关闭

            main_window()

            top.quit()
      else:
            self.PassWord.delete(0, END)
            tkinter.messagebox.askokcancel\
                (title = '密码错误',message='密码错误!')
    def set_Cmd(self, event=None):
      people_set()

if __name__ == "__main__":
    top = Tk()
    Application(top).mainloop()
    try: top.destroy()
    except: pass

Wirror 发表于 2021-7-9 22:11:09

Twilight6 发表于 2021-7-9 21:53
搞不懂了,呃

我还有一个文件,如果函数是主函数就可以

#!/usr/bin/env python
#-*- coding:utf-8 -*-
from people import *
from Main_Window import *
from tkinter import *
import tkinter.messagebox
import os, sys
try:
    from tkinter import *
except ImportError:#Python 2.x
    PythonVersion = 2
    from Tkinter import *
    from tkFont import Font
    from ttk import *
    #Usage:showinfo/warning/error,askquestion/okcancel/yesno/retrycancel
    from tkMessageBox import *
    #Usage:f=tkFileDialog.askopenfilename(initialdir='E:/Python')
    #import tkFileDialog
    #import tkSimpleDialog
else:#Python 3.x
    PythonVersion = 3
    from tkinter.font import Font
    from tkinter.ttk import *
    from tkinter.messagebox import *
    #import tkinter.filedialog as tkFileDialog
    #import tkinter.simpledialog as tkSimpleDialog    #askstring()

class Application_ui(Frame):
    #这个类仅实现界面生成功能,具体事件处理代码在子类Application中。
    def __init__(self, master=None):
      Frame.__init__(self, master)
      self.master.title('登录')
      self.master.geometry('900x471')
      self.master.resizable(0,0)
      self.createWidgets()

    def createWidgets(self):
      self.top = self.winfo_toplevel()

      self.style = Style()

      self.style.configure('Quit.TButton',font=('宋体',9))
      self.Quit = Button(self.top, text='退出', command=self.Quit_Cmd, style='Quit.TButton')
      self.Quit.place(relx=0.764, rely=0.696, relwidth=0.126, relheight=0.087)

      self.style.configure('Ok.TButton',font=('宋体',9))
      self.Ok = Button(self.top, text='登录', command=self.Ok_Cmd, style='Ok.TButton')
      self.Ok.place(relx=0.613, rely=0.696, relwidth=0.126, relheight=0.087)

      self.PassWordVar = StringVar(value='')
      self.PassWord = Entry(self.top, show='*', textvariable=self.PassWordVar, font=('宋体',9))
      self.PassWord.place(relx=0.596, rely=0.425, relwidth=0.339, relheight=0.07)

      self.WorkNumberVar = StringVar(value='')
      self.WorkNumber = Entry(self.top, textvariable=self.WorkNumberVar, font=('宋体',9))
      self.WorkNumber.place(relx=0.596, rely=0.306, relwidth=0.339, relheight=0.07)

      self.style.configure('Label2.TLabel',anchor='center', background='#3399FF', font=('宋体',14))
      self.Label2 = Label(self.top, text='北京自选科贸有限公司', style='Label2.TLabel')
      self.Label2.place(relx=0.329, rely=0.934, relwidth=0.294, relheight=0.053)

      self.style.configure('Label1.TLabel',anchor='center', foreground='#FF8000', background='#00FFFF', font=('宋体',48))
      self.Label1 = Label(self.top, text='自选', style='Label1.TLabel')
      self.Label1.place(relx=0.142, rely=0.374, relwidth=0.196, relheight=0.221)

      self.style.configure('L3.TLabel',anchor='w', font=('宋体',18))
      self.L3 = Label(self.top, text='工号', style='L3.TLabel')
      self.L3.place(relx=0.516, rely=0.306, relwidth=0.072, relheight=0.07)

      self.style.configure('Label3.TLabel',anchor='w', font=('宋体',18))
      self.Label3 = Label(self.top, text='密码', style='Label3.TLabel')
      self.Label3.place(relx=0.516, rely=0.425, relwidth=0.072, relheight=0.07)

      self.style.configure('set.TButton',font=('宋体',9))
      self.set = Button(self.top, text='注册用户', command=self.set_Cmd, style='set.TButton')
      self.set.place(relx=0.853, rely=0.849, relwidth=0.108, relheight=0.046)
class Application(Application_ui):
    #这个类实现具体的事件处理回调函数。界面生成代码在Application_ui中。
    def __init__(self, master=None):
      Application_ui.__init__(self, master)

    def Quit_Cmd(self, event=None):
      top.quit()
    def show(self, event=None):
      top.update()
      top.deiconify()
    def Ok_Cmd(self, event=None):
      if self.PassWord.get() == '12345':
            top.withdraw()

            main_window()

            top.quit()# 这里在类里面可以调用主函数的tk对象
      else:
            self.PassWord.delete(0, END)
            tkinter.messagebox.askokcancel\
                (title = '密码错误',message='密码错误!')
    def set_Cmd(self, event=None):
      people_set()

if __name__ == "__main__":
    top = Tk()
    Application(top).mainloop()
    try: top.destroy()
    except: pass

Twilight6 发表于 2021-7-9 22:34:11

Wirror 发表于 2021-7-9 22:11
我还有一个文件,如果函数是主函数就可以

#!/usr/bin/env python




那我好像明白了,你先前代码的调用是如何调用的?是不是直接 gotoruler()?

Wirror 发表于 2021-7-10 10:43:46

Twilight6 发表于 2021-7-9 22:34
那我好像明白了,你先前代码的调用是如何调用的?是不是直接 gotoruler()?

对对

Twilight6 发表于 2021-7-10 10:49:45

Wirror 发表于 2021-7-10 10:43
对对



gotoruler 中创建的变量属于局部变量,你 gotoruler 函数一执行结束就导致变量被内存回收机制给回收了

所以导致你先前的窗口无法 quit,你不把他封装成函数,放在全局正常执行试试看,应该就没问题了

Wirror 发表于 2021-7-10 11:00:52

本帖最后由 Wirror 于 2021-7-10 11:03 编辑

Twilight6 发表于 2021-7-10 10:49
gotoruler 中创建的变量属于局部变量,你 gotoruler 函数一执行结束就导致变量被内存回收机制给回收 ...

明白了,可是如果想在1.py打开2.py写的窗口怎么实现呢?主函数只能有一个
得先from 2 import *
然后在用里面的函数啊{:5_92:}

Twilight6 发表于 2021-7-10 11:06:16

Wirror 发表于 2021-7-10 11:00
明白了,可是如果想在1.py打开2.py写的窗口怎么实现呢?主函数只能有一个

把你之前代码最后改成这样试试看:

class Application(Application_ui):

    def __init__(self, master=None):
      Application_ui.__init__(self, master)

    def Command1_Cmd(self, event=None):

      if self.order.get() == '12345':
            ruler_window.quit()
            starter()
      else:
            pass

ruler_window = 0
def gotoruler():
    global ruler_window
    ruler_window = Tk()
    ruler_window.attributes("-topmost", -1)
    Application(ruler_window).mainloop()
页: [1] 2
查看完整版本: tkinter: 函数中Tk()一个对象为什么在Application类中不能quit()?好像是作用域的问题