[英]Tkinter button executing script throws NameError
我有一个Tkinter GUI,其中三个按钮分别运行一个单独的脚本。 其中两个可以很好地加载,但是第三个抛出了NameError,说我的名字之一没有定义。 但是,当我不通过GUI运行脚本时,它运行良好。
这是GUI代码:
import sys
import os
import tkinter
import cv2
from tkinter.filedialog import askopenfilename
from tkinter import messagebox
import numpy as np
import matplotlib.pyplot as plt
top=tkinter.Tk()
top.geometry("300x350")
top.config(background='black')
top.title('Test')
top.resizable(height=False, width=False)
def thresholdCallBack():
exec(open('motionindexthreshold.py').read())
def autoremoveCallBack():
exec(open('motionindexgenerator.py').read())
def videoTaggingCallBack():
exec(open('stepthrough.py').read())
def quitCallBack():
top.destroy()
M = tkinter.Message(top, text='Test', width=280, background='black', foreground='white', font=('Courier', 28))
B = tkinter.Button(top,text="Define Motion Index Threshold",command= thresholdCallBack)
C = tkinter.Button(top,text="Autoremove Nonmovement Video Segments",command= autoremoveCallBack)
D = tkinter.Button(top,text="Tag Video Frames",command= videoTaggingCallBack)
E = tkinter.Button(top,text="Quit", command=quitCallBack)
B.config(height=5, width=80, background='red')
C.config(height=5, width=80, background='blue', foreground='white')
D.config(height=5, width=80, background='yellow')
E.config(height=5, width=80, background='green')
M.pack()
B.pack()
C.pack()
D.pack()
E.pack()
top.mainloop()
这是注册按键时崩溃的python脚本:
import cv2
import tkinter as tk
from tkinter.filedialog import askopenfilename
from tkinter import messagebox
import numpy as np
import os
import matplotlib.pyplot as plt
import sys
framevalues = []
count = 1
root = tk.Tk()
root.withdraw()
selectedvideo = askopenfilename()
selectedvideostring = str(selectedvideo)
cap = cv2.VideoCapture(selectedvideo)
length = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
def stanceTag():
framevalues.append('0' + ' ' + '|' + ' ' + str(int(cap.get(1))))
print (str(int(cap.get(1))), '/', length)
print(framevalues)
def swingTag():
framevalues.append('1' + ' ' + '|' + ' ' + str(int(cap.get(1))))
print (str(int(cap.get(1))), '/', length)
print(framevalues)
def unsureTag():
framevalues.append('-1' + ' ' + '|' + ' ' + str(int(cap.get(1))))
print (str(int(cap.get(1))), '/', length)
print(framevalues)
def rewindFrames():
cap.set(1,((int(cap.get(1)) - 2)))
print (int(cap.get(1)), '/', length)
framevalues.pop()
print(framevalues)
while (cap.isOpened()):
ret, frame = cap.read()
# check if read frame was successful
if ret == False:
break
# show frame first
cv2.imshow('frame',frame)
# then waitKey
frameclick = cv2.waitKey(0) & 0xFF
if frameclick == ord('a'):
swingTag()
elif frameclick == ord('r'):
rewindFrames()
elif frameclick == ord('s'):
stanceTag()
elif frameclick == ord('d'):
unsureTag()
elif frameclick == ord('q'):
with open((selectedvideostring + '.txt'), 'w') as textfile:
for item in framevalues:
textfile.write("{}\n".format(item))
break
else:
continue
cap.release()
cv2.destroyAllWindows()
有谁知道如何解决这个问题?
谢谢
如果您需要从另一个python脚本运行代码,则应该使用导入来获取另一个脚本并在另一个脚本中运行函数。 这将是代码的问题,因为您将程序的核心置于函数之外,因此它将在导入后立即运行。 由于这个原因(以及其他原因),您应该在函数中包含所有代码。 您可以通过检查__main__
属性来检测代码是否已导入。
我对代码进行了重组,将所有代码移到函数中,然后将其导入并从GUI按钮调用适当的函数。
这是您的GUI代码应如下所示:
import tkinter
import motionindexthreshold
import motionindexgenerator
import stepthrough
def main():
top=tkinter.Tk()
top.geometry("300x350")
top.config(background='black')
top.title('Test')
top.resizable(height=False, width=False)
M = tkinter.Message(top, text='Test', width=280, background='black', foreground='white', font=('Courier', 28))
B = tkinter.Button(top,text="Define Motion Index Threshold",command=motionindexthreshold.main)
C = tkinter.Button(top,text="Autoremove Nonmovement Video Segments",command=motionindexgenerator.main)
D = tkinter.Button(top,text="Tag Video Frames",command=stepthrough.main)
E = tkinter.Button(top,text="Quit", command=top.destroy)
B.config(height=5, width=80, background='red')
C.config(height=5, width=80, background='blue', foreground='white')
D.config(height=5, width=80, background='yellow')
E.config(height=5, width=80, background='green')
M.pack()
B.pack()
C.pack()
D.pack()
E.pack()
top.mainloop()
if __name__ == '__main__':
main()
这是您的模块代码应如下所示:
import cv2
import tkinter as tk
from tkinter.filedialog import askopenfilename
def stanceTag(cap, framevalues):
framevalues.append('0' + ' ' + '|' + ' ' + str(int(cap.get(1))))
print (str(int(cap.get(1))), '/', length)
print(framevalues)
def swingTag(cap, framevalues):
framevalues.append('1' + ' ' + '|' + ' ' + str(int(cap.get(1))))
print (str(int(cap.get(1))), '/', length)
print(framevalues)
def unsureTag(cap, framevalues):
framevalues.append('-1' + ' ' + '|' + ' ' + str(int(cap.get(1))))
print (str(int(cap.get(1))), '/', length)
print(framevalues)
def rewindFrames(cap, framevalues):
cap.set(1,((int(cap.get(1)) - 2)))
print (int(cap.get(1)), '/', length)
framevalues.pop()
print(framevalues)
def main():
framevalues = []
count = 1
selectedvideo = askopenfilename()
selectedvideostring = str(selectedvideo)
cap = cv2.VideoCapture(selectedvideo)
length = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
while (cap.isOpened()):
ret, frame = cap.read()
# check if read frame was successful
if ret == False:
break
# show frame first
cv2.imshow('frame',frame)
# then waitKey
frameclick = cv2.waitKey(0) & 0xFF
if frameclick == ord('a'):
swingTag(cap, framevalues)
elif frameclick == ord('r'):
rewindFrames(cap, framevalues)
elif frameclick == ord('s'):
stanceTag(cap, framevalues)
elif frameclick == ord('d'):
unsureTag(cap, framevalues)
elif frameclick == ord('q'):
with open((selectedvideostring + '.txt'), 'w') as textfile:
for item in framevalues:
textfile.write("{}\n".format(item))
break
else:
continue
cap.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
# this is called if this code was not imported ... ie it was directly run
# if this is called, that means there is no GUI already running, so we need to create a root
root = tk.Tk()
root.withdraw()
main()
显然这是一个猜测; 我无法测试这是否可以解决您的问题,但我认为可以。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.