PDA

View Full Version : MainThread and QThread



Qiieha
21st May 2012, 16:56
Hi,
I have a MainWindow with a QTabWidget and a QPlainTextEdit. If I click on a button an Object is created and a Thread. The Object is moved to the thread and some signals and slots get connected:


BaseExport* creator = new BaseExport(NULL);
MyThread* mthread = new MyThread(NULL);

creator->moveToThread(mthread);

connect(creator,SIGNAL(new_status(QString)),this,S LOT(status_received(QString)),Qt::QueuedConnection );
connect(creator,SIGNAL(finished()),ui->progressBar,SLOT(hide()),Qt::QueuedConnection);
connect(creator,SIGNAL(finished()),creator,SLOT(de leteLater()),Qt::QueuedConnection);
connect(creator,SIGNAL(error(QString)),this,SLOT(e rror_received(QString)),Qt::QueuedConnection);
connect(creator,SIGNAL(more_than_one_result(QList<QList<SetField *> *> *)),this,SLOT(more_than_one_result_slot(QList<QList<MatchingSetField*>*>*)),Qt::QueuedConnection);
connect(this,SIGNAL(decided(QList<SetField*>*)),creator,SLOT(decided_slot(QList<SetField*>*)),Qt::QueuedConnection);
creator->connect(mthread,SIGNAL(started()),SLOT(create()));
connect(creator,SIGNAL(finished()),mthread,SLOT(qu it()));
connect(mthread,SIGNAL(finished()),mthread,SLOT(de leteLater()));

mthread->start();



Everything works fine. The create Slot of my Object starts and do some work. The signals (new_status, error) are received and the guithread shows the status and the errors.
It works to the point where the creator object in the thread need some information from the user. The object emits the signal more_than_one_result(). The receiving slot opens a QDialog with a table, which shows the results.
After choosing a result, the Mainthread emits the signal decided and sends a QList back to the thread.

The thread waits for the response in an QEventLoop waitloop;
In the slot decided_slot the waitloop ends with the call waitloop.quit(). And there sometimes occurs the error:


QPixmap: It is not safe to use pixmaps outside the GUI thread
QPixmap: It is not safe to use pixmaps outside the GUI thread


and the app crashes.
What's wrong? Maybe somebody can give me a hint. Thank u

^NyAw^
21st May 2012, 17:36
It seems that you are accessing GUI elements into the thread.

Qiieha
21st May 2012, 18:28
Thank u for your help.
No I don't access gui elements. In Guithread a method sorts out the QList after that the signal decided(QList<Object*>*) is emitted.

amleto
21st May 2012, 19:01
"No I don't access gui elements. In Guithread a method sorts out the QList after that the signal decided(QList<Object*>*) is emitted."

Qt disagrees with you ;)


It might help if you showed all code related to qpixmap. Including where they are passed around through QObject/QWidget pointers.

Qiieha
21st May 2012, 19:11
I don't use qpixmap in the application.

this is the method, where signal is emitted:


void IntWidget::more_than_one_result_slot(QList<QList<SetField *> *> *result_list)
{
qDebug() << "IntWidget::more_than_one_result_slot(QList<QList<SetField *> *> *result_list)";
qDebug() << this->thread();
DecideDlg dlg(this,result_list);
dlg.exec();
QList<MatchingSetField*>* chosen_list = dlg.getChosenList();
//emit the signal. the slot is in Thread
emit decided(chosen_list);
}

this is the slot


void BaseExport::decided_slot(QList<SetField *> *decide_list)
{
qDebug() << "BaseExport::decided_slot(QList<SetField *> *decide_list)";
for(int i = 0; i < decide_list->size(); i++){
SetField* decided_setfield = decide_list->value(i);
Set* current_set = sets->value(decided_setfield->getMsId());
SetField* origin_setfield = current_set->getSetFields()->value(decided_setfield->getId());
origin_setfield->setResult_Value(decided_setfield->getResult_Value());
delete decided_setfield;
}
delete decide_list;
waitloop.quit();
}

Qiieha
22nd May 2012, 08:27
The behaviour above occurs at a Dual Core Processor. On a single Core Processor the slot of the Object in the Thread is never executed.

Nobody has an Idea?

amleto
22nd May 2012, 10:45
what is the class def for SetField?


your single core problem is probably due to your 'wait loop' / misuse of event loops / whatever other blocking tactics you use.

Qiieha
22nd May 2012, 11:42
class SetField
{
private:
int id;
int reg_id;
int foo_id;
QString cast;
int field;

public:
SetField(int id, int reg_id, int foo_id, QString cast, int field);
~SetField();

//setter
//getter
};


Ok, then it is probably a misuse of QEventLoop. The Thread should wait for the response. What technic I should use?

Added after 41 minutes:

I solved the Problem!
It was a misuse of QEventLoop. BlockingQueuedConnection solved the Problem. QEventLoop is unnecessary in this case....

amleto
22nd May 2012, 12:54
"Ok, then it is probably a misuse of QEventLoop. The Thread should wait for the response. What technic I should use?"
signal/slot queued connection