我正在用tkinter制作GUI,允许我单击一个将运行端口扫描的按钮。我有一个用于端口扫描的脚本,该脚本可以正常运行,我已经设法通过GUI上的按钮打开了端口扫描器,但是随后我收到了一个错误,否则单独运行端口扫描器时不会收到此错误。

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\Steve\AppData\Local\Programs\Python\Python35-32\lib\tkinter\__init__.py", line 1550, in __call__
    return self.func(*args)
  File "<string>", line 51, in Scan
NameError: name 'IP_Input' is not defined


我的代码:

class CallWrapper:
    """Internal class. Stores function to call when some user
    defined Tcl function is called e.g. after an event occurred."""
    def __init__(self, func, subst, widget):
        """Store FUNC, SUBST and WIDGET as members."""
        self.func = func
        self.subst = subst
        self.widget = widget

    def __call__(self, *args):
        """Apply first function SUBST to arguments, than FUNC."""
        try:
            if self.subst:
                args = self.subst(*args)
            return self.func(*args)           # THIS IS THE ERROR #
        except SystemExit:
            raise
        except:
            self.widget._report_exception()


class XView:
    """Mix-in class for querying and changing the horizontal position
    of a widget's window."""

    def xview(self, *args):
        """Query and change the horizontal position of the view."""
        res = self.tk.call(self._w, 'xview', *args)


这是第51行错误之后的代码

def Scan():
    print ('Scan Called.') #Debugging
    IP = str(IP_Input.get(0.0, tkinter.END))    #THIS IS ERROR LINE 51#
    print ("IP #Debugging")
    Start = int(PortS.get(0.0, tkinter.END))
    End = int(PortE.get(0.0, tkinter.END))
    TestSocket = socket.socket()
    CurrentPort = Start
    OpenPorts = 0
    print ('Starting scan...')
    HowFar = int(CurrentPort/End * 100)
    ProgText = HowFar, r'%'
    Label1.config(text=('Percentage Done:', ProgText))

最佳答案

问题出在您的exec语句上。您正在打开另一个名为.pyport_scanner.py文件,然后调用exec(open("./port scanner.py))

这只是行不通的。

为什么这样不起作用:

当您执行exec(open("path to .py file").read())时,exec当然会执行此代码,但是问题是此文件中的全局变量不在范围内。

因此,要使这项工作(我不建议这样做),您必须使用:

exec(open(path).read(), globals())


documentation


  如果globals词典不包含键内置函数的值,则在该键下插入对内置模块buildins词典的引用。这样,您可以通过将自己的内建字典插入全局变量中,然后再将其传递给exec()来控制可执行代码可以使用哪些内建。


如果您确实想以这种方式调用文件,则应使用os.system

替代方法:

您确实不需要以这种方式调用文件。现在,您有两个Tk()实例正在运行。如果需要另一个窗口,则为此提供了一个小部件。这是Toplevel小部件。您可以重组代码以创建一个Toplevel实例,该实例在您单击按钮时就包含端口扫描器应用程序。一个示例是,使用Toplevel小部件(如果需要,在其他文件中)创建端口扫描器应用程序,然后将“ app”导入到文件中,然后单击按钮以初始化应用程序。

补充说明:

您正在调用while循环,如果该循环运行(持续任何明显的时间),则这将阻塞GUI的主事件循环并导致GUI“挂起”。

您的第一个猜测不应是经过广泛测试和使用的python标准库的一部分存在缺陷。问题是(99.9%的时间)

while True:
    print("In your own code.")

10-06 13:19