我正在用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何时关闭?
答案 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}}处理程序,并发出自己的自定义信号。