❝开发中遇到了关闭窗口右上角"X"号居然不能正常退出程序,而是隐藏了窗口。究竟是什么回事呢? ❞
问题重现
执行下列代码后点击右上角"X"号居然退出不了程序,而是隐藏了窗口。原以为会恢复正常退出程序的功能,其实不然。
代码语言:javascript复制#include <QApplication>
#include <QWidget>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget w;
/* 切换到无标题栏模式 */
w.setWindowFlag(Qt::ToolTip, true);
// ...一些操作
/* 恢复到有标题栏模式 */
w.setWindowFlag(Qt::ToolTip, false);
w.show();
return a.exec();
}
而正常操作下,下列代码点击右上角"X"号可以正常关闭窗口。
代码语言:javascript复制int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget w;
w.show();
return a.exec();
}
问题分析
通过查看setWindowFlags的源码发现了这个函数adjustQuitOnCloseAttribute
,似乎是可以改变了关闭按钮的状态,我们再进入函数一探究竟。
void QWidgetPrivate::setWindowFlags(Qt::WindowFlags flags)
{
Q_Q(QWidget);
...
if ((q->data->window_flags | flags) & Qt::Window) {
...
// 为了向后兼容,我们只在重新创建窗口时才更改Qt::WA_QuitOnClose属性值。
adjustQuitOnCloseAttribute();
}
...
}
adjustQuitOnCloseAttribute
函数如下:
void QWidgetPrivate::adjustQuitOnCloseAttribute()
{
Q_Q(QWidget);
if (!q->parentWidget()) {
Qt::WindowType type = q->windowType();
if (type == Qt::Widget || type == Qt::SubWindow)
type = Qt::Window;
if (type != Qt::Widget && type != Qt::Window && type != Qt::Dialog)
q->setAttribute(Qt::WA_QuitOnClose, false);
}
}
可以看到,「当窗口类型不是Widget,Window,Dialog时则会设置关闭按钮不处理退出程序的操作。」
代码语言:javascript复制if (type != Qt::Widget && type != Qt::Window && type != Qt::Dialog)
q->setAttribute(Qt::WA_QuitOnClose, false);
问题解决
设置setAttribute(Qt::WA_QuitOnClose, true)
让其恢复关闭按钮退出的作用。
#include <QApplication>
#include <QWidget>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget w;
/* 切换到无标题栏模式 */
w.setWindowFlag(Qt::ToolTip, true);
// ...一些操作
/* 恢复到有标题栏模式 */
w.setWindowFlag(Qt::ToolTip, false);
/* 恢复关闭按钮的作用 */
w.setAttribute(Qt::WA_QuitOnClose, true);
w.show();
return a.exec();
}