PDA

View Full Version : singleShot



saman_artorious
9th June 2012, 10:13
I use the QTimer::singleShot function to delay for some seconds. If, that's the only thing, I set
the SLOT parameter to NULL. Otherwise, I pass a SLOT function to it.

As I checked the program, I think, the SingleShot function does not wait till the time pass and then carry on with
the rest of the instructions. could you tell me how I can accomplish that? knowing that I cannot use the sleep() function at all as it would
suspend all processes.

Your

wysota
9th June 2012, 10:28
QEventLoop loop;
QTimer::singleShot(1000, &loop, SLOT(quit()));
loop.exec();

However a much better idea is to just put the rest of your code in a separate slot and use the timer to call that slot.

Zlatomir
9th June 2012, 10:37
If you need that only for testing you can use: QTest::qSleep(1000); //one second (you will need CONFIG += qtestlib in your .pro file)

saman_artorious
9th June 2012, 11:04
if I use QTImer with interval set, it keeps reseting and triggering the SLOT() infinitely. What I want is the SLOT get triggered only and only once, or even without any slots, set to NULL, for the sake of suspending the process.

So, I guess this may get me to what I want
QEventLoop loop;
QTimer::singleShot(msec, &loop, NULL);
loop.exec();

wysota
9th June 2012, 11:09
if I use QTImer with interval set, it keeps reseting and triggering the SLOT() infinitely.
QTimer::setSingleShot()


What I want is the SLOT get triggered only and only once, or even without any slots, set to NULL, for the sake of suspending the process.
Timers do not suspend anything. The code I gave you also doesn't suspend anything, it merely enters an event loop and exits it after a predefined period of time. However if during that time something happens (e.g. some timer fires) other slots and functions will be executed. If the code is part of some slot it might happen that this slot will be reentered again.

saman_artorious
9th June 2012, 11:43
In other words, let's consider this, whenever a particular condition sets to TRUE, I need to start a timer for a specific amount of time and then it goes dim till the condition goes true again.
For this case, which one do yo think is better

-connect the timer, set interval, set singleshot to true. and.. in this case I think everytime I need to activate the timer I should call restart

the other case is to:
-connect the timer, setinterval, and set the timer to start and stop when it times out.

Considering that it should only run when the condition goes true.

are the above correct?


QTimer::setSingleShot()


Timers do not suspend anything. The code I gave you also doesn't suspend anything, it merely enters an event loop and exits it after a predefined period of time. However if during that time something happens (e.g. some timer fires) other slots and functions will be executed. If the code is part of some slot it might happen that this slot will be reentered again.

is there any way to wait for some period of time before executing the next instructions then? imagine I don't want to call any slots in some cases, I only want to delay.

wysota
9th June 2012, 11:53
In other words, let's consider this, whenever a particular condition sets to TRUE, I need to start a timer for a specific amount of time and then it goes dim till the condition goes true again.
I don't understand what you mean. If you mean that you want it to fire once then make it a single shot timer by calling setSingleShot(true).


For this case, which one do yo think is better

-connect the timer, set interval, set singleshot to true. and.. in this case I think everytime I need to activate the timer I should call restart

the other case is to:
-connect the timer, setinterval, and set the timer to start and stop when it times out.
The first one.


is there any way to wait for some period of time before executing the next instructions then? imagine I don't want to call any slots in some cases, I only want to delay.
Call sleep().

saman_artorious
9th June 2012, 14:27
It's not a good idea to use sleep(), as it would suspend all Timers n connections for a while. is there any other way to do it?

if I use this


QEventLoop loop;
QTimer::singleShot(msec, &loop, NULL);
loop.exec();


will it stop the instruction execution or not.?

wysota
9th June 2012, 14:29
is there any way to wait for some period of time before executing the next instructions then? imagine I don't want to call any slots in some cases, I only want to delay.
That's what you wanted, wasn't it?

saman_artorious
9th June 2012, 14:30
I don't know if you get my point or not. I cannot use sleep() as it will damage all the QTimers (suspends them all).
I just want to delay for some seconds. And, I don't want to use as many slots to put the rest of my code inside it.

sleep() suspends all running threads or timers. I don't want that, I only want to delay one particular thread.

amleto
9th June 2012, 15:26
sounds like you are stuck on trying to implement YOUR solution to a problem we don't know anything about.

saman_artorious
10th June 2012, 08:02
consider the following:



void FuelSystem::DSLFL_DataReceive(QByteArray data)
{
/* 4)Lower sensor 5)upper Sensor 6)water sensor */

QByteArray command_SV15;
QByteArray command_HV14;
QByteArray command_FTWL_SV9;

if(data.at(3) == FUEL_SYSTEM)
{
if(data.at(4) == 0x01)
{
FuelPump_start();

command_SV15.append(FUEL_SYSTEM);
command_SV15.append(DSLFL_ST_SV_15);
command_SV15.append(0x01);

emit DSLFL_SendToRS485(command_SV15);
delay(_DELAY_MSEC);
}
else if(data.at(5) == 0x01)
{
FuelPump_stop();

command_HV14.append(FUEL_SYSTEM);
command_HV14.append(DSLFL_HT_SV_14);
command_HV14.append((char) 0x00);

emit DSLFL_SendToRS485(command_HV14);
delay(_DELAY_MSEC);
}

if((data.at(6) == 0x01) && (pumpStat == OFF))
{
command_FTWL_SV9.append(FUEL_SYSTEM);
command_FTWL_SV9.append(DSLFLWaterEvacuate_SV_9);
command_FTWL_SV9.append(0x01);

emit DSLFL_SendToRS485(command_FTWL_SV9);
delay(_DELAY_MSEC);

waterEvacuateTimer->start();
}
}
}

void FuelSystem::delay(int msec){
QEventLoop loop;
QTimer::singleShot(msec, &loop, NULL);
loop.exec();
}



As I send a packet to PLC, I need to delay for some time, waiting for the result of PLC operations. Here, I cannot use sleep() as it is a system call and it will suspend all other
QTimers and the whole program. what I want is to only delay the current particular thread or object for 2 seconds everytime I connect to PLC.

I hope this is clear now. : )

amleto
10th June 2012, 12:15
so you are just dealing with asynch io. This is not new problem and isn't solved best with blocking calls. Where is your code that you say 'needs to wait'?

wysota
10th June 2012, 20:42
sleep() suspends all running threads or timers. I don't want that, I only want to delay one particular thread.

Sleep doesn't suspend any timers, those are handled by the operating system. Sleep suspends a thread. I have no idea why you want to delay anything at the places you marked in your code. Just put each if in a separate slot and upon ending one slot, start a timer to trigger the next one.

amleto
11th June 2012, 00:36
should he even be using timers? Looks like the code should be moved into slots, and called by something that is signalled when new data arrives.

wysota
11th June 2012, 08:48
should he even be using timers?
Probably not.

Looks like the code should be moved into slots, and called by something that is signalled when new data arrives.
That's right, provided he has some ability to be informed of data arrival.

saman_artorious
11th June 2012, 09:04
for example, if I want to command a valve to open via PLC. or let's say I want to switch on a pump, I need to delay for quite a small period of time, waiting for that valve to open in reality.
then check via proximity switches whether it really got open or not after 2 seconds for example. That's why I need to delay for two seconds and the carry on with the rest of the instructions in that particular thread.
if sleep() suspends threads then it's not a good idea to thread, I may use it in the above code to delay that thread, but it suspends all other threads as well.

I have also used singleShot using SLOT, but in some cases I don not want to execute any SLOTS, just delaying for two sec.
I think everything's now clear for you all. : )

wysota
11th June 2012, 10:11
then check via proximity switches whether it really got open or not after 2 seconds for example.
And if not?


if sleep() suspends threads then it's not a good idea to thread,
???


I may use it in the above code to delay that thread, but it suspends all other threads as well.
Maybe you don't have other threads...


I have also used singleShot using SLOT, but in some cases I don not want to execute any SLOTS, just delaying for two sec.
Delay what?

Usually if you want to delay something then you want this something to happen after that delay and not that you don't want anything to happen after that period of time.

I'm leaning more and more to an opinion that you either have some misconception or misdesign in your program. To be honest, blocking anything in a reactive system such as one controlling some pump that can flood something seems to be a mistake on its own.

kuroi_neko
12th June 2012, 04:07
Just my two cents: have you considered using a QSemaphore::tryAcquire() with timeout ?

QSemaphore blocker;
blocker.tryAcquire (1, delay);That would block the calling thread and only it, with no interference with other threads, timers or whatever.
Of course the thread would be dead to the outer world during the wait, so the GUI would better have to run somewhere else.

As for polling an asynchronous device, I would suggest to create a dedicated thread instead of blocking the one issuing the command. But that's answering a question you did not ask, so...