Results 1 to 6 of 6

Thread: Changing a variable out of scope of lambda expression

  1. #1
    Join Date
    Jul 2021
    Posts
    5
    Qt products
    Qt4
    Platforms
    Windows

    Default Changing a variable out of scope of lambda expression

    In my project I am trying to implement the Game of Life on a 40*40 grid. There is a button which starts/stop the animation and there are 3 numbers that will decide how the next generation of living cells is created: the repRule, the underRule and the overRule.
    These three numbers are initialized at the beginning of mainwindow.cpp and I have a slider for each one of them as I want the user to be able to change them while running the application, the problem is that when I connect the sliders to a lambda function, the value of these integers do not change outside the scope of the lambda function. I have read some documentation on lambda functions, I have tried adding "&" before the variables like I did with a variable named "play" and I have tried to add the "mutable" keyword, but it still doesn't work.
    Here is a minimal example that shows the problem I'm having: (I am debugging the values of the integers when using the sliders and when the animation is running)

    mainwindow.h:

    Qt Code:
    1. #ifndef MAINWINDOW_H
    2. #define MAINWINDOW_H
    3.  
    4. #include <QMainWindow>
    5. #include <vector>
    6. #include <iostream>
    7.  
    8. #include <QApplication>
    9. #include <QPushButton>
    10. #include <QGraphicsScene>
    11. #include <QGraphicsItem>
    12. #include <QGraphicsView>
    13. #include <QTimer>
    14.  
    15.  
    16. QT_BEGIN_NAMESPACE
    17. namespace Ui
    18. {
    19. class MainWindow;
    20. }
    21. QT_END_NAMESPACE
    22.  
    23. using namespace std;
    24.  
    25. // global variables:
    26. const int WIDTH = 660;
    27. const int HEIGHT = 400;
    28. const int SIZE = 10;
    29. const int NCOL = HEIGHT/SIZE; //SIZE must be a divisor of HEIGHT
    30.  
    31. const QColor aliveCol = QColor(200,200,200);
    32. const QColor deadCol = QColor(50,50,50);
    33. const QColor textColor = Qt::white;
    34.  
    35. class Cell {
    36. public:
    37. int x;
    38. int y;
    39. bool alive;
    40. vector<pair<int,int>> neigh;
    41.  
    42. Cell(int a = 0, int b = 0) {
    43. x = a;
    44. y = b;
    45. alive = false;
    46. vector<pair<int,int>> neigh;
    47. }
    48.  
    49. void draw(QGraphicsScene *scene){
    50. QGraphicsRectItem *cell1 = new QGraphicsRectItem(this->x*SIZE,this->y*SIZE,SIZE,SIZE);
    51. if (this->alive) {
    52. cell1->setBrush(QBrush(aliveCol));
    53. }
    54. else {
    55. cell1->setBrush(QBrush(deadCol));
    56. }
    57. scene->addItem(cell1);
    58. }
    59.  
    60. };
    61.  
    62. class MainWindow : public QMainWindow
    63. {
    64. Q_OBJECT
    65.  
    66. public:
    67. MainWindow(QWidget *parent = nullptr);
    68. ~MainWindow();
    69.  
    70. void updateScene(Cell mat[NCOL][NCOL], QGraphicsScene *scene);
    71.  
    72. int countAlive(Cell c, Cell mat[NCOL][NCOL]);
    73.  
    74. void step(Cell mat[NCOL][NCOL], int rep, int under, int over);
    75.  
    76. private:
    77. Ui::MainWindow *ui;
    78. Cell mat[NCOL][NCOL] = {};
    79. };
    80. #endif // MAINWINDOW_H
    To copy to clipboard, switch view to plain text mode 

    mainwindow.cpp:
    Qt Code:
    1. #include "mainwindow.h"
    2. #include "ui_mainwindow.h"
    3. #include <QtCore/QRandomGenerator>
    4. #include <algorithm>
    5. #include <QDebug>
    6. #include <QSlider>
    7.  
    8. MainWindow::MainWindow(QWidget *parent)
    9. : QMainWindow(parent)
    10. , ui(new Ui::MainWindow)
    11. {
    12. ui->setupUi(this);
    13. QGraphicsScene *scene = new QGraphicsScene(0, 0, WIDTH, HEIGHT+70);
    14.  
    15. //Rules:
    16. int repRule = 3; //reproduction rule
    17. int underRule = 1; //underpopulation rule
    18. int overRule = 4; //overpopulation rule
    19.  
    20. //background:
    21. scene->setBackgroundBrush(Qt::gray);
    22.  
    23. for (int i = 0; i <= NCOL; i++)
    24. {
    25. scene->addLine(SIZE*i,0,SIZE*i,HEIGHT);
    26. scene->addLine(0,SIZE*i,HEIGHT,SIZE*i);
    27. }
    28.  
    29. //adding the button:
    30. QPushButton *button1;
    31. button1 = new QPushButton();
    32. button1->setGeometry(QRect(420, 20, 100, 30));
    33. button1->setText("Start / Stop");
    34. scene->addWidget(button1);
    35.  
    36. //adding sliders:
    37. //reproduction slider
    38. QSlider *repSlider;
    39. repSlider = new QSlider(Qt::Horizontal);
    40. repSlider->setGeometry(20,440,100,20);
    41. repSlider->setRange(0,8);
    42. repSlider->setValue(repRule);
    43. scene->addWidget(repSlider);
    44.  
    45. QGraphicsTextItem *sl1Text = new QGraphicsTextItem("Reprodution:");
    46. sl1Text->setPos(20,420);
    47. sl1Text->setDefaultTextColor(textColor);
    48. scene->addItem(sl1Text);
    49.  
    50. //underpopulation slider
    51. QSlider *underPopSlider;
    52. underPopSlider = new QSlider(Qt::Horizontal);
    53. underPopSlider->setGeometry(140,440,100,20);
    54. underPopSlider->setRange(0,8);
    55. underPopSlider->setValue(underRule);
    56. scene->addWidget(underPopSlider);
    57.  
    58. QGraphicsTextItem *sl2Text = new QGraphicsTextItem("Underpopulation:");
    59. sl2Text->setPos(140,420);
    60. sl2Text->setDefaultTextColor(textColor);
    61. scene->addItem(sl2Text);
    62.  
    63. //overpopulation slider
    64. QSlider *overPopSlider;
    65. overPopSlider = new QSlider(Qt::Horizontal);
    66. overPopSlider->setGeometry(260,440,100,20);
    67. overPopSlider->setRange(0,8);
    68. overPopSlider->setValue(overRule);
    69. scene->addWidget(overPopSlider);
    70.  
    71. QGraphicsTextItem *sl3Text = new QGraphicsTextItem("Overpopulation:");
    72. sl3Text->setPos(260,420);
    73. sl3Text->setDefaultTextColor(textColor);
    74. scene->addItem(sl3Text);
    75.  
    76. //building the cells matrix:
    77. for (int i = 0; i<NCOL; i++) {
    78. for (int j = 0; j<NCOL; j++) {
    79. mat[i][j] = Cell(i,j);
    80. }
    81. }
    82.  
    83. //adding the neighbours:
    84. for (int i = 0; i<NCOL; i++) {
    85. for (int j = 0; j<NCOL; j++) {
    86. mat[i][j].neigh.push_back(make_pair((i-1+NCOL)%NCOL,(j-1+NCOL)%NCOL));
    87. mat[i][j].neigh.push_back(make_pair(i,(j-1+NCOL)%NCOL));
    88. mat[i][j].neigh.push_back(make_pair((i+1)%NCOL,(j-1+NCOL)%NCOL));
    89. mat[i][j].neigh.push_back(make_pair((i-1+NCOL)%NCOL,j));
    90. mat[i][j].neigh.push_back(make_pair((i+1)%NCOL,j));
    91. mat[i][j].neigh.push_back(make_pair((i-1+NCOL)%NCOL,(j+1)%NCOL));
    92. mat[i][j].neigh.push_back(make_pair(i,(j+1)%NCOL));
    93. mat[i][j].neigh.push_back(make_pair((i+1)%NCOL,(j+1)%NCOL));
    94. }
    95. }
    96.  
    97. //have an initial layout for debugging
    98. mat[20][19].alive = true;
    99. mat[20][20].alive = true;
    100. mat[20][21].alive = true;
    101.  
    102. bool play = false;
    103.  
    104. updateScene(mat, scene);
    105.  
    106. //make scene
    107. QGraphicsView *view = new QGraphicsView(scene);
    108. view->setFixedSize(670, 480);
    109. view->show();
    110.  
    111. QTimer *_timer = new QTimer; //for the animation
    112.  
    113. //connect the button:
    114. connect(button1, &QPushButton::clicked, this, [&play]()
    115. {
    116. play = !play;
    117. }
    118. );
    119.  
    120. //connect the sliders:
    121. connect(repSlider, &QSlider::valueChanged, this, [&play, repSlider, &repRule](){
    122. if(!play) {
    123. repRule = repSlider->value();
    124. qDebug() << repRule;
    125. }
    126. });
    127.  
    128. connect(underPopSlider, &QSlider::valueChanged, this, [&play, underPopSlider, &underRule](){
    129. if(!play) {
    130. underRule = underPopSlider->value();
    131. qDebug() << underRule;
    132. }
    133. });
    134.  
    135. connect(overPopSlider, &QSlider::valueChanged, scene, [&play, overPopSlider, &overRule](){
    136. if(!play) {
    137. overRule = overPopSlider->value();
    138. qDebug() << overRule;
    139. }
    140. });
    141.  
    142. connect(_timer, &QTimer::timeout, scene, [this, &play, scene, repRule, underRule, overRule]()
    143. {
    144. if (play) {
    145. step(mat, repRule, underRule, overRule);
    146. updateScene(mat, scene);
    147. }
    148. }
    149. );
    150.  
    151. _timer->start(200);
    152. }
    153.  
    154. MainWindow::~MainWindow()
    155. {
    156. delete ui;
    157. }
    158.  
    159. void MainWindow::updateScene(Cell mat[NCOL][NCOL], QGraphicsScene *scene)
    160. {
    161. for (int i = 0; i<NCOL; i++) {
    162. for (int j = 0; j<NCOL; j++) {
    163. mat[i][j].draw(scene);
    164. }
    165. }
    166. }
    167.  
    168. int MainWindow::countAlive(Cell c, Cell mat[NCOL][NCOL]) //auxiliary function for the step function
    169. {
    170. int r = 0;
    171. for (pair<int,int> p : c.neigh) {
    172. if (mat[get<0>(p)][get<1>(p)].alive) {r++;}
    173. }
    174. return r;
    175. }
    176.  
    177. void MainWindow::step(Cell mat[NCOL][NCOL], int repN, int underN, int overN) //animation step
    178. {
    179. int aliveCount;
    180. vector<pair<int,int>> living = {};
    181. for (int i = 0; i < NCOL; i++) {
    182. for (int j = 0; j < NCOL; j++) {
    183. aliveCount = countAlive(mat[i][j],mat);
    184. //rules:
    185. if(!mat[i][j].alive){
    186. if(aliveCount == repN) {
    187. living.push_back(make_pair(i,j));
    188. }
    189. }
    190. else if (aliveCount > underN && aliveCount < overN) {
    191. living.push_back(make_pair(i,j));
    192. }
    193. }
    194. }
    195. for (int i = 0; i < NCOL; i++) {
    196. for (int j = 0; j < NCOL; j++) {
    197. mat[i][j].alive = std::find(living.begin(), living.end(), make_pair(i,j)) != living.end();
    198. }
    199. }
    200. qDebug() << repN << underN << overN;
    201. }
    To copy to clipboard, switch view to plain text mode 

    I will also take this opportunity to say that the animation runs slower with the time so there is probably a memory leak somewhere which I can't catch, so I'd appreciate is someone could help me with that aswell

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,246
    Thanks
    304
    Thanked 866 Times in 853 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Changing a variable out of scope of lambda expression

    //Rules:
    int repRule = 3; //reproduction rule
    int underRule = 1; //underpopulation rule
    int overRule = 4; //overpopulation rule

    bool play = false;
    Of course, you understand that these are all local variables, defined only in the scope of the MainWindow constructor, and as soon as the constructor exits, the variables go away, right? So it doesn't matter how you capture them in the lambda, they simply don't exist once the constructor exits. I am fuzzy on this part, but I suspect that once the variables go out of scope, so do the connections to the timer and slider signals.

    If you want to be able to access them outside the scope of the constructor, then they need to be member variables of the MainWindow class.

    I don't even know if your lambda statements are correct for that matter. Instead of trying to be so cutting edge, you could easily turn all of the lambdas into actual slots in MainWindow, in which case you would have immediately discovered the problem with your variables and their scope. So why don't you do that first until you get everything running, then try the more advanced way of doing it.

    For example, I have no idea what these are supposed to do, using QGraphicsScene as the connection target for the signals::

    Qt Code:
    1. connect(overPopSlider, &QSlider::valueChanged, scene, [&play, overPopSlider, &overRule](){
    2. if(!play) {
    3. overRule = overPopSlider->value();
    4. qDebug() << overRule;
    5. }
    6. });
    7.  
    8. connect(_timer, &QTimer::timeout, scene, [this, &play, scene, repRule, underRule, overRule]()
    9. {
    10. if (play) {
    11. step(mat, repRule, underRule, overRule);
    12. updateScene(mat, scene);
    13. }
    14. }
    15. );
    To copy to clipboard, switch view to plain text mode 

    I don't see any obvious memory leak in your minimal example, so you have probably "minimaled" it out.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  3. #3
    Join Date
    Jul 2021
    Posts
    5
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Changing a variable out of scope of lambda expression

    I am not sure this is what you meant, but I changed my code to this.

    mainwindow.h:
    Qt Code:
    1. #ifndef MAINWINDOW_H
    2. #define MAINWINDOW_H
    3.  
    4. #include <QMainWindow>
    5. #include <vector>
    6. #include <iostream>
    7.  
    8. #include <QApplication>
    9. #include <QPushButton>
    10. #include <QGraphicsScene>
    11. #include <QGraphicsItem>
    12. #include <QGraphicsView>
    13. #include <QTimer>
    14. #include <QSlider>
    15.  
    16.  
    17. QT_BEGIN_NAMESPACE
    18. namespace Ui
    19. {
    20. class MainWindow;
    21. }
    22. QT_END_NAMESPACE
    23.  
    24. using namespace std;
    25.  
    26. // global variables:
    27. const int WIDTH = 660;
    28. const int HEIGHT = 400;
    29. const int SIZE = 10;
    30. const int NCOL = HEIGHT/SIZE; //SIZE must be a divisor of HEIGHT
    31.  
    32. const QColor aliveCol = QColor(200,200,200);
    33. const QColor deadCol = QColor(50,50,50);
    34. const QColor textColor = Qt::white;
    35.  
    36. class Cell {
    37. public:
    38. int x;
    39. int y;
    40. bool alive;
    41. vector<pair<int,int>> neigh;
    42.  
    43. Cell(int a = 0, int b = 0) {
    44. x = a;
    45. y = b;
    46. alive = false;
    47. vector<pair<int,int>> neigh;
    48. }
    49.  
    50. void draw(QGraphicsScene *scene){
    51. QGraphicsRectItem *cell1 = new QGraphicsRectItem(this->x*SIZE,this->y*SIZE,SIZE,SIZE);
    52. if (this->alive) {
    53. cell1->setBrush(QBrush(aliveCol));
    54. }
    55. else {
    56. cell1->setBrush(QBrush(deadCol));
    57. }
    58. scene->addItem(cell1);
    59. }
    60.  
    61. };
    62.  
    63. class MainWindow : public QMainWindow
    64. {
    65. Q_OBJECT
    66.  
    67. public:
    68. //Rules:
    69. int repRule = 3; //reproduction rule
    70. int underRule = 1; //underpopulation rule
    71. int overRule = 4; //overpopulation rule
    72.  
    73. QSlider *repSlider;
    74. QSlider *underPopSlider;
    75. QSlider *overPopSlider;
    76.  
    77. QGraphicsTextItem *sl1Text = new QGraphicsTextItem("Reprodution:");
    78. QGraphicsTextItem *sl2Text = new QGraphicsTextItem("Underpopulation:");
    79. QGraphicsTextItem *sl3Text = new QGraphicsTextItem("Overpopulation:");
    80.  
    81. MainWindow(QWidget *parent = nullptr);
    82. ~MainWindow();
    83.  
    84. void updateScene(Cell mat[NCOL][NCOL], QGraphicsScene *scene);
    85.  
    86. int countAlive(Cell c, Cell mat[NCOL][NCOL]);
    87.  
    88. void step(Cell mat[NCOL][NCOL], int rep, int under, int over);
    89.  
    90. private:
    91. Ui::MainWindow *ui;
    92. Cell mat[NCOL][NCOL] = {};
    93.  
    94. public slots:
    95. void updateRules();
    96. };
    97. #endif // MAINWINDOW_H
    To copy to clipboard, switch view to plain text mode 

    mainwindow.cpp

    Qt Code:
    1. #include "mainwindow.h"
    2. #include "ui_mainwindow.h"
    3. #include <QtCore/QRandomGenerator>
    4. #include <algorithm>
    5. #include <QDebug>
    6.  
    7. MainWindow::MainWindow(QWidget *parent)
    8. : QMainWindow(parent)
    9. , ui(new Ui::MainWindow)
    10. {
    11. ui->setupUi(this);
    12. QGraphicsScene *scene = new QGraphicsScene(0, 0, WIDTH, HEIGHT+70);
    13.  
    14. //background:
    15. scene->setBackgroundBrush(Qt::gray);
    16.  
    17. for (int i = 0; i <= NCOL; i++)
    18. {
    19. scene->addLine(SIZE*i,0,SIZE*i,HEIGHT);
    20. scene->addLine(0,SIZE*i,HEIGHT,SIZE*i);
    21. }
    22.  
    23. //adding the button:
    24. QPushButton *button1;
    25. button1 = new QPushButton();
    26. button1->setGeometry(QRect(420, 20, 100, 30));
    27. button1->setText("Start / Stop");
    28. scene->addWidget(button1);
    29.  
    30. //adding sliders:
    31. //reproduction slider
    32.  
    33. repSlider = new QSlider(Qt::Horizontal);
    34. repSlider->setGeometry(20,440,100,20);
    35. repSlider->setRange(0,8);
    36. repSlider->setValue(repRule);
    37. scene->addWidget(repSlider);
    38.  
    39. sl1Text->setPos(20,420);
    40. sl1Text->setDefaultTextColor(textColor);
    41. scene->addItem(sl1Text);
    42.  
    43. //underpopulation slider
    44. underPopSlider = new QSlider(Qt::Horizontal);
    45. underPopSlider->setGeometry(140,440,100,20);
    46. underPopSlider->setRange(0,8);
    47. underPopSlider->setValue(underRule);
    48. scene->addWidget(underPopSlider);
    49.  
    50. sl2Text->setPos(140,420);
    51. sl2Text->setDefaultTextColor(textColor);
    52. scene->addItem(sl2Text);
    53.  
    54. //overpopulation slider
    55. overPopSlider = new QSlider(Qt::Horizontal);
    56. overPopSlider->setGeometry(260,440,100,20);
    57. overPopSlider->setRange(0,8);
    58. overPopSlider->setValue(overRule);
    59. scene->addWidget(overPopSlider);
    60.  
    61. sl3Text->setPos(260,420);
    62. sl3Text->setDefaultTextColor(textColor);
    63. scene->addItem(sl3Text);
    64.  
    65. //building the cells matrix:
    66. for (int i = 0; i<NCOL; i++) {
    67. for (int j = 0; j<NCOL; j++) {
    68. mat[i][j] = Cell(i,j);
    69. }
    70. }
    71.  
    72. //adding the neighbours:
    73. for (int i = 0; i<NCOL; i++) {
    74. for (int j = 0; j<NCOL; j++) {
    75. mat[i][j].neigh.push_back(make_pair((i-1+NCOL)%NCOL,(j-1+NCOL)%NCOL));
    76. mat[i][j].neigh.push_back(make_pair(i,(j-1+NCOL)%NCOL));
    77. mat[i][j].neigh.push_back(make_pair((i+1)%NCOL,(j-1+NCOL)%NCOL));
    78. mat[i][j].neigh.push_back(make_pair((i-1+NCOL)%NCOL,j));
    79. mat[i][j].neigh.push_back(make_pair((i+1)%NCOL,j));
    80. mat[i][j].neigh.push_back(make_pair((i-1+NCOL)%NCOL,(j+1)%NCOL));
    81. mat[i][j].neigh.push_back(make_pair(i,(j+1)%NCOL));
    82. mat[i][j].neigh.push_back(make_pair((i+1)%NCOL,(j+1)%NCOL));
    83. }
    84. }
    85.  
    86. //have an initial layout for debugging
    87. mat[20][19].alive = true;
    88. mat[20][20].alive = true;
    89. mat[20][21].alive = true;
    90.  
    91. bool play = false;
    92.  
    93. updateScene(mat, scene);
    94.  
    95. //make scene
    96. QGraphicsView *view = new QGraphicsView(scene);
    97. view->setFixedSize(670, 480);
    98. view->show();
    99.  
    100. QTimer *_timer = new QTimer; //for the animation
    101.  
    102. //connect the button:
    103. connect(button1, &QPushButton::clicked, this, [&play]()
    104. {
    105. play = !play;
    106. }
    107. );
    108.  
    109. connect(repSlider, &QSlider::valueChanged, this, &MainWindow::updateRules);
    110.  
    111. connect(underPopSlider, &QSlider::valueChanged, this, &MainWindow::updateRules);
    112.  
    113. connect(overPopSlider, &QSlider::valueChanged, this, &MainWindow::updateRules);
    114.  
    115. connect(_timer, &QTimer::timeout, scene, [this, &play, scene]()
    116. {
    117. if (play) {
    118. step(mat, repRule, underRule, overRule);
    119. updateScene(mat, scene);
    120. }
    121. }
    122. );
    123.  
    124. _timer->start(200);
    125. }
    126.  
    127. MainWindow::~MainWindow()
    128. {
    129. delete ui;
    130. }
    131.  
    132. void MainWindow::updateScene(Cell mat[NCOL][NCOL], QGraphicsScene *scene)
    133. {
    134. for (int i = 0; i<NCOL; i++) {
    135. for (int j = 0; j<NCOL; j++) {
    136. mat[i][j].draw(scene);
    137. }
    138. }
    139. }
    140.  
    141. int MainWindow::countAlive(Cell c, Cell mat[NCOL][NCOL]) //auxiliary function for the step function
    142. {
    143. int r = 0;
    144. for (pair<int,int> p : c.neigh) {
    145. if (mat[get<0>(p)][get<1>(p)].alive) {r++;}
    146. }
    147. return r;
    148. }
    149.  
    150. void MainWindow::step(Cell mat[NCOL][NCOL], int repN, int underN, int overN) //animation step
    151. {
    152. int aliveCount;
    153. vector<pair<int,int>> living = {};
    154. for (int i = 0; i < NCOL; i++) {
    155. for (int j = 0; j < NCOL; j++) {
    156. aliveCount = countAlive(mat[i][j],mat);
    157. //rules:
    158. if(!mat[i][j].alive){
    159. if(aliveCount == repN) {
    160. living.push_back(make_pair(i,j));
    161. }
    162. }
    163. else if (aliveCount > underN && aliveCount < overN) {
    164. living.push_back(make_pair(i,j));
    165. }
    166. }
    167. }
    168. for (int i = 0; i < NCOL; i++) {
    169. for (int j = 0; j < NCOL; j++) {
    170. mat[i][j].alive = std::find(living.begin(), living.end(), make_pair(i,j)) != living.end();
    171. }
    172. }
    173. }
    174.  
    175. void MainWindow::updateRules()
    176. {
    177. repRule = repSlider->value();
    178. underRule = underPopSlider->value();
    179. overRule = overPopSlider->value();
    180. }
    To copy to clipboard, switch view to plain text mode 

    There is probably a lot that can still be improved regarding where things should go but at least now the sliders are working fine when I mess with their values. The one thing that threw me off was the fact that it was working perfectly for the "play" variable, unlike the sliders...
    Last edited by FBF_Luis; 21st August 2021 at 00:31. Reason: reformatted to look better

  4. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,246
    Thanks
    304
    Thanked 866 Times in 853 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Changing a variable out of scope of lambda expression

    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.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  5. #5
    Join Date
    Jul 2021
    Posts
    5
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Changing a variable out of scope of lambda expression

    That code came from a question I asked on a forum a while ago. It did what I intended at the moment and then I just added stuff and never got any problems with it, so I just went whit it.
    Would then say that I should make "play" and "scene" also members from mainwindow class and use a slot instead of a lambda function to connect to that timer?

  6. #6
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,246
    Thanks
    304
    Thanked 866 Times in 853 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Changing a variable out of scope of lambda expression

    Would then say that I should make "play" and "scene" also members from mainwindow class and use a slot instead of a lambda function to connect to that timer?
    That's how I would do it. Makes it much easier to debug when it is a slot and not a lambda.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

Similar Threads

  1. Value of variable changing randomly
    By satilla in forum Newbie
    Replies: 0
    Last Post: 30th May 2018, 11:06
  2. QTimer Lambda
    By bmn in forum Qt Programming
    Replies: 2
    Last Post: 8th March 2016, 08:23
  3. variable scope question
    By jeffmetal in forum Newbie
    Replies: 6
    Last Post: 16th June 2011, 23:41
  4. Variable not declared in this scope error
    By hojoff79 in forum Newbie
    Replies: 1
    Last Post: 30th December 2010, 01:29
  5. QT and variable scope
    By tommy in forum Qt Programming
    Replies: 1
    Last Post: 29th November 2007, 22:32

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.