QWidget closeEvent(...) 没有被 QProcess::terminate() 调用

Posted

技术标签:

【中文标题】QWidget closeEvent(...) 没有被 QProcess::terminate() 调用【英文标题】:QWidget closeEvent(...) Not Being Called with QProcess::terminate() 【发布时间】:2018-09-20 20:31:15 【问题描述】:

我有一个作为 Windows 系统托盘应用程序运行的 Qt 应用程序 (A)。

我还有另一个 Qt 应用程序 (B) 可以启动/关闭任何可执行文件。

如果我尝试使用其系统托盘上下文菜单关闭应用程序 (A),一切都会按预期工作(进程被终止,系统托盘图标消失)。

但是,如果我尝试通过应用程序 (B) 关闭应用程序 (A),应用程序 (A) 的系统托盘图标会消失,但其进程仍在后台运行。我必须强制终止进程才能让它退出。

应用程序 (B) 使用 QProcess 来启动可执行文件。当请求时,它调用 QProcess::terminate() 来关闭启动的应用程序。

关闭实际具有窗口(窗体)的应用程序没有问题。只有这一个无窗口系统托盘应用程序 (A) 有问题。

我已经覆盖了永远不会触发/调用的 QWidget::closeEvent(...)。

如何在应用程序 (A) 中触发 closeEvent(...)?

Qt 文档暗示 closeEvent 是由窗口关闭请求触发的,这可能是问题,因为应用程序 (A) 没有窗口。我需要给应用程序(A)一个表格并隐藏它吗?

【问题讨论】:

提供minimal reproducible example 嗨@tranqui341,我们可能需要更多信息才能提供帮助。请注意,您在 Windows 系统托盘中看到的是一个窗口,并为其分配了一个句柄(您甚至可以使用 Spy++ 深入了解它的属性和消息)。此外,当您的应用程序 B 调用 terminate() 时,如果您的应用程序 A 没有使用带有 exec() 的 QApplication 循环,它将不会关闭进程,只会关闭进程的所有***窗口。请分享更多信息,以便我们提供帮助。 【参考方案1】:

原来需要一个表单来接收 closeEvent。

当 Qt 从窗口系统接收到一个***窗口小部件的窗口关闭请求时,使用给定事件调用[closeEvent]。

我向应用程序 (A) 添加了一个表单并将其隐藏。

setStyleSheet( "background: transparent;" );
setAttribute( Qt::WA_TranslucentBackground );

现在,当应用程序 (B) 发送 QProcess::terminate() 时,将触发 closeEvent 并且一切都按预期关闭!

嗯,几乎……我没想到的一件事是,即使隐藏了窗口,它仍然有一个任务栏按钮。为了删除它,我在构造函数中添加了以下内容:

setWindowFlags( Qt::SubWindow ); 
show();

Qt Hide Taskbar Item

【讨论】:

以上是关于QWidget closeEvent(...) 没有被 QProcess::terminate() 调用的主要内容,如果未能解决你的问题,请参考以下文章

PtQt5 closeEvent 关闭事件,退出提示框

单击关闭按钮后取消关闭 QWidget

如何要求密码关闭窗口?

accept()函数用来告诉Qt,事件处理函数“接收”了这个事件,不要再传递;ignore()函数则告诉Qt,事件处理函数“忽略”了这个事件,需要继续传递(看一下QWidget::mousePress

如何要求密码才能关闭窗口?

pyqt tips