Modify Qlabel value in Runtime
-
I have tried the code that you have put me and emits well. There is a While loop. This loop, at the end of each iteration, calls the daysDown () method but it works fine, in each iteration it shows "downDays called"
@juaniyoalm said in Modify Qlabel value in Runtime:
There is a While loop. This loop, at the end of each iteration, calls the daysDown () method but it works fine, in each iteration it shows "downDays called"
Yeah, but the emit is processed once the event loop is free running - which is not the case in your while loop.
Try replacing the loop with some QTimer, for example.
Edit: it is rather the repainting of the GUI that is processed when the event loop is running.
-
@juaniyoalm said in Modify Qlabel value in Runtime:
There is a While loop. This loop, at the end of each iteration, calls the daysDown () method but it works fine, in each iteration it shows "downDays called"
Yeah, but the emit is processed once the event loop is free running - which is not the case in your while loop.
Try replacing the loop with some QTimer, for example.
Edit: it is rather the repainting of the GUI that is processed when the event loop is running.
Thank you for your answer.
Sorry but I'm starting to use Qt and I'm not going to use it well yet. How do I substitute the while loop for QTimer?
-
Thank you for your answer.
Sorry but I'm starting to use Qt and I'm not going to use it well yet. How do I substitute the while loop for QTimer?
@juaniyoalm
Hi
before changing to a timer, you could try inserting
QApplication::processEvents();
( its static )
in the loop just after calling daysDown()
This drives the event loop and if it updates, its clear it was strangulating the event loop.
Please note however, its not the optimal / recommended way of fixing it.
Its just to test we found the guilty section :) -
Thank you for your answer.
Sorry but I'm starting to use Qt and I'm not going to use it well yet. How do I substitute the while loop for QTimer?
Something like this (only brain compiled):
// world.h #include <QTimer> class World : public QObject { // ... public slots: void downDays(); private: QTimer *m_timer; } // world.cpp m_timer = new QTimer(this); m_timer->setTimeout(1000); connect(m_timer, &QTimer::timeout, this, &World::downDays); m_timer->start();
-
Thank you for your answer.
Sorry but I'm starting to use Qt and I'm not going to use it well yet. How do I substitute the while loop for QTimer?
I've inserted QApplication::processEvents() and the app works fine now!!
What would be the correct way to do it?
-
I've inserted QApplication::processEvents() and the app works fine now!!
What would be the correct way to do it?
@juaniyoalm using a QTimer ;)
-
@juaniyoalm using a QTimer ;)
Qtimer class hasn't a member named setTimeout...
-
Qtimer class hasn't a member named setTimeout...
@juaniyoalm sorry, use setInterval
-
@juaniyoalm sorry, use setInterval
I used setInterval but the app does not work fine. I have placed it in the constructor.
This is my code:
Initial.cpp (Window)
Initial::Initial() { widget.setupUi(this); // Conexíon de Observers connect(this->widget.nHongosLineEdit,&QLineEdit::textEdited, this, &Initial::on_nHongosLineEdit); connect(this->widget.startButton,&QPushButton::clicked, this, &Initial::buttonInitClick); connect(&mundo, &World::daysChange, this->widget.infoDiasLabel, &QLabel::setText); connect(&mundo, &World::daysChange, this, &Initial::daysChanged); m_timer = new QTimer(this); m_timer->setInterval(1000); connect(m_timer, &QTimer::timeout, this, &Initial::daysChanged); m_timer->start(); // Validación de campos QIntValidator* validator = new QIntValidator(0, 500, this); this->widget.nFilasLineEdit->setValidator(validator); this->widget.nColumnasLineEdit->setValidator(validator); this->widget.nHongosLineEdit->setValidator(validator); this->widget.diasLineEdit->setValidator(validator); this->widget.tableWidget->horizontalHeader()->stretchLastSection(); this->widget.tableWidget->verticalHeader()->setVisible(false); this->widget.infoHongosLabel->setText("0"); this->widget.infoDiasLabel->setText("100"); }
Initial.h
class Initial : public QMainWindow { Q_OBJECT public: Initial(); void tableFill(); void init(); virtual ~Initial(); public slots: void on_nHongosLineEdit( const QString & text ); void buttonInitClick (); void daysChanged(); private: Ui::Initial widget; World mundo; int rows; int col; int nFungus; int days; QTimer *m_timer; };
World.cpp (Only loop)
while (this->days != 0) { cout << endl; cout << "----------------------------------" << endl; cout << "QUEDA(N) " << this->days << " DIA(S) " << endl; cout << "----------------------------------" << endl; // Recorremos todos los hongos de los que disponemos. for (unsigned long i = 0; i < this->allFungus.size(); i++) { fungus = getFungusByPosition(i); // Si el hongo esta COMPLETAMENTE saciado, reestablecemos su saciedad. if (fungus->getSatiate() == 5) fungus->setSatiate(0); cell = getCell(fungus->getPlace().first, fungus->getPlace().second); // Mientras que el hongo no este saciado... while (!fungus->isSaciate()) { if (cell->thereIsFood()) { // Si la celda tiene comida... cout << "La celda (" << fungus->getPlace().first << ", " << fungus->getPlace().second << ")" << " tiene comida" << endl; cell->feed(); fungus->feed(); cout << "El hongo con id " << fungus->getId() << " se come una unidad de la celda situada en la coordenada (" << fungus->getPlace().first << ", " << fungus->getPlace().second << ")" << endl; if (fungus->isSaciate()){ cout << "El hongo con id " << fungus->getId() << " esta saciado" << endl; cout << endl; } } else { // Si la celda no tiene comida... cout << "No hay comida en la celda " << fungus->getPlace().first << ", " << fungus->getPlace().second << endl; // Identificamos el movimiento del hongo. int move = moveType(fungus, areLimit(std::pair<unsigned long, unsigned long>(fungus->getPlace().first, fungus->getPlace().second))); // Realizamos el movimiento del hongo. assignMove(move, cell, fungus); cout << "El hongo " << fungus->getId() << " se ha movido a la coordenada " << fungus->getPlace().first << ", " << fungus->getPlace().second << endl; if(!cell->thereIsFood()) break; } // Fin del condicional HAY COMIDA } // Fin del WHILE SACIADO } // Fin del FOR // Decrementamos los días downDays(); //QApplication::processEvents(); } // Fin del WHILE DÍAS
World.h
using namespace std; // Tipos definidos que permiten la creación de la matriz (World) typedef vector<vector<Cell*>> AllWorld; class World : public QObject { Q_OBJECT public: unsigned long days; // Días que durará el mundo. World(); // Constructor de World por defecto. World(unsigned long, unsigned long, unsigned long, unsigned long); // Constructor de World sobrecargado. void createWorld(unsigned long, unsigned long, unsigned long, unsigned long); // Crea un mundo. void distributeFungus(unsigned long, unsigned long); // Distribuye aleatoriamente los hongos en el mundo. void initializeWorld(); // Inicializa el mundo. AllWorld getWorld(); // Devuelve el mundo. vector<Fungus*> getAllFungus(); // Devuelve un array de punteros a los hongos. int getAllFungusSize(); // Devuelve el número de hongos totales. unsigned long rowSize(); // Número de filas de la matriz (World). unsigned long columnSize(); // Número de columnas de la matriz (World). Fungus* getFungusByPosition(unsigned long); // Devuelve un hongo dada una posicion del array de punteros. int areLimit(std::pair<unsigned long, unsigned long> place); // Devuelve en qué límite se encuentra el hongo (0 para no límite). int moveType(Fungus*, int); // Comprueba en que celda hay comida y devuelve un movimiento. Cell* getCell(int, int); // Devuelve un puntero a una celda del mundo. void assignMove(int, Cell*, Fungus*); // Mueve un hongo de celda. void downDays(); // Decrementa un día. virtual ~World(); // Destructor de World por defecto. signals: void daysChange(const QString &); private: AllWorld world; // Matriz que contiene todas las celdas (Mundo). vector<Fungus> allFungus; // Array de hongos. double timeExecute; };
-
I used setInterval but the app does not work fine. I have placed it in the constructor.
This is my code:
Initial.cpp (Window)
Initial::Initial() { widget.setupUi(this); // Conexíon de Observers connect(this->widget.nHongosLineEdit,&QLineEdit::textEdited, this, &Initial::on_nHongosLineEdit); connect(this->widget.startButton,&QPushButton::clicked, this, &Initial::buttonInitClick); connect(&mundo, &World::daysChange, this->widget.infoDiasLabel, &QLabel::setText); connect(&mundo, &World::daysChange, this, &Initial::daysChanged); m_timer = new QTimer(this); m_timer->setInterval(1000); connect(m_timer, &QTimer::timeout, this, &Initial::daysChanged); m_timer->start(); // Validación de campos QIntValidator* validator = new QIntValidator(0, 500, this); this->widget.nFilasLineEdit->setValidator(validator); this->widget.nColumnasLineEdit->setValidator(validator); this->widget.nHongosLineEdit->setValidator(validator); this->widget.diasLineEdit->setValidator(validator); this->widget.tableWidget->horizontalHeader()->stretchLastSection(); this->widget.tableWidget->verticalHeader()->setVisible(false); this->widget.infoHongosLabel->setText("0"); this->widget.infoDiasLabel->setText("100"); }
Initial.h
class Initial : public QMainWindow { Q_OBJECT public: Initial(); void tableFill(); void init(); virtual ~Initial(); public slots: void on_nHongosLineEdit( const QString & text ); void buttonInitClick (); void daysChanged(); private: Ui::Initial widget; World mundo; int rows; int col; int nFungus; int days; QTimer *m_timer; };
World.cpp (Only loop)
while (this->days != 0) { cout << endl; cout << "----------------------------------" << endl; cout << "QUEDA(N) " << this->days << " DIA(S) " << endl; cout << "----------------------------------" << endl; // Recorremos todos los hongos de los que disponemos. for (unsigned long i = 0; i < this->allFungus.size(); i++) { fungus = getFungusByPosition(i); // Si el hongo esta COMPLETAMENTE saciado, reestablecemos su saciedad. if (fungus->getSatiate() == 5) fungus->setSatiate(0); cell = getCell(fungus->getPlace().first, fungus->getPlace().second); // Mientras que el hongo no este saciado... while (!fungus->isSaciate()) { if (cell->thereIsFood()) { // Si la celda tiene comida... cout << "La celda (" << fungus->getPlace().first << ", " << fungus->getPlace().second << ")" << " tiene comida" << endl; cell->feed(); fungus->feed(); cout << "El hongo con id " << fungus->getId() << " se come una unidad de la celda situada en la coordenada (" << fungus->getPlace().first << ", " << fungus->getPlace().second << ")" << endl; if (fungus->isSaciate()){ cout << "El hongo con id " << fungus->getId() << " esta saciado" << endl; cout << endl; } } else { // Si la celda no tiene comida... cout << "No hay comida en la celda " << fungus->getPlace().first << ", " << fungus->getPlace().second << endl; // Identificamos el movimiento del hongo. int move = moveType(fungus, areLimit(std::pair<unsigned long, unsigned long>(fungus->getPlace().first, fungus->getPlace().second))); // Realizamos el movimiento del hongo. assignMove(move, cell, fungus); cout << "El hongo " << fungus->getId() << " se ha movido a la coordenada " << fungus->getPlace().first << ", " << fungus->getPlace().second << endl; if(!cell->thereIsFood()) break; } // Fin del condicional HAY COMIDA } // Fin del WHILE SACIADO } // Fin del FOR // Decrementamos los días downDays(); //QApplication::processEvents(); } // Fin del WHILE DÍAS
World.h
using namespace std; // Tipos definidos que permiten la creación de la matriz (World) typedef vector<vector<Cell*>> AllWorld; class World : public QObject { Q_OBJECT public: unsigned long days; // Días que durará el mundo. World(); // Constructor de World por defecto. World(unsigned long, unsigned long, unsigned long, unsigned long); // Constructor de World sobrecargado. void createWorld(unsigned long, unsigned long, unsigned long, unsigned long); // Crea un mundo. void distributeFungus(unsigned long, unsigned long); // Distribuye aleatoriamente los hongos en el mundo. void initializeWorld(); // Inicializa el mundo. AllWorld getWorld(); // Devuelve el mundo. vector<Fungus*> getAllFungus(); // Devuelve un array de punteros a los hongos. int getAllFungusSize(); // Devuelve el número de hongos totales. unsigned long rowSize(); // Número de filas de la matriz (World). unsigned long columnSize(); // Número de columnas de la matriz (World). Fungus* getFungusByPosition(unsigned long); // Devuelve un hongo dada una posicion del array de punteros. int areLimit(std::pair<unsigned long, unsigned long> place); // Devuelve en qué límite se encuentra el hongo (0 para no límite). int moveType(Fungus*, int); // Comprueba en que celda hay comida y devuelve un movimiento. Cell* getCell(int, int); // Devuelve un puntero a una celda del mundo. void assignMove(int, Cell*, Fungus*); // Mueve un hongo de celda. void downDays(); // Decrementa un día. virtual ~World(); // Destructor de World por defecto. signals: void daysChange(const QString &); private: AllWorld world; // Matriz que contiene todas las celdas (Mundo). vector<Fungus> allFungus; // Array de hongos. double timeExecute; };
@juaniyoalm Well, the blocking loop is still there.
You need to move the loop body into a slot and call that slot from the QTimers timeout signal. When
this->days == 0
, you stop the timer. Should be pretty straight forward.