I have a Tkinter GUI with three buttons running a separate script each. Two of them load fine, however the third one throws up a NameError, saying one of my names isn't defined. However when I run the script not through the GUI, it runs fine.
This is the GUI code:
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()
And this is the python script that crashes when a keypress is registered:
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()
Does anyone have any ideas how to solve this issue?
Thanks
If you need to run code from another python script, then you should use an import to get the other script and run a function in the other script. This will be a problem with your code since you have the core of your program outside of a function, so it would run as soon as it's imported. For the reason (and others) you should have all of your code in functions. You can detect if the code was imported or not by checking the __main__
attribute.
I restructured your code to move all the code into functions, then import it and call the appropriate function from the GUI buttons.
This is what your GUI code should look like:
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()
And this is what your module code should look like:
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()
Obviously this is a guess; I have no way to test if this solves your issue, but I think it will.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.