Passing object reference to a Timer slot
-
Hi,
I am currently working with Qt4.8 and I have to toggle an icon image for which I have used QTimer class but in my code I am maintaining an object of a widget class which is having details and functions to set the layout and pixmap of the icons. The problem I am facing is that the reference cannot be passed to slot function due to signature mismatch of SIGNAL (timout()) and slot function. The object is local in one of the function passed by another function. So is there any other way round to access that object in the slot function.```
void TCStatusTrainView::drawBrakes(TCarCarWidget * pCarItem, const CCCUOtoTDDB * pBuffer, const int cst)
{const TCCarModel * pCarModel = pCarItem->getModel(); const CarType *pCarType = pCarModel->getCarType(); QSize car = QSize(qint16(pCarItem->size().width()), qint16(pCarItem->size().height())); int x = car.width() / 2; // car.width() / 2; int y = car.height(); if((pCarType->getCarType() == CarType::E_CarType::BDX) || (pCarType->getCarType() == CarType::E_CarType::AB) || (pCarType->getCarType() == CarType::E_CarType::B)) { switch (pBuffer->IFEMStatus[cst]) // Used Door signal for test purpose #TODO:- update with brake signal { case ECTrainStatus::MagneticBrakeApplied: icon_down = ":/Brakes/status_magnetic_applied.png"; break; case ECTrainStatus::MagneticBrakePartiallyTight: { a_BlinkTimer->start(1000); } break; default: icon_down = ":/Brakes/status_magnetic_default.png"; break; } } else { icon_down = ""; } if (icon_down != "") { pCarItem->addPixmapToSceneBrake(QPoint(x-15, y + 19), icon_down); }
}
void TCStatusTrainView::blinkMagneticPad() { if(icon_down == "") { icon_down = ":/Brakes/status_magnetic_partially_applied.png"; icon_down1 = ""; } else if (icon_down1 == "") { icon_down1 = ":/Brakes/status_magnetic_blink.png"; icon_down = ""; } }
Also I have created a custom timer class but still the problem is same as in the slot for custom class I need to have access to emit the signal of with pCarItem type ``
CustomTimer.cpp
#include "customtimer.h" CustomTimer::CustomTimer() { timer = new QTimer(this); connect(timer, SIGNAL(timeout()),this,SLOT(myTimerSlot())); timer->start(1000); } void CustomTimer::myTimerSlot() { emit sigV_BrakeNotification(TCarCarWidget &pCarItem); } CustomTimer.h
#ifndef CUSTOMTIMER_H #define CUSTOMTIMER_H #include <QTimer> #include "tcar_car_widget.h" class CustomTimer : public QObject { Q_OBJECT public: CustomTimer(); QTimer *timer; signals: void sigV_BrakeNotification(TCarCarWidget &pCarItem); public slots: void myTimerSlot(); }; #endif // CUSTOMTIMER_H
-
@Manish-Dhariwal Where is the timer actually?
The thing is: timer should not care about any parameters, it's just a timer and fires a timeout signal."The object is local in one of the function passed by another function" - you have a local widget instance?! Why local?
You should implement some logic which changes what needs to be changed each time timeout signal is emitted.
Toggling an icon is actually easy: define a bool variable and in the slot connected to the timeout signal you toggle the value of that bool variable and depending on its current value change the icon:void MyClass::onTimeout() { boolVar = !boolVar; if (boolVar) { ... } else { ... } }
-
Thanks for your response :)
Where is the timer actually? Timer is connected in onCreate() method of the view class declared in .h file.
you have a local widget instance? Local means the widget object is created in function populate() ```void TCStatusTrainView::populate() { if (a_pTrainWidget == 0 || a_pTrainWidget->scene() == 0) { return; } const CCCUOtoTDDB * pBuffer = a_pPdTrainStatus->getBuffer(); quint8 maxCarCount = a_pTrainWidget->getCarCarWidgetsCount(); for (int car = 0; car < maxCarCount; car++) { TCarCarWidget * pCarItem = a_pTrainWidget->getCarWidgetByIptIdx(car); if (pCarItem) { pCarItem->clearPixmap(); drawLocalCab(pCarItem, pBuffer, car); drawKey(pCarItem, pBuffer, car); drawCoupler(pCarItem, pBuffer, car); switch (currentMode) { case SM_DOORS: drawDoors(pCarItem, pBuffer, car); break; case SM_LIGHTS: pCarItem->setCarNumberPosition(posTopmedView); drawLights(pCarItem, pBuffer, car); break; case SM_PAS: drawPas(pCarItem, pBuffer, car); break; case SM_BRAKE: drawBrakes(pCarItem, pBuffer, car); break; default: break; } } } a_pTrainWidget->scene()->update(); }
Logic for toggling is working but the widget is not updated because it has to call function addPixmapToSceneBrake() which is accessible to pCarItem. The function than add the pixmap to a QGraphicsPixmapItem for each car type passed to drawBrakes.
-
@Manish-Dhariwal said in Passing object reference to a Timer slot:
widget is not updated
You mean pCarItem?
"because it has to call function addPixmapToSceneBrake()" - and what is the problem with that?
-
@jsulm said in Passing object reference to a Timer slot:
addPixmapToSceneBrake
pCarItem is not accessible in slot function and to toggle the image I have to call addPixmapToSceneBrake() from the slot. So If any how I can pass the pCarItem to slot its done.
-
@Manish-Dhariwal I still don't really understand your code. To which slot do you connect the timeout? Do you want to toggle for all cars? or only for one specific?
-
No because if you see populate() function the pCarItem is iterated dynamically basis on maxCarCount and also drawBrakes(pCarItem, pBuffer, car); is called with each car number.
-
@jsulm Yes I have to iterate through all the cars. The slot is the blinkMagneticPad() and timer is started from drawBrakes depending on condition. drawBrakes() is called from populate() function for each car with pCarItem.
customtimer i am not using right now I have just tried if any custom signal and slot can be used to pass the argument in slot
-
@Manish-Dhariwal said in Passing object reference to a Timer slot:
Yes I have to iterate through all the cars
Then you can do the same in your slot:
quint8 maxCarCount = a_pTrainWidget->getCarCarWidgetsCount(); for (int car = 0; car < maxCarCount; car++) { TCarCarWidget * pCarItem = a_pTrainWidget->getCarWidgetByIptIdx(car);
and call what ever needs to be called for each pCarItem.