The one thing that threw me off was the fact that it was working perfectly for the "play" variable, unlike the sliders...
I think you somehow got lucky with this:

Qt Code:
  1. connect(_timer, &QTimer::timeout, scene, [this, &play, scene, repRule, underRule, overRule]()
  2. {
  3. if (play) {
  4. step(mat, repRule, underRule, overRule);
  5. updateScene(mat, scene);
  6. }
  7. }
  8. );
To copy to clipboard, switch view to plain text mode 

(Which makes absolutely no sense, because you have made "scene" the target of the connect() statement instead of "this". You have effectively invented a new slot for QGraphicsScene that doesn't exist in reality).

You have captured the address of "play" in the lambda, and even though it has gone out of scope, the lambda expression is still able to read and write to it. I think you got lucky that your program didn't crash, but it is probably because all the memory used by the program gets allocated in the MainWindow constructor and the address used by this variable didn't get reused for something else once the constructor had exited. If you had used "play" instead of "&play" it would not work.