簡體   English   中英

Tkinter按鈕執行腳本拋出NameError

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM