V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
qile1
V2EX  ›  Python

tkinter 如何退出,具体是在多线程下面如何退出

  •  
  •   qile1 · 2018-09-19 19:36:37 +08:00 · 4600 次点击
    这是一个创建于 2262 天前的主题,其中的信息可能已经有所发展或是发生改变。

    弄了一个 windown10 后台循环读文件程序。程序运行后最小化到桌面右下角。在右下角图标上面有 3 个功能菜单,一个显示“配置参数”界面,一个显示“运行列表”界面,一个退出按钮

    “配置参数”界面可以正常显示关闭。 “运行列表”界面关闭后,点击桌面右下角退出按钮后,程序退出隔一会儿会报错,报错内容如下:

    Exception ignored in: <bound method Variable.__del__ of <tkinter.StringVar object at 0x03DFAEF0>>
    Traceback (most recent call last):
      File "C:\Users\85447\AppData\Local\Programs\Python\Python36-32\lib\tkinter\__init__.py", line 329, in __del__
        if self._tk.getboolean(self._tk.call("info", "exists", self._name)):
    RuntimeError: main thread is not in main loop
    Tcl_AsyncDelete: async handler deleted by the wrong thread
    

    此段代码可能是产生报错原因

    instrserial_button = Entry(self, textvariable=self.dec_name_dict[dish], width=15,
                                               bg='white',state='readonly')#.grid(row=j, column=3)
    

    使用 sysTrayIcon 做的桌面右下角图标,主要代码摘抄这里

    def showRegSet_sys(sysTrayIcon):
        try:
            title = u'reg instrserial(NET)'
            w1hd2 = win32gui.FindWindow(0, title)
            # w1hd = 0
            print ("w1hd2",w1hd2)
            if w1hd2 ==0:
                #print ("w1hd==0")
                Regroot = Tk()
                # decroot.wm_attributes('-topmost',1)
                Regroot.geometry("400x300")
                app2 = regWindow(Regroot)
                def on_focus_out(event):
                    if event.widget == Regroot:
                        Regroot.destroy()
                        # Regroot.quit
                Regroot.bind("<FocusOut>", on_focus_out)
                Regroot.mainloop()
            else:
                win32gui.SetForegroundWindow(w1hd2)
        except Exception as E:
            pass
            print(E)
    class regWindow(Frame):#弹出桌面框显示类
        """定义一个 window 类,window 的父类是 frame,这样 window 就用了 frames 的属性和功能"""
        def __init__(self,master=NONE):
            #__int()__这里是一个构造函数
            Frame.__init__(self,master)
            self.master=master
            # self.reg_instr = p_query(
            #     """SELECT  instrid,instrserial,instrsn,register_dt,install_dt FROM lab_instrument1 order by instrid """)
            self.reg_instr = [(1, '230', '1mvpwtpkdv'), (2, '500', 'yxc3juy5p3')]
            self.initwindow()
            # self.initwindow2()
    
        def initwindow(self):#tkinter 模块添加按钮,相对于长提多了如下部分代码
            #设置窗体标题
            self.master.title("reg instrserial(NET)")
            self.sv = StringVar()
            self.sv2 = StringVar()
            self.pack(side="top", fill="x")
            # dishes=[("1","23"),("2","gsdf"),("3","fdgsrd"),("4","dfg")]
            self.order = {}
            self.add_buttons = {}
            self.instrserial_button_dict={}
            self.price_labels = {}
            self.order_labels = {}
            self.state_dict = {}
            self.svv2 = {}
            self.svv = {}
            self.dec_name_dict = {}
            j = 2
            self.en6 = StringVar()
            nianling2 = Entry(self, width=25, bg='white', state='readonly', textvariable=self.en6).grid(row=j-1, column=1,  columnspan=2)
            self.en6.set("uuu")
            Button_chaxun = Button(self, text='关闭', command=self.clinet_exit).grid(row=j-1, column=4)
            # Button_chaxun = Button(self, text='关闭 2', command=self.master.quit).grid(row=j - 1, column=3)
            for dish in self.reg_instr:
    
                self.svv[dish[0]] = StringVar()
                self.dec_name_dict[dish[0]] = StringVar()
            Label(self, text="ID").grid(row=j, column=1)
            Label(self, text="码").grid(row=j, column=2)
            for i in self.reg_instr:
                j += 2
                print("j:",j)
                # dish, price = dish_data[0], dish_data[1].encode('latin-1').decode('gbk')
                instrid, instrserial, instrsn = i
                dish = i[0]
                name = i[1].encode('latin-1').decode('gbk')
                self.state_dict[dish] = 'normal'
                self.svv2[dish] = dish
                self.dec_name_dict[dish].set(name)
                sn_code = 10
                if sn_code > 0:
                    b = Entry(self, width=15, bg='white', state='readonly')#.grid(row=j, column=2)
                    instrserial_button = Entry(self, textvariable=self.dec_name_dict[dish], width=15,
                                               bg='white',state='readonly')#.grid(row=j, column=3)
                else:
                    pass
                    # b = Entry(self, width=15, bg='white', state='readonly')
                    # b = Entry(self, textvariable=self.svv[dish], validate="focusout", width=15, bg='white', state=self.state_dict[dish],
                    #           validatecommand=lambda d=self.svv[dish], k=dish: self.add_dish_to_order(d, self.state_dict[dish], k))
                    # instrserial_button = Entry(self, textvariable=self.dec_name_dict[dish], validate="focusout", width=15,
                    #                        bg='white',state=self.state_dict[dish],
                    #                        validatecommand=lambda d=self.dec_name_dict[dish],instrid=dish, k=name: self.add_dec_name(d,instrid,k))#.grid(row=j, column=3)
                # # b['state']  = 'readonly'svv2[dish]
                # #  print(dish)
                self.add_buttons[dish] = b
                self.add_buttons[dish].grid(row=j, column=2)
                self.instrserial_button_dict[dish]=instrserial_button
                self.instrserial_button_dict[dish].grid(row=j, column=3)
    
        def add_dish_to_order(self, d, dish, i):
            return True
    
        def add_dec_name(self, d, instrid, i):
            return True
    
        def clinet_exit(self):
            # self.master.deiconify()
            # print('showRegSet()')
            self.master.destroy()
    
    
    menu_options = (('显示(S)', None,showDecSet),
                    ('other', None, (('解码注册', None, showRegSet_sys),
                                     ))
                   )
                   
    

    参考代码在这里 https://paste.ubuntu.com/p/VzTV26tcvc/

    1 条回复    2018-09-20 22:51:08 +08:00
    qile1
        1
    qile1  
    OP
       2018-09-20 22:51:08 +08:00
    Regroot.destroy() 已经销毁了,为啥还会提示 main thread is not in main loop
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1092 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 22:34 · PVG 06:34 · LAX 14:34 · JFK 17:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.