我正在使用 Qt 为 2D 绘图库 xmgrace 开发自定义控制界面。我的项目中有 3 个组件:
- 用 Qt 制作的 GUI
- 一个 QThread,它在后台线程中从 C 运行一些共享对象代码。
- 使用管道连接到上述两者的 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::run 函数的形式是:
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:
好吧,我忘了提到从一开始就围绕这个问题的最大谜团。我基本上通过 ssh 在工作站(位置 B)上工作(位置 A),我在该工作站上编写代码并运行该程序。B 连接在 2 个物理网络上。A 通过网络 1 连接到 B。现在,从我在 A 的终端(即通过网络 1 在 ssh 上)工作时,这个问题从未发生过。但是当我直接访问 B 或通过网络 2 通过 ssh 访问 B 时,它始终会发生。请注意,每次代码仅在 B 上执行。这两个网络都被数百人使用。
编辑 5
最后,我通过子类化 QDialog 并制作自定义 MessageBox 解决了我的问题,因为我真的不需要 QMessageBox 的扩展功能。我仍然不知道 QMessageBox 中究竟是什么导致了这个问题。我想 Qt 中的一些错误将永远是一个谜。