Qt - 检测QWindow何时关闭

时间:2014-02-08 06:42:49

标签: c++ qt game-engine

我正在用Qt制作游戏,我正在制作一个自定义游戏循环,所以我可以精确控制逻辑时间步长并以最大帧速率渲染。

通常,要创建QWindow,您可以执行此操作:

...
QGuiApplication app(argc,argv);
QWindow* window = new QWindow();
window.show();
app.exec();
...

当窗口关闭时,exec()会返回。

但是,我是按照以下方式进行的:

QGuiApplication *app = new QGuiApplication(argc,argv);
     QWindow* window = new QWindow();
     window.show();
     while (!terminate_loop) {
          app->processEvents();
          GameUpdate();
          GameRender();
     }
     app->exit();

但是,当窗口关闭时,我的循环继续运行。我需要检测窗口何时关闭,以便我的循环可以终止。我尝试了以下内容为了捕获窗口关闭的时间:

connect(app,SIGNAL(lastWindowClosed()),this,SLOT(windowClosed()));

当窗口关闭时,应该触发后面的插槽,但它永远不会被触发。当我使用app->exec()而不是手动处理事件时, 会触发。

void QTEngine::windowClosed() {
    terminate_loop = true;
}

经过进一步调查,Qt文档说明如下:

  

[lastWindowClosed]是在最后一个可见主数据库时从exec()发出的   窗口(即没有父窗口的窗口)关闭。

由于我没有使用exec(),因此不会发出此信号。还有其他方法可以检测QWindow何时关闭?

2 个答案:

答案 0 :(得分:4)

您应该使用Qt内部事件循环来设计您的游戏应用程序。 Qt提供的"OpenGL Window" example显示了渲染循环的一个很好的例子。

但是,有可能在QWindow上获得关闭事件。从版本5.4.1开始,未提供方便的closeEvent()函数。但是,您可以在QWindow上安装事件过滤器对象并获取close事件。以下是此类事件过滤器对象实现的示例:

class CloseEventFilter : public QObject
{
     Q_OBJECT
public:
     CloseEventFilter(QObject *parent) : QObject(parent) {}

protected: 
     bool eventFilter(QObject *obj, QEvent *event)
     {
          if (event->type() == QEvent::Close)
          { 
               // Do something interesting, emit a signal for instance.
          }

          return QObject::eventFilter(obj, event);
     }

};

要将事件过滤器附加到窗口,只需使用任何QObject子类(包括QWindow)实现的installEventFilter()函数。

QGuiApplication *app = new QGuiApplication(argc,argv);
QWindow* window = new QWindow();
CloseEventFilter *closeFilter = new CloseEventFilter(window);
window->installEventFilter(closeFilter);
...

答案 1 :(得分:-1)

我能想到两个可能的解决方案。我没有测试过任何一种解决方案。

1)您可以使用QWindow标记创建Qt::WA_DeleteOnClose。这样做是在窗口关闭时删除对象。删除的任何QObject都会发出destroyed()信号,这意味着您应该能够将destroyed()信号连接到您的广告位。

2)您还可以重新实现QWidget::closeEvent()的{​​{1}}处理程序,并发出自己的自定义信号。