Have you tried QObject::setObjectName() and QObject::dumpObjectInfo() to debug/monitor the active connections?
Anyways, a small self-contained example to reproduce the problem would be nice.
Have you tried QObject::setObjectName() and QObject::dumpObjectInfo() to debug/monitor the active connections?
Anyways, a small self-contained example to reproduce the problem would be nice.
Answer: no, no
It is part of a 15000 lines program system, I'll try to build a small system with the observed
behaviour
best
janK
I was just constructing a small subset of my program when I realized that "Processor" as mentioned in my first description is a running thread.
So Gui is the gui, Processor a separately running thread and backend just an object instantiated in the processor.
Is it possible/safe to connect from within backend
connect (MyGui, SIGNAL (...), this, SLOT (...)),
then
disconnect (MyGui, SIGNAL (...), this, SLOT (...))
and then reapply connect (MyGui, SIGNAL (...), this, SLOT (...))
again from an object, instantiated from a thread (Processor)?
Where Processor contains code like
if (cond) {
delete MyBackend;
MyBackend = new Backend (...)
}
best jan
It took me some time isolating the relevant parts.
The detector is an object, depending on parameter settings (omitted here), created and recreated. On recreation it attempts to connect itself to the GUI (MyRadioInterface), on destruction it disconnects
#
#include "gui.h"
#include "detector.h"
void Detector::test (int n) {
fprintf (stderr, "int is %d\n", n);
}
Detector:etector (RadioInterface *RI) {
int t;
_WorkingRate = 9600;
MyRadioInterface = RI;
t = connect (MyRadioInterface, SIGNAL (setting_Balance (int)),
this, SLOT (test (int)));
fprintf (stderr, "creating new detector, connect yields %d\n", t);
}
Detector::~Detector () {
disconnect (MyRadioInterface, SIGNAL (setting_Balance (int)),
this, SLOT (test (int)));
}
complex Detector:rocessSample (complex sample) {
return complex (0, 0);
}
The main processor of the radio instantiates (a.o.) the detector
#include "gui.h"
#include "doradio.h"
#define WILL_START 01012
#define RUNNING 01013
#define WILL_EXIT 01014
#define NONE 01111
#define SET_NEW_WORKING_RATE 01001
extern complex ComplexZero;
doRadio::doRadio (RadioInterface *RI) {
MyRadioInterface = RI;
_WorkingRate = 9600;
ModeofOperation = WILL_START;
ChangeComponent = NONE;
connect (RI, SIGNAL (setting_Halt (void)), this, SLOT (setHalt (void)));
connect (RI, SIGNAL (setting_WorkingRate (int)), this, SLOT (setWorkingRate (int)));
MyDetector = new Detector (MyRadioInterface);
}
doRadio::~doRadio () {
}
void doRadio::setHalt () {
ModeofOperation = WILL_EXIT;
}
void doRadio::setWorkingRate (int wr) {
_WorkingRate = wr;
ChangeComponent = SET_NEW_WORKING_RATE;
}
/*
* The actual process
*/
void doRadio::run () {
complex sample;
int ExitCondition = 0;
while (!ExitCondition) {
switch (ChangeComponent) {
case SET_NEW_WORKING_RATE:
delete MyDetector; //THIS LINE AFFECTS BEHAVIOUR
MyDetector = new Detector (MyRadioInterface);
ChangeComponent = NONE;
break;
default:
break;
}
switch (ModeofOperation) {
case WILL_START:
ModeofOperation = RUNNING;
break;
case WILL_EXIT:
ExitCondition = 1; // exit the loop and die
break;
case RUNNING:
sleep (10);
sample = MyDetector -> processSample (ComplexZero);
break;
}
}
}
I just connected the detector object with something on my gui (a slider here),
when given as above, the decoder reports "1" as result of the connection, however
moving the slider does not result in a signal sent (only the first time)
When commented out the line
delete MyDetector
I can send signals "setWorkingRate" here and the decoder not only
reports "1" as result of the connection, but the gui slider is effectively connected
to the "test" method, and lots of numbers will be printed
Anyone with some idea???
(or formulated differently: help urgently needed)
best jan
You construct the first Detector in the constructor of your thread class. That means, this object is part of the main thread because your thread (doRadio) is not started yet.
Then you delete the detector from the running thread (doRadio) where the detector object belongs to the main thread. After that, you construct a new detector in the doRadio thread (So the new object belongs to the doRadio thread).
Qt distinguish between queued connection and normal connection. Queued connection will work between threads, normal won't. If you do not specify a connection type while connecting (like you did), the connection type will be auto. In this case Qt uses QueuedConnection between different threads. So far...
After the delete, you will get a QueuedConnection. This means, your thread needs to dispatch events in your run method to process the signals from the main thread. But you do not dispatch the event with an event loop. You have to call QThread::exec in doRadio::run() to use the threads event loop or you can create your own event loop, cause QThread::exec() will only return after exit() called. That would be hard to bring together with your while loop.![]()
janK (24th August 2010)
OK, I see the point. The good thing is to realize that it is indeed my code that is erroneous, the bad news
is that I have to think really hard for a good solution, I'll study on Queued Connections.
Thanks a lot
best jan
Hi Jan,
I forget to tell you. You can try to move the object with moveToThread(QThread* targetThread) to your main thread before you do the connect. Not perfect but should work.
Actually, I changed the program such that the detector object is created
and managed by the main thread.
Thanks anyway for the suggestion, I do realize that I still have to learn a lot
on the details of Qt
Thanks for your efforts, appreciated
best jan
Bookmarks