所以必须有一种方法可以给继承的 QGLWidget 一个指向视图对象的指针,并且无论何时应该绘制视图
如果您demo_app::display()从 inside调用QGLWidget::paintGL,它将起作用并将场景绘制到QGLWidget上下文中。但是,这将使用QGLWidget' 上下文,因此您需要将所有初始化函数移动到QGLWidget. 我不记得 OpenGL 对象是否可以跨上下文共享,但如果不能做到这一点也不会感到惊讶。
但是当视图不知道它时,我怎么能告诉小部件更新()。
好吧,添加指向QWidget视图的指针并调用QWidget->update(). 应该很明显。
如果您想从基于 GLUT 的窗口中绘制 qt 小部件...
即,如果您想将 Qt 小部件“嵌入”到 GLUT 窗口中。
每个 Qt 小部件都有render方法。您可以使用此方法将小部件绘制到 anyQPaintDevice或使用 any QPainter。
因此,要从框架内绘制小部件,您必须向小部件提供其中之一并手动调用渲染。
您还必须从框架中转发鼠标和键盘事件并将它们转换为 Qt 事件。
这应该是可行的,但实施起来会很痛苦。
另请参阅EmbeddedDialogs演示和QGraphicsProxyWidget。
如果您只是想在 glut 窗口之外使用 GUI 小部件,而不是将它们嵌入到 glut 窗口中......
将与您的框架和 glut 消息相关的所有内容包装到QObject中,并将 glut 消息处理放入该对象的插槽中。将此插槽连接到超时运行的计时器0。
我的代码示例(使用 SDL):
class Game: public QObject{
Q_OBJECT
protected:
void processSdlEvents();
...
protected slots:
void onGameEnd();
void timerSlot();
...
};
Game::Game(/*arguments*/ ...){
...
gameTimer = new QTimer(this);
gameTimer->setSingleShot(false);
gameTimer->setInterval(0);
connect(gameTimer, SIGNAL(timeout()), this, SLOT(timerSlot()));
...
}
void Game::timerSlot(){
processSdlEvents();
update();
render();
}
void Game::processSdlEvents(){
SDL_Event event;
QList<GameEventHandler*> eventHandlers = findChildren<GameEventHandler*>();
/*WARNING: This is NOT an infinite loop. */
while (SDL_PollEvent(&event) != 0){
if (event.type == SDL_QUIT){
emit gameEnded();
continue;
}
bool processed = false;
for (int i = 0; i < eventHandlers.size(); i++){
if (eventHandlers[i]->processEvent(&event)){
processed = true;
break;
}
}
if (processed)
continue;
for (int i = 0; i < joysticks.size(); i++){
if (joysticks[i]->processEvent(&event)){
processed = true;
break;
}
}
/*if (processed)
continue;*/
}
}
int main(int argc, char** argv){
QApplication app(argc, argv);
int result = 0;
try{
Game game;
QObject::connect(&game, SIGNAL(gameEnded()), &app, SLOT(quit()));
game.start();
result = app.exec();
}
catch(const QString& s){
reportException(s);
}
catch(std::exception& e){
reportException(e);
}
catch(...){
reportException();
}
return result;
}
请注意 processSdlEvents 不是无限循环。它偶尔会被调用一次,并处理自上次调用以来收到的所有事件,然后终止。
在这种情况下,您的框架特定函数是从 Qt 主循环中调用的。
您也可以采取其他方式,并在您自己的框架中从主循环调用 Qt 特定函数(使用QEventLoopclass 或QApplication::processEvents()),但它可能不太可靠,我自己没有尝试过。