【问题标题】:GUI freezes the rest of python codeGUI 冻结了其余的 python 代码
【发布时间】:2014-05-25 15:05:52
【问题描述】:

我在 python 中使用 wx gui。和一个opencv对象检测。 GUI 在我运行它时冻结其余代码 GUI 出现,当我关闭窗口时代码启动我发现很多关于这个问题的提问者> 解决方案是创建一个线程来运行 gui 并在 main 方法中启动这个线程但是同样的问题仍然存在这里是线程

class GuIthread(threading.Thread):

def __init__ (self):
    threading.Thread.__init__(self)

def run(self):
    gettext.install("app") # replace with the appropriate catalog name\
    global View

    app = MyApp(0)
    app.MainLoop()

那么这里是主要方法

if __name__ == '__main__':
parser = OptionParser(usage = "usage: %prog [options] [filename|camera_index]")
parser.add_option("-c", "--cascade", action="store", dest="cascade", type="str", help="Haar cascade file, default %default", default = "../data/haarcascades/haarcascade_frontalface_alt.xml")
(options, args) = parser.parse_args()

cascade = cv.Load(options.cascade)
global Count

if len(args) != 1:
    parser.print_help()
    sys.exit(1)

input_name = args[0]
if input_name.isdigit():
    capture = cv.CreateCameraCapture(int(input_name))
else:
    capture = None

cv.NamedWindow("video", 1)

#size of the video
width = 600
height = 500

if width is None:
    width = int(cv.GetCaptureProperty(capture, cv.CV_CAP_PROP_FRAME_WIDTH))
else:
    cv.SetCaptureProperty(capture,cv.CV_CAP_PROP_FRAME_WIDTH,width)

if height is None:
    height = int(cv.GetCaptureProperty(capture, cv.CV_CAP_PROP_FRAME_HEIGHT))
else:
    cv.SetCaptureProperty(capture,cv.CV_CAP_PROP_FRAME_HEIGHT,height)

if capture:
    frame_copy = None
    thread1 = myThread()
    thread1.start()
    threadGUI = GuIthread()
    threadGUI.start()
    threadGUI.join()
    frame_copy = None
    t0=time.time()
    while True:
        global frame 
        frame = cv.QueryFrame(capture)
      #  cv.SaveImage('pic.jpg', frame)
        t1=time.time()
        if (t1-t0) >= 10:
            thread1.run()
            t0=t1
            SendPic (frame)
            Count=0                

        if not frame:
            cv.WaitKey(0)
            break
        if not frame_copy:
            frame_copy = cv.CreateImage((frame.width,frame.height),
                                        cv.IPL_DEPTH_8U, frame.nChannels)

        if frame.origin == cv.IPL_ORIGIN_TL:
            cv.Copy(frame, frame_copy)
        else:
            cv.Flip(frame, frame_copy, 0)

        detect_and_draw(frame_copy, cascade)

        if cv.WaitKey(10) >= 0:
            break
else:
    image = cv.LoadImage(input_name, 1)
    detect_and_draw(image, cascade)
    cv.WaitKey(0)

cv.DestroyWindow("video")

出现 gui 和视频窗口,但代码不运行,除非我关闭 GUI 窗口视频开始

我尝试的是 我添加了 GUIthread.join() (添加之前分段错误) 我试图让代码在一个方法中运行 GUI 并调用它,结果发生了相同的结果,但没有出现视频窗口。

【问题讨论】:

  • 这是一个 wxPython GUI 程序吗?你的方法是倒退的。通常,您在主线程上启动 GUI 循环。然后工作线程或后台线程执行您需要的任何处理并更新 GUI。对于 wxPython,有很多关于如何构建程序的很好的示例,请参阅此处作为开始。 wiki.wxpython.org/Non-Blocking%20Gui
  • 这个链接建议的是我已经做过的。创建一个线程并在main方法的最开始调用它
  • 不,正如我所说,它是倒退的。您试图将 GUI 放入第二个线程。 GUI 循环需要保留在主线程中(这可能是您遇到 seg 错误的原因)。您的“捕获”代码属于后台线程。这有点过时了,但它是使用 wxPython 进行线程化的更好示例:wiki.wxpython.org/LongRunningTasks
  • @user3673789 Mark 已经明确指出了你的问题。
  • 所以@Mark 你在说什么我必须在一个线程中制作整个代码并将GUI作为我的主要内容(对不起,我是python和编码的新手)所以我理解的是我必须删除 .join() 因为它是阻塞的东西,我必须创建一个线程来执行检测代码并在主线程中创建 gui 我做对了吗?

标签: python multithreading opencv user-interface


【解决方案1】:

首先,@Mark 是正确的,您正在从正常的惯例倒退,即 GUI 在主线程中运行。你的代码被阻塞了,因为你正在这样做

threadGUI = GuIthread()
threadGUI.start()
threadGUI.join()  # This blocks until threadGUI is complete.

threadGUI.join() 调用将使您的程序阻塞,直到 app.MainLoop() 完成,这在您关闭 GUI 之前不会发生。

【讨论】:

  • 我试图将每个检测代码放在一个线程中,将 GUI 代码放在另一个线程中,并在主线程中调用视频开始,当 gui 打开时检测停止,然后当我关闭GUI 视频恢复工作
  • @user3673789 你需要在主线程中有GUI代码。
猜你喜欢
  • 1970-01-01
  • 2015-03-05
  • 1970-01-01
  • 2012-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多