Qt minuteries ne peut pas être arrêté à partir d'un autre thread
Hy,
Je suis en train d'écrire mon premier Qt programme et d'obtenir maintenant des ennuis avec:
QObject::killTimer: minuteries ne peut pas être arrêté à partir d'un autre thread
QObject::startTimer: minuteries ne peut pas être démarré à partir d'un autre thread
Mon programme va communiquer à un CANOpen bus pour que je suis en utilisant le Canfestival Pile. Le Canfestival va travailler avec des méthodes de rappel. Pour détecte un délai d'attente dans la communication-je configurer une fonction de minuterie (en quelque sorte comme un chien de garde). Mon timer package comprend un "tmr" module "TimerForFWUpgrade module" et un "SingleTimer" module. Le "tmr" module a été à l'origine C programmé de sorte que le statique "TimerForFWUpgrade" méthodes de l'interface. Le "tmr" module fera partie d'un C programmé forfait mise à jour Firmware.
La minuterie fonctionne comme suit. Avant d'envoyer un message je vais appeler TMR_Set méthode. Puis dans mon programme inactif boucle avec TMR_IsElapsed nous vérifier une minuterie de dépassement de capacité. Si TMR_IsElapsed je vais faire la errorhandling. Comme vous le voyez le TMR_Set méthode sera appelée en continu et redémarrez le QTimer encore et encore.
Ci-dessus a relevé des erreurs apparaissent, si je commence mon programme. Pouvez-vous me dire si mon idée pourrait fonctionner? Pourquoi est-ce que les erreurs apparaissent? Dois-je utiliser des threads supplémentaires (QThread) pour le thread principal?
Merci
Matt
Exécuter et boucle d'Inactivité:
void run
{
//start communicate with callbacks where TMR_Set is set continously
...
while(TMR_IsElapsed(TMR_NBR_CFU) != 1);
//if TMR_IsElapsed check for errorhandling
....
}
Module de tmr (interface de programme C):
extern "C"
{
void TMR_Set(UINT8 tmrnbr, UINT32 time)
{
TimerForFWUpgrade::set(tmrnbr, time);
}
INT8 TMR_IsElapsed(UINT8 tmrnbr)
{
return TimerForFWUpgrade::isElapsed(tmrnbr);
}
}
Module TimerForFWUpgrade:
SingleTimer* TimerForFWUpgrade::singleTimer[NR_OF_TIMERS];
TimerForFWUpgrade::TimerForFWUpgrade(QObject* parent)
{
for(unsigned char i = 0; i < NR_OF_TIMERS; i++)
{
singleTimer[i] = new SingleTimer(parent);
}
}
//static
void TimerForFWUpgrade::set(unsigned char tmrnbr, unsigned int time)
{
if(tmrnbr < NR_OF_TIMERS)
{
time *= TimerForFWUpgrade::timeBase;
singleTimer[tmrnbr]->set(time);
}
}
//static
char TimerForFWUpgrade::isElapsed(unsigned char tmrnbr)
{
if(true == singleTimer[tmrnbr]->isElapsed())
{
return 1;
}
else
{
return 0;
}
}
Module SingleTimer:
SingleTimer::SingleTimer(QObject* parent) : QObject(parent),
pTime(new QTimer(this)),
myElapsed(true)
{
connect(pTime, SIGNAL(timeout()), this, SLOT(slot_setElapsed()));
pTime->setTimerType(Qt::PreciseTimer);
pTime->setSingleShot(true);
}
void SingleTimer::set(unsigned int time)
{
myElapsed = false;
pTime->start(time);
}
bool SingleTimer::isElapsed()
{
QCoreApplication::processEvents();
return myElapsed;
}
void SingleTimer::slot_setElapsed()
{
myElapsed = true;
}
QTimer
classe?le corps de
isElapsed()
est tellement mauvais.Pouvez-vous me donner plus d'informations? Ce qui est mauvais dans le corps de isElapsed? Merci
J'utilise le QTimer classe. Mais je ne peux pas l'utiliser directement ou peut-être vous pouvez me dire comment...
Pourquoi vous ne pouvez pas l'utiliser directement? Pourriez-vous montrer vos tentatives?
OriginalL'auteur Matt | 2014-10-20
Vous devez vous connecter pour publier un commentaire.
Utilisation
QTimer
à cet effet et de faire usage deSIGNALS
etSLOT
dans le but de démarrage et d'arrêt de la minuterie/s à partir de différents threads. Vous pouvez émettre le signal à partir de n'importe quel thread et de l'attraper dans le thread qui a créé la minuterie d'agir sur elle.Puisque vous dites que vous êtes nouveau à Qt, je vous suggère d'aller à travers des tutoriels avant de procéder afin que vous sachiez ce que Qt a à offrir, et de ne pas essayer de réinventer la roue. 🙂
VoidRealms est un bon point de départ.
OriginalL'auteur nnb
Vous avez ce problème, car les compteurs à zéro dans le tableau statique est créé dans
Thread X
, mais a commencé et s'est arrêté dansThread Y
. Ce n'est pas permis, parce que Qt s'appuyer sur l'affinité des threads en attente des chronomètres.Vous pouvez soit créer, start stop dans le même thread ou l'utilisation de signaux et de slots pour déclencher
start
etstop
opérations pour le timer. Le signal et le slot de la solution est un peu problématique Parce que vous avezn
QTimer objets (Astuce: comment faire pour démarrer la minuterie à la positioni
?)Ce que vous pouvez faire à la place est de créer et d'initialiser la minuterie à la position
tmrnbr
dansqui est exécuté par le même thread.
D'ailleurs, vous n'avez pas besoin d'un
SingleTimer
classe. Vous êtes à l'aide de Qt5, et vous avez déjà tout ce que vous devez à votre disposition:SingleTimer::isElapsed
est vraimentQTimer::remainingTime() == 0
;SingleTimer::set
est vraimentQTimer::setSingleShot(true); QTimer::start(time);
SingleTimer::slot_setElapsed
devient inutileSingleTimer::SingleTimer
devient inutile et que vous n'avez pas besoin d'unSingleTimer
classe plusOriginalL'auteur UmNyobe
J'ai eu les erreurs de suite après changement de mon timer concept. Je'dont utilisation plus mon SingleTimer module. Avant le QTimer je ne laisserai pas de délai d'attente et peut-être à cause de cela, j'ai des problèmes. Maintenant, j'ai un cyclique QTimer que les temps chaque 100ms dans le logement de fonction je puis compter les événements. Ci-dessous mon code de travail:
OriginalL'auteur Matt