销户c语言,c – 如何在注销时优雅地退出QApplication?
我有一個(gè)帶有通知區(qū)域圖標(biāo)的應(yīng)用程序,因此主窗口可能會(huì)忽略關(guān)閉事件.我正在嘗試保存應(yīng)用程序退出的首選項(xiàng)和歷史記錄.我還想在應(yīng)用程序運(yùn)行時(shí)處理注銷.雖然應(yīng)用程序是跨平臺(tái)的,但它在GNU /
Linux中最方便/最有用,因此Windows注銷行為的關(guān)注度要低得多.
這是一個(gè)用于測(cè)試不同桌面環(huán)境/窗口管理器行為的最小可編譯示例:
// 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()
注銷時(shí)大多數(shù)完整的桌面環(huán)境都會(huì)嘗試關(guān)閉可見(jiàn)窗口.但由于測(cè)試應(yīng)用程序在關(guān)閉時(shí)不會(huì)退出,因此注銷將被中斷/取消.如果在窗口不可見(jiàn)時(shí)執(zhí)行注銷,它會(huì)正常退出(就像我想要的那樣).功能較少的桌面環(huán)境/窗口管理器會(huì)忽略仍在運(yùn)行的應(yīng)用程序并退出.他們中的大多數(shù)甚至沒(méi)有警告應(yīng)用程序有關(guān)注銷,因此文件中既沒(méi)有“closeEvent()”,也沒(méi)有“onAboutToQuit()”,也沒(méi)有“M :: ~M()”,程序輸出被重定向.
詳細(xì)結(jié)果(所有非Windows結(jié)果來(lái)自Manjaro GNU / Linux):
>完整的桌面環(huán)境,如果可見(jiàn)窗口拒絕退出,則取消注銷,優(yōu)雅地完成隱形應(yīng)用程序:
closeEvent()
onAboutToQuit()
M::~M()
{ KDE, XFCE, Mate, GNOME, Cinnamon }
所有其他人都不取消退出,但其中一些人試圖警告應(yīng)用程序.
>我不知道為什么onAboutToQuit()出現(xiàn)在日志中,但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 }
對(duì)于(GCC 4.9.1或Clang 3.4.2)AND(Qt 4.8.6 OR Qt 5.3.1)的任何組合,行為完全相同.然而,當(dāng)我在Xubuntu上嘗試Qt 4.8和Qt 5.2時(shí),結(jié)果有些不同:XFCE中的Qt 5.2沒(méi)有阻塞 – 無(wú)論主窗口可見(jiàn)性如何,應(yīng)用程序都能正常完成.但Qt 4.8存在阻塞(與Manjaro相同).
我知道可以正確處理注銷(沒(méi)有阻塞),因?yàn)橛袔讉€(gè)應(yīng)用程序可以做到這一點(diǎn).所有這些都有通知區(qū)域圖標(biāo),關(guān)閉通知區(qū)域,但不阻止注銷.
>基于Qt:GoldenDict,Transmission-Qt,Kopete;
>以GTK為基礎(chǔ):Audacious,Pidgin.
我檢查了基于Qt的源代碼,發(fā)現(xiàn)處理closeEvent沒(méi)什么特別之處:
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 );
}
}
所以問(wèn)題:
>即使主窗口可見(jiàn),如何確保我的應(yīng)用程序不會(huì)阻止注銷?
>如何確保在盡可能多的桌面環(huán)境/窗口管理器中注銷時(shí)調(diào)用onAboutToQuit()和~M()?
我懷疑應(yīng)該收聽(tīng)一些系統(tǒng)信號(hào),但我不知道究竟是哪一個(gè)……
總結(jié)
以上是生活随笔為你收集整理的销户c语言,c – 如何在注销时优雅地退出QApplication?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 安装python37路径报错_解决pyc
- 下一篇: mongoose如何发送html页面,M