2013-02-21 148 views
1

我正在使用Qt开发xmgrace(一个2D绘图库)的自定义控件接口。 我在我的项目3个部分组成:QProcess:当进程仍在运行时销毁

  1. Qt中
  2. 甲的QThread制成的GUI它运行由C在后台线程中一些共享对象的代码。
  3. 一个xmgrace窗口使用管道连接到上面的两个。 (使用grace_np库)

(1) --> (2)的通信是通过更改共享对象代码中声明的某些全局变量的状态来完成的。

来自(1) --> (3)的通信& (2) --> (3)正在使用由grace_np库提供的内置函数。

现在,来自(2) --> (1)的通信是导致问题的原因。我尝试了两种我能想到的方式: a)在Qt代码中声明共享对象,它发出Qt信号并在C代码中调用。 b)从线程返回并使用返回值执行一些操作,然后重新启动线程。

这两种方法都给出了不可靠的结果。我的GUI卡/引起分段错误,我得到的消息:

QProcess: Destroyed while process is still running

我不会在我的代码使用QProcess中类的任意位置。所以这已经成为一个谜。 请提供一些有关这可能的原因的信息。

PS:管道到(3)是一种方式,只需要这种方式。

编辑1:

仅供参考我使用Qt 4.2,所以我不能用QObject的方法,然后使用movetothread() 对不起不把代码,我不能由于公司的政策,也因为我不知道该放什么(它太大)。共享的c代码是400k +行

我相信我发现了我的问题的罪魁祸首。看来使用QMessageBox类导致了这个问题。我最初使用QMessageBox的静态函数。现在我已经尝试通过堆栈和堆声明它,但问题仍然存在。 但我发现,从我的代码中删除所有对QMessageBox的调用解决了这个问题。 但现在的问题是,如何显示消息? 我只是在这里进行推测,但是QMessageBox的模态性质是否可能会阻塞我的程序和xmgrace之间存在的管道,并随后导致它退出?然后创建一个自定义的QMessageBox(非模态)可能会解决这个问题。

编辑2:

我不是从工作线程调用QMessageBox提示。再加上我使用工作线程的方式,它永远不会返回,除非我关闭程序。为了让一个想法我的QThread ::运行函数的形式为:

QThread_Object::run() 
{ 
    c_init(); 
    c_main(); 
} 

其中c_init & c_run从共享的C代码链接功能。所以直接从这些内部调用QMessageBox是不可能的。 现在我打算废除QMessageBox并改为使用QMainWindow状态栏。但是它并没有提供完整的功能。我想这可能是一个错误使用Qt 4.2

编辑3:

我从(2) --> (1)刚才提到通信是什么造成的问题。现在我已经完全消除了这种通信,并且更准确地发现问题是由启动辅助线程后随时调用QMessageBox引起的。早些时候上面提到的通信导致Qt间接发出一个信号并调用一个我认为是罪魁祸首的QMessageBox。

编辑4:

好吧,我忘了提,因为周围之初这个问题的最大谜团。我基本上工作(地点A)通过ssh在工作站(地方B)上我编码和运行这个程序。 B在2个物理网络上连接。 A通过网络1连接到B.现在这个问题有从来没有从我的终端在A(即通过网络1在ssh上)工作时发生。但是,当我直接访问B或通过网络2上的ssh访问B时,它始终如一。请注意,每次仅在B上执行代码。这两个网络都被掠夺者使用。

编辑5

最后,我已经子类QDialog的,使一个自定义的MessageBox,因为我真的不要求QMessageBox提示的扩展功能解决了我的问题。我仍然不知道QMessageBox内导致问题的原因。我想Qt中的一些bug始终是个谜。

+2

没有代码?饼干怎么样? – 2013-02-21 08:56:21

+1

如果我们不知道你是否在做1,2和3,那么我们不能回答。“我没有给QProcess打电话,但它让我的程序崩溃”并没有给我们太大的帮助。 – Phlucious 2013-02-21 17:28:23

回答

1

由于没有代码,我在黑暗中拍摄了一小段代码,但它听起来像是您的QProcess是有意或无意地在堆栈上创建的,或者您的QThread过早被破坏。我将钱投入到您的QThread对象被错误地启动。自从文档(或直到最近)一直困扰以来,很难责怪你。考虑阅读this threadthis thread并且根本不需要子类QThread。

编辑: 如果QMessageBox是你的罪魁祸首,那么我猜你是从子线程显示它。从documentation

GUI应用程序中,主线程也被称为GUI线程 ,因为它是被允许执行GUI相关 操作的唯一线索。

有几种方法可以显示来自子线程的消息。就我个人而言,我使用qt的错误报告方案并将qCritical,qDebug等重定向到stderr。另一个更简单的方法就是让你的工作线程的QString信号被你的GUI线程捕获,然后显示/收集错误。我喜欢让我的MainWindow收集错误,然后在工作线程完成时一次显示它们。

编辑2: 由于这个问题似乎是QMessageBox是模态(即,挡住你的主线程同时工作线程向前移动),您可以轻松地在其非模态方式使用QMessageBox提示解决这个问题。只需将0作为QMessageBox构造函数/静态函数中的父窗口小部件即可。处理过程将继续进行,无需等待用户退出窗口 - 这也可能导致多个消息框同时打开。如果这有助于避免错误,请仔细检查代码以确保关闭后窗口已正确销毁。

+0

感谢您关注此问题,但不幸的是,我无法尝试其他方法,因为我使用的是Qt4.2,其中子类别QThread是唯一的选项。我很抱歉没有放置代码,因为我不能公司的政策,也因为我不知道该放什么。 – theta 2013-02-25 09:53:08

+0

我用编辑审查了你的问题。请参阅我上面的编辑。 – Phlucious 2013-02-25 17:24:51

+0

不幸的是,我认为这不是直接的问题,但它可能与Qt内的这个概念有某种关系,因为我一直面临着这个问题的行为。 – theta 2013-02-26 04:16:11

相关问题