我正在用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
语句上。您正在打开另一个名为.py
的port_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.")