I’m making a GUI-focused game.
The game itself is developed somewhat independently of the GUI. My reasoning is that I might want to change the interface technology at a later date. Right now, the game runs in a loop, with each iteration of the loop representing a slice of simulation time. After each loop, the game can expose a new GameState
object representing the world.
Currently, in the main thread, I am creating a QApplication
and creating a QGraphicsScene
which is sent to my main window where it’s used by a QGraphicsView
.
int main(int argc, char *argv[])
{
QApplication::setStyle(QStyleFactory::create("Windows Vista"));
QApplication a(argc, argv);
QTranslator translator;
const QStringList uiLanguages = QLocale::system().uiLanguages();
for (const QString &locale : uiLanguages) {
const QString baseName = "SentientRobotFootballLeague_" + QLocale(locale).name();
if (translator.load(":/i18n/" + baseName)) {
a.installTranslator(&translator);
break;
}
}
QGraphicsScene matchScene;
MainWindow w{&matchScene};
w.show();
std::thread gameThread(game_thread_func, std::ref(matchScene));
return a.exec();
}
My gameThread
then creates and adds items to the QGraphicsScene
parameter. However, occassionally QT crashes. I’m fairly certain this is because I’m adding GUI elements to the scene while the view is trying to read it etc. From what I’ve read, QGraphicsScene
isn’t thread-safe.
So, what’s the correct way to do this? I can’t find a way to employ mutexes/lock guards around when I might need to update the QGraphicsScene
and when the QGraphicsView
might want to read from it. Is there a way I can patch into QTs main event loop and check for changes to my game object to update the scene?
Should I be using a QTimer
to periodically check if the game object is updated and redraw the scene then?
Preferable the scene updates would be happening in a separate thread so the GUI doesn’t get potentially bogged down.
1