首页 > 解决方案 > Tkinter 程序错误:UnboundLocalError:分配前引用的局部变量 'conn'

问题描述

我不明白这个错误:

File "c:\Users\Leon\Desktop\Page Guis\Client Chat Gui\unknown2.py", line 169, in __init__
self.Button1.configure(command=conn)
UnboundLocalError: local variable 'conn' referenced before assignment

完整代码:

        #  -*- coding: utf-8 -*-
    import platform
    import sys
    import socket
    import tkinter as tk
    import tkinter.ttk as ttk
    py3 = True


    version = "1.0"


    def vp_start_gui():
        '''Starting point when module is the main routine.'''
        global val, w, root
        root = tk.Tk()
        top = Toplevel1(root)
        root.mainloop()


    w = None


    def create_Toplevel1(rt, *args, **kwargs):
        '''Starting point when module is imported by another module.
        Correct form of call: 'create_Toplevel1(root, *args, **kwargs)' .'''
        global w, w_win, root
        #rt = root
        root = rt
        w = tk.Toplevel(root)
        top = Toplevel1(w)
        unknown2_support.init(w, top, *args, **kwargs)
        return (w, top)


    def destroy_Toplevel1():
        global w
        w.destroy()
        w = None


    class Toplevel1:
        def __init__(self, top=None):

            def passText(event, self):
                self.Entry2.delete(0, END)

            _bgcolor = '#d9d9d9'  # X11 color: 'gray85'
            _fgcolor = '#000000'  # X11 color: 'black'
            _compcolor = '#d9d9d9'  # X11 color: 'gray85'
            _ana1color = '#d9d9d9'  # X11 color: 'gray85'
            _ana2color = '#ececec'  # Closest X11 color: 'gray92'

            self.style = ttk.Style()
            self.style.theme_use()
            self.style.configure('.', background=_bgcolor)
            self.style.configure('.', foreground=_fgcolor)
            self.style.map('.', background=[
                        ('selected', _compcolor), ('active', _ana2color)])

            top.geometry("672x551+292+105")
            top.minsize(120, 1)
            top.maxsize(1370, 749)
            top.resizable(1,  1)
            top.title("Client Chat (" + version+")")
            top.configure(background="#d9d9d9")

            self.Frame1 = tk.Frame(top)
            self.Frame1.place(relx=0.238, rely=0.0,
                            relheight=0.989, relwidth=0.757)
            self.Frame1.configure(relief='groove')
            self.Frame1.configure(borderwidth="2")
            self.Frame1.configure(relief="groove")
            self.Frame1.configure(background="#d9d9d9")

            self.Entry2 = tk.Entry(self.Frame1)
            self.Entry2.place(relx=0.02, rely=0.899, height=40, relwidth=0.715)
            self.Entry2.configure(background="white")
            self.Entry2.configure(disabledforeground="#a3a3a3")
            self.Entry2.configure(font="TkFixedFont")
            self.Entry2.configure(foreground="#000000")
            self.Entry2.configure(insertbackground="black")
            self.Entry2.insert(0, "Message:")
            self.Entry2.bind("<Button>", passText)

            self.Button2 = tk.Button(self.Frame1)
            self.Button2.place(relx=0.766, rely=0.899, height=44, width=107)
            self.Button2.configure(activebackground="#ececec")
            self.Button2.configure(activeforeground="#000000")
            self.Button2.configure(background="#d9d9d9")
            self.Button2.configure(disabledforeground="#a3a3a3")
            self.Button2.configure(foreground="#000000")
            self.Button2.configure(highlightbackground="#d9d9d9")
            self.Button2.configure(highlightcolor="black")
            self.Button2.configure(pady="0", relief='groove')
            self.Button2.configure(text='''SEND''')

            self.Scrolledlistbox1 = ScrolledListBox(self.Frame1)
            self.Scrolledlistbox1.place(
                relx=0.02, rely=0.018, relheight=0.853, relwidth=0.965)
            self.Scrolledlistbox1.configure(background="white")
            self.Scrolledlistbox1.configure(disabledforeground="#a3a3a3")
            self.Scrolledlistbox1.configure(font="TkFixedFont")
            self.Scrolledlistbox1.configure(foreground="black")
            self.Scrolledlistbox1.configure(highlightbackground="#d9d9d9")
            self.Scrolledlistbox1.configure(highlightcolor="#d9d9d9")
            self.Scrolledlistbox1.configure(selectbackground="blue")
            self.Scrolledlistbox1.configure(selectforeground="white")

            self.Frame2 = tk.Frame(top)
            self.Frame2.place(relx=0.0, rely=0.0, relheight=0.989, relwidth=0.225)
            self.Frame2.configure(relief='groove')
            self.Frame2.configure(borderwidth="2")
            self.Frame2.configure(relief="groove")
            self.Frame2.configure(background="#d9d9d9")

            self.Label1 = tk.Label(self.Frame2)
            self.Label1.place(relx=0.066, rely=0.018, height=21, width=124)
            self.Label1.configure(anchor='w')
            self.Label1.configure(background="#d9d9d9")
            self.Label1.configure(disabledforeground="#a3a3a3")
            self.Label1.configure(foreground="#000000")
            self.Label1.configure(text='''IP Adress:''')

            self.Entry1 = tk.Entry(self.Frame2)
            self.Entry1.place(relx=0.066, rely=0.073, height=20, relwidth=0.821)
            self.Entry1.configure(background="white")
            self.Entry1.configure(disabledforeground="#a3a3a3")
            self.Entry1.configure(font="TkFixedFont")
            self.Entry1.configure(foreground="#000000")
            self.Entry1.configure(insertbackground="black")

            self.Label1_1 = tk.Label(self.Frame2)
            self.Label1_1.place(relx=0.066, rely=0.147, height=21, width=124)
            self.Label1_1.configure(activebackground="#f9f9f9")
            self.Label1_1.configure(activeforeground="black")
            self.Label1_1.configure(anchor='w')
            self.Label1_1.configure(background="#d9d9d9")
            self.Label1_1.configure(disabledforeground="#a3a3a3")
            self.Label1_1.configure(foreground="#000000")
            self.Label1_1.configure(highlightbackground="#d9d9d9")
            self.Label1_1.configure(highlightcolor="black")
            self.Label1_1.configure(text='''PORT Adress:''')

            self.Entry1_1 = tk.Entry(self.Frame2)
            self.Entry1_1.place(relx=0.066, rely=0.202, height=20, relwidth=0.821)
            self.Entry1_1.configure(background="white")
            self.Entry1_1.configure(disabledforeground="#a3a3a3")
            self.Entry1_1.configure(font="TkFixedFont")
            self.Entry1_1.configure(foreground="#000000")
            self.Entry1_1.configure(highlightbackground="#d9d9d9")
            self.Entry1_1.configure(highlightcolor="black")
            self.Entry1_1.configure(insertbackground="black")
            self.Entry1_1.configure(selectbackground="blue")
            self.Entry1_1.configure(selectforeground="white")

            self.Button1 = tk.Button(self.Frame2)
            self.Button1.place(relx=0.066, rely=0.275, height=24, width=127)
            self.Button1.configure(activebackground="#ececec")
            self.Button1.configure(activeforeground="#000000")
            self.Button1.configure(background="#d9d9d9")
            self.Button1.configure(disabledforeground="#a3a3a3")
            self.Button1.configure(foreground="#000000")
            self.Button1.configure(highlightbackground="#d9d9d9")
            self.Button1.configure(highlightcolor="black")
            self.Button1.configure(pady="0")
            self.Button1.configure(relief="groove")
            self.Button1.configure(text='''CONNECT''')
            self.Button1.configure(command=conn)

            msg_in = Entry2.get()
            connect = False

            def conn():
                HOST = Entry1.get()
                PORT = Entry1_1.get()

                client_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                client_sock.connect((HOST, PORT))
                connect = True

                while True:
                    client_sock.send(bytes(msg_in, 'utf-8'))

    # The following code is added to facilitate the Scrolled widgets you specified.


    class AutoScroll(object):
        '''Configure the scrollbars for a widget.'''

        def __init__(self, master):
            #  Rozen. Added the try-except clauses so that this class
            #  could be used for scrolled entry widget for which vertical
            #  scrolling is not supported. 5/7/14.
            vsb = ttk.Scrollbar(master, orient='vertical', command=self.yview)
            hsb = ttk.Scrollbar(master, orient='horizontal', command=self.xview)
            self.configure(yscrollcommand=self._autoscroll(vsb))
            self.configure(xscrollcommand=self._autoscroll(hsb))
            self.grid(column=0, row=0, sticky='nsew')
            vsb.grid(column=1, row=0, sticky='ns')
            hsb.grid(column=0, row=1, sticky='ew')
            master.grid_columnconfigure(0, weight=1)
            master.grid_rowconfigure(0, weight=1)
            # Copy geometry methods of master  (taken from ScrolledText.py)
            methods = tk.Pack.__dict__.keys() | tk.Grid.__dict__.keys() \
                | tk.Place.__dict__.keys()

            for meth in methods:
                if meth[0] != '_' and meth not in ('config', 'configure'):
                    setattr(self, meth, getattr(master, meth))

        @staticmethod
        def _autoscroll(sbar):
            '''Hide and show scrollbar as needed.'''
            def wrapped(first, last):
                first, last = float(first), float(last)
                if first <= 0 and last >= 1:
                    sbar.grid_remove()
                else:
                    sbar.grid()
                sbar.set(first, last)
            return wrapped

        def __str__(self):
            return str(self.master)


    def _create_container(func):
        '''Creates a ttk Frame with a given master, and use this new frame to
        place the scrollbars and the widget.'''
        def wrapped(cls, master, **kw):
            container = ttk.Frame(master)
            container.bind('<Enter>', lambda e: _bound_to_mousewheel(e, container))
            container.bind(
                '<Leave>', lambda e: _unbound_to_mousewheel(e, container))
            return func(cls, container, **kw)
        return wrapped


    class ScrolledListBox(AutoScroll, tk.Listbox):
        '''A standard Tkinter Listbox widget with scrollbars that will
        automatically show/hide as needed.'''
        @_create_container
        def __init__(self, master, **kw):
            tk.Listbox.__init__(self, master, **kw)
            AutoScroll.__init__(self, master)

        def size_(self):
            sz = tk.Listbox.size(self)
            return sz


    def _bound_to_mousewheel(event, widget):
        child = widget.winfo_children()[0]
        if platform.system() == 'Windows' or platform.system() == 'Darwin':
            child.bind_all('<MouseWheel>', lambda e: _on_mousewheel(e, child))
            child.bind_all('<Shift-MouseWheel>',
                        lambda e: _on_shiftmouse(e, child))
        else:
            child.bind_all('<Button-4>', lambda e: _on_mousewheel(e, child))
            child.bind_all('<Button-5>', lambda e: _on_mousewheel(e, child))
            child.bind_all('<Shift-Button-4>', lambda e: _on_shiftmouse(e, child))
            child.bind_all('<Shift-Button-5>', lambda e: _on_shiftmouse(e, child))


    def _unbound_to_mousewheel(event, widget):
        if platform.system() == 'Windows' or platform.system() == 'Darwin':
            widget.unbind_all('<MouseWheel>')
            widget.unbind_all('<Shift-MouseWheel>')
        else:
            widget.unbind_all('<Button-4>')
            widget.unbind_all('<Button-5>')
            widget.unbind_all('<Shift-Button-4>')
            widget.unbind_all('<Shift-Button-5>')


    def _on_mousewheel(event, widget):
        if platform.system() == 'Windows':
            widget.yview_scroll(-1*int(event.delta/120), 'units')
        elif platform.system() == 'Darwin':
            widget.yview_scroll(-1*int(event.delta), 'units')
        else:
            if event.num == 4:
                widget.yview_scroll(-1, 'units')
            elif event.num == 5:
                widget.yview_scroll(1, 'units')


    def _on_shiftmouse(event, widget):
        if platform.system() == 'Windows':
            widget.xview_scroll(-1*int(event.delta/120), 'units')
        elif platform.system() == 'Darwin':
            widget.xview_scroll(-1*int(event.delta), 'units')
        else:
            if event.num == 4:
                widget.xview_scroll(-1, 'units')
            elif event.num == 5:
                widget.xview_scroll(1, 'units')

    vp_start_gui()

我也试过 autopep8 但这是同样的错误:

Traceback (most recent call last):
  File "c:\Users\Leon\Desktop\Page Guis\Client Chat Gui\unknown2.py", line 300, in <module>
    vp_start_gui()
  File "c:\Users\Leon\Desktop\Page Guis\Client Chat Gui\unknown2.py", line 17, in vp_start_gui
    top = Toplevel1(root)
  File "c:\Users\Leon\Desktop\Page Guis\Client Chat Gui\unknown2.py", line 169, in __init__
    self.Button1.configure(command=conn)
UnboundLocalError: local variable 'conn' referenced before assignment

标签: pythontkinter

解决方案


command=conn在您实际定义之前,您已经conn使用def conn(). 将函数移动conn到引用它的上方某处。否则你在conn分配任何东西之前引用它,因此错误:

def conn():
  ...
...
self.Button1.configure(command=conn)

推荐阅读