【问题标题】:Program Doesn't Terminate Correctly程序未正确终止
【发布时间】:2011-05-04 17:54:11
【问题描述】:

我正在编写一个计算机视觉应用程序(C++ 和 OpenCV)。我正在使用 wxWidgets 为它创建一个 GUI——这很简单;按钮按下事件调用跟踪器应用程序开始。

我终止应用程序的调用(即单击关闭按钮)如下:

// Exiting the App
void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
    // true is to force the frame to close
    Close(true);
}

这通常适用于更简单的 GUI 应用程序。然而,这一次,框架消失了,在任务管理器中,进程似乎继续运行并持有内存。这很烦人,因为如果我运行或调试应用程序,然后进行一些更改并尝试再次运行,而不事先手动终止进程,编译器会抛出链接错误,因为 .exe 是

最后一个增量链接未找到或未构建。

尝试插入蛮力退出(1);在 onQuit 方法中,但它会导致应用程序崩溃。

我不确定它是什么.. 在没有 GUI 的情况下运行时,应用程序运行并终止正常(尽管它的调用方式略有不同 - 从 main() 函数而不是从调用的按钮按下事件处理程序一个抽象基类)。

有没有可能是因为一个类被声明为全局范围?如在一个文件中,我有一个在任何类方法之外声明的类的实例?也许 wxWidgets 不能处理这个?

澄清一下:

我要关闭的框架是顶级框架。当它不调用计算机视觉方法时,我对完全相同的 GUI 代码没有任何问题。

我没有专门编写任何多线程代码,但首先,我收到一条错误消息,上面写着“错误:无法初始化 OLE”。为了解决这个问题,我必须将 wxUSE_DRAG_AND_DROP、wxUSE_CLIPBOARD、wxUSE_OLE 和 wxUSE_OLE_AUTOMATION 设置为 0(而不是 1),然后(重新)编译 wxWidgets。

只是想知道,HighGUI 中是否存在某种与 WxWidgets 不一致的线程?有没有其他人遇到过类似的问题?

【问题讨论】:

  • 听起来你有多个线程,调用Close() 不会杀死所有线程。
  • 如果您没有挂钩到窗口生成的按钮按下事件,是什么让您认为按下按钮时会发生什么?设置断点并调试或显示更多相关代码。

标签: c++ wxwidgets


【解决方案1】:
::wxExit

void wxExit()

调用 wxApp::OnExit 后退出应用程序。只应在紧急情况下使用:通常应删除顶层框架(在删除所有其他框架之后)以终止应用程序。请参阅 wxCloseEvent 和 wxApp。

包含文件

<wx/app.h>

您也可以简单地调用 crt 函数 exit(),它会立即关闭所有内容。

但是,如果您想比这些相当粗暴的方法更有礼貌(如果您在 wxApp::OnExit 中放置了一些特殊的关闭代码,您可能特别想要这样做 ) 然后你想找到顶层窗口并关闭它。从代码中的任何位置执行此操作

wxGetApp().GetTopWindow()->Close()

【讨论】:

  • 是的,将它放在 OnExit() 方法中,但它不起作用。还尝试了 wxGetApp()->GetTopWindow()->Close() 但这是无效的语法,我很确定无论如何我都会关闭我的顶级窗口。
  • 如果您需要帮助,您需要更加小心地遵循人们的建议。尝试调用 ::wxExit() 并调用 exit()。对于 wxGetApp,您是否使用 DECLARE_APP
  • 感谢您的帮助,非常感谢。抱歉,我以前从未见过没有前一课的 '::' ......好吧,我试过 ::wxExit();退出(1);但没有快乐。此外,正确的调用似乎是 wxGetApp().GetTopWindow()->Close();但这并没有解决问题。我很确定我已经关闭了顶级框架。
  • :: 没有前面的类意味着该方法在全局命名空间中。我很难相信调用 exit() 不会关闭您的应用程序。你确定调用正在执行吗?
  • 你是对的,wxGetApp() 返回应用对象的引用。我已经编辑了我的答案。
【解决方案2】:

感谢大家的帮助,我已经解决了这个问题。现在看起来很明显,但当时想不通!

最初,我的计算机视觉应用是从主函数调用的。但是,有了新的 GUI 代码,就不需要 main,所以我用 shell 类替换了原来的 main。

虽然我已经小心地在我的计算机视觉类的方法中释放分配的内存,但我并没有对原始的 main 函数如此小心,因为一旦该函数结束,以前使用的所有内存都会被程序的常规清除退出。

与新 GUI 代码的不同之处在于,当 shell 类完成时 - 程序仍在运行。线索在于,即使计算机视觉应用程序结束,我的网络摄像头上的蓝光仍然亮着。

* 一定要调用 cvReleaseCapture( &capture );释放该线程并释放硬件 *

【讨论】:

    【解决方案3】:

    您对Close 的调用只会关闭框架,但不会停止应用程序,因为它不是最后一个顶级窗口。 wxWidget 包含一个主题Window Deletion Overview。它指出

    当最后一个顶级窗口(wxFrame 或 wxDialog)被销毁时,wxWidgets 应用程序会自动退出。将任何应用程序范围的清理代码放入 wxApp::OnExit(这是一个虚函数,而不是事件处理程序)。

    您的框架是顶级框架吗?如果没有,您可能必须在顶级框架上调用CloseDestroy

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-10-08
      • 1970-01-01
      • 2015-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多