我有一个带有通知区域图标的应用程序,因此主窗口可能会忽略关闭事件.我正在尝试保存应用程序退出的首选项和历史记录.我还想在应用程序运行时处理注销.虽然应用程序是跨平台的,但它在GNU /

Linux中最方便/最有用,因此Windows注销行为的关注度要低得多.

这是一个用于测试不同桌面环境/窗口管理器行为的最小可编译示例:

// main.cpp

# include

# include

# include

# include

# include

class M : public QMainWindow

{

Q_OBJECT

public:

~M();

public slots:

void onAboutToQuit();

private:

void closeEvent(QCloseEvent *);

};

M::~M()

{

std::cout << "M::~M()" << std::endl;

}

void M::onAboutToQuit()

{

std::cout << "onAboutToQuit()" << std::endl;

}

void M::closeEvent(QCloseEvent * e)

{

std::cout << "closeEvent()" << std::endl;

hide();

QTimer::singleShot(5000, this, SLOT(show()));

e->ignore();

}

int main(int argc, char * argv[])

{

QApplication app(argc, argv);

M m;

m.setWindowModality(Qt::NonModal);

m.connect(& app, SIGNAL(aboutToQuit()),

SLOT(onAboutToQuit()));

m.show();

return app.exec();

}

# include "main.moc"

// CMakeLists.txt

cmake_minimum_required(VERSION 2.6)

project(closeeventbug)

option(QT5 "Use Qt5" OFF)

if(QT5)

find_package(Qt5Core REQUIRED)

find_package(Qt5Widgets REQUIRED)

else()

find_package(Qt4 REQUIRED)

include_directories(${QT_INCLUDES})

endif()

include_directories(${CMAKE_CURRENT_BINARY_DIR})

set(CMAKE_AUTOMOC ON)

add_executable(closeeventbug main.cpp)

if(QT5)

qt5_use_modules(closeeventbug Core Widgets)

else()

target_link_libraries(closeeventbug ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY})

endif()

注销时大多数完整的桌面环境都会尝试关闭可见窗口.但由于测试应用程序在关闭时不会退出,因此注销将被中断/取消.如果在窗口不可见时执行注销,它会正常退出(就像我想要的那样).功能较少的桌面环境/窗口管理器会忽略仍在运行的应用程序并退出.他们中的大多数甚至没有警告应用程序有关注销,因此文件中既没有“closeEvent()”,也没有“onAboutToQuit()”,也没有“M :: ~M()”,程序输出被重定向.

详细结果(所有非Windows结果来自Manjaro GNU / Linux):

>完整的桌面环境,如果可见窗口拒绝退出,则取消注销,优雅地完成隐形应用程序:

closeEvent()

onAboutToQuit()

M::~M()

{ KDE, XFCE, Mate, GNOME, Cinnamon }

所有其他人都不取消退出,但其中一些人试图警告应用程序.

>我不知道为什么onAboutToQuit()出现在日志中,但M :: ~M()不是这种情况……

closeEvent()

onAboutToQuit()

{ Windows7 }

3.

closeEvent()

{ icewm, E17 }

4.

{ RazorQt, LxDE, LxQt, i3, budgie, fluxbox, awesome, openbox,

wmii, E16, pekWM, uwm, fvwm, xmonad, spectrwm, windowmaker,

herbstluftwm, WindowsXP }

对于(GCC 4.9.1或Clang 3.4.2)AND(Qt 4.8.6 OR Qt 5.3.1)的任何组合,行为完全相同.然而,当我在Xubuntu上尝试Qt 4.8和Qt 5.2时,结果有些不同:XFCE中的Qt 5.2没有阻塞 – 无论主窗口可见性如何,应用程序都能正常完成.但Qt 4.8存在阻塞(与Manjaro相同).

我知道可以正确处理注销(没有阻塞),因为有几个应用程序可以做到这一点.所有这些都有通知区域图标,关闭通知区域,但不阻止注销.

>基于Qt:GoldenDict,Transmission-Qt,Kopete;

>以GTK为基础:Audacious,Pidgin.

我检查了基于Qt的源代码,发现处理closeEvent没什么特别之处:

https://github.com/goldendict/goldendict/blob/master/mainwindow.cc

void MainWindow::closeEvent( QCloseEvent * ev )

{

if ( cfg.preferences.enableTrayIcon && cfg.preferences.closeToTray )

{

ev->ignore();

hide();

}

else

{

ev->accept();

qApp->quit();

}

}

https://github.com/bfleischer/transmission/blob/master/qt/mainwin.cc

void

TrMainWindow :: closeEvent( QCloseEvent * event )

{

// if they're using a tray icon, close to the tray

// instead of exiting

if( !myPrefs.getBool( Prefs :: SHOW_TRAY_ICON ) )

event->accept( );

else {

toggleWindows( false );

event->ignore( );

}

}

void

TrMainWindow :: toggleWindows( bool doShow )

{

if( !doShow )

{

hide( );

}

else

{

if ( !isVisible( ) ) show( );

if ( isMinimized( ) ) showNormal( );

//activateWindow( );

raise( );

QApplication::setActiveWindow( this );

}

}

git clone git://anongit.kde.org/kopete

void KopeteWindow::closeEvent ( QCloseEvent *e )

{

// if we are not ok to exit on close and we are not shutting down then just do what needs to be done if a

// window is closed.

KopeteApplication *app = static_cast ( kapp );

if ( !shouldExitOnClose() && !app->isShuttingDown() && !app->sessionSaving() ) {

// BEGIN of code borrowed from KMainWindow::closeEvent

// Save settings if auto-save is enabled, and settings have changed

if ( settingsDirty() && autoSaveSettings() )

saveAutoSaveSettings();

if ( queryClose() ) {

e->accept();

}

// END of code borrowed from KMainWindow::closeEvent

kDebug ( 14000 ) << "just closing because we have a system tray icon";

}

else

{

kDebug ( 14000 ) << "delegating to KXmlGuiWindow::closeEvent()";

KXmlGuiWindow::closeEvent ( e );

}

}

所以问题:

>即使主窗口可见,如何确保我的应用程序不会阻止注销?

>如何确保在尽可能多的桌面环境/窗口管理器中注销时调用onAboutToQuit()和~M()?

我怀疑应该收听一些系统信号,但我不知道究竟是哪一个……

销户c语言,c – 如何在注销时优雅地退出QApplication?相关推荐

  1. 让电脑注销的c语言程序,C语言实现系统关机注销功能

    C语言实现系统关机注销功能 发布时间:2020-09-21 14:07:22 来源:脚本之家 阅读:71 作者:zyh_helen 本文实例为大家分享了C语言实现系统关机注销的具体代码,供大家参考,具 ...

  2. 在c语言中引用数组元素时,其数组下标的数据类型允许是什么

    在c语言中引用数组元素时,其数组下标的数据类型允许是:整型常量或整型表达式.C语言规定只能逐个引用数组元素而不能一次引用整个数组,数据元素的表示形式为"数组名[下标]",下标可以是 ...

  3. 51单片机c语言电子钟(已加入调时 '整点报时功能1),51单片机c语言电子钟(已加入调时、闹铃、整点报时功能1)万年历2...

    51单片机c语言电子钟(已加入调时.闹铃.整点报时功能1)万年历2 51单片机c语言电子钟(已加入调时.闹铃.整点报时功能1)万年历1 ·一个固定数组 ·时钟,秒表,日历,闹钟 */ #include ...

  4. c++语言中如果调用函数时,需要改变实参或者返回多个值,应该采取,C++综合练习题2...

    C++程序设计综合练习题(二) 一.单项选择题 1. 静态成员函数没有() A. 返回值 B. this指针 C. 指针参数 D. 返回类型 2. 假定AB为一个类,则执行"AB a(2), ...

  5. Python语言的动态性:运行时动态绑定,删除属性和方法

           Python是动态语言,动态语言是一类在运行时可以改变其结构的语言:例如新的函数.对象.甚至代码可以被引进,已有的函数可以被删除或是其他结构上的变化.通俗点说就是在运行时代码可以根据某些 ...

  6. linux启动时、登录时或注销时执行脚本

    init.d开机启动 在启动时执行 Linux 脚本 有两种传统的方法可以实现在启动时执行命令或脚本: 方法 #1 - 使用 cron 任务 除了常用格式(分 / 时 / 日 / 月 / 周)外,cr ...

  7. C语言技巧:有if时使用likely和unlikely让代码运行更快

    在单片机/嵌入式编程中,对速度要求比较高,likely和unlikely就是一个比较好的技巧,适用于有if-else分支,且知道哪个发生概率大的情况​. 参考文章:C语言技巧:有if时使用likely ...

  8. C语言规定 定义符号常量时必须用大写字母,C语言规定,定义符号常量时必须用大写字母()...

    C语言规定,定义符号常量时必须用大写字母() 采用实地盘存制时,语言规财产物资的期末结存数就是( ). 定定义大写I'llaskMr.Smithtoringyouup_________hecomesb ...

  9. 西门子HMI触摸屏如何组态当用户注销或自动注销时自动跳转到指定画面?

    西门子HMI触摸屏如何组态当用户注销或自动注销时自动切换到指定画面? 实现该功能的思路: 建立一个计划任务,触发器 - 用户更改,事件 激活屏幕-某某画面 举例说明: 新建一个项目,添加一块触摸屏,添 ...

最新文章

  1. Python赋值运算符(入门必读)
  2. 中科院微生物所高程组招聘助研3名(正式编制)
  3. web服务器与网页表单通信,前端与后端通信的几种方式
  4. html弹窗确认取消公告代码,js 弹出确认与取消对话框的四种方法
  5. gradle学习(1)hello world
  6. java jms clust,Geoserver 的 JMS Cluster modules(集群数据同步)
  7. iOS 修改UITabBar的默认点击行为
  8. simplexml和xpath
  9. 有赞大数据平台安全建设实践
  10. oracle ojvm generic,Oracle OJVM安全补丁
  11. iis php.exe,在IIS75下使用php运行exe程序的总结
  12. debian9 设置
  13. 一句话搞懂JavaSE、JavaEE和JavaME之间的区别
  14. mikumikudance 5.X for Android,AR MMD(拡張現実×MikuMikuDance)
  15. 【2G模组Air202开发】使用LuatTools下载Luat底层Lod及编写第一个程序:流水灯
  16. 你需要TrustedInstaller提供的权限才能对此文件进行更改
  17. 我不要我觉得,我要你觉得--如何根据企业研发的现状实施DevOps
  18. 新中产人群生活态度及网络理财安全行为研究报告
  19. html网页屏保,屏幕保护是什么
  20. R 编程中的 LOOCV(留一法交叉验证)

热门文章

  1. 自定义设置一个屏保程序
  2. Unsigned 陷阱
  3. C语言小项目(画机器猫)
  4. python记忆式键入_Python基础
  5. php获取页面中的指定内容,php 获取页面中指定内容的实现类
  6. 经典兔子问题python视频_Python练习题 007:兔子生兔子
  7. java 且_JAVA中逻辑运算符“|”和“”与“||”和“”的用法
  8. python中deepcopy函数_Python学习笔记函数之copy()和deepcopy()
  9. python求圆柱体的体积_漫谈超球体的体积公式
  10. 浮点加法器计算机组成原理,计算机组成原理 第二章运算方法与运算器