задача такая, нужно создать несколько потоков, в частности 3, причем чтобы из первого потока запускался второй, из второго третий, а в третьем производились вычисления.
информацию о состоянии вычислений третьего потока нужно вывести на progressBar формы.
я использую сигнально слотовые соединения т.е
запускаю первый поток:
void MainWindow::on_pushButton_clicked()
{
ThMain_1 *MAIN_1 = new ThMain_1;
MAIN_1->start();
connect(MAIN_1,SIGNAL(progress_th_2(int)),this,SLOT(on_progressBar_2_valueChanged(int)));
}
void MainWindow::on_progressBar_2_valueChanged(int value)
{
ui->progressBar_2->setValue(value);
}
запускаю второй поток:
void ThMain_1::run()
{
ThSub_1 *THSUB_1 = new ThSub_1;
THSUB_1->start();
connect(THSUB_1,SIGNAL(progress_th_2(int)),this,SLOT(SetProgress_th_2(int)));
}
void ThMain_1::SetProgress_th_2(int progress)
{
emit progress_th_2(progress);
}
void ThSub_1::run()
{
th_2 *TH_2 = new th_2;
TH_2->start();
connect(TH_2,SIGNAL(progress_2(int)),this,SLOT(SetProgress_th_2(int)))
}
void ThSub_1::SetProgress_th_2(int progress)
{
emit progress_th_2(progress);
}
void th_2::run()
{
int __progress=0;
double _result=0;
for (int i=0; i<=199800; i++)
{
_result+=cos(atan(i));
if (i%1998==0)
{
emit progress_2(++__progress);
}
}
}
connect(THSUB_1,SIGNAL(progress_th_2(int)),this,SLOT(SetProgress_th_2(int)));
...
void ThMain_1::SetProgress_th_2(int progress)
{
emit progress_th_2(progress);
}
TH_2->start();
connect(TH_2,SIGNAL(progress_2(int)),this,SLOT(SetProgress_th_2(int)))
Спасибо за совет, я переделал немного код, в результате получилось
void MainWindow::on_pushButton_clicked()
{
ThMain_1 *MAIN_1 = new ThMain_1;
connect(MAIN_1,SIGNAL(progress(int)),this,SLOT(on_progressBar_valueChanged(int)));
MAIN_1->start();
}
void MainWindow::on_progressBar_valueChanged(int value)
{
ui->progressBar->setValue(value);
}
//2
void ThMain_1::run()
{
ThSub_1 *THSUB_1 = new ThSub_1;
connect(THSUB_1,SIGNAL(progress(int)),this,SIGNAL(progress(int)));
THSUB_1->start();
}
//3
void ThSub_1::run()
{
Th_1 *TH_1 = new Th_1;
connect(TH_1,SIGNAL(progress(int)),this,SIGNAL(progress(int)));
TH_1->start();
}
//вычисления (для теста полставил вместо вычислений)
void Th_1::run()
{
for (int i=1; i<=100; i++)
{
sleep(1);
emit progress(i);
}
}
можно проверить что возвращает connect во всех случаях соединения.
в консоль предупреждения не сыпятся во время выполнения программы?
я не спец в QT, но есть предположение, что внутри обработки сигнала повторный вызов этого же сигнала просто "гасится". то есть, функция
void ThMain_1::SetProgress_th_2(int progress)
{
emit progress_th_2(progress);
}
Нет, в консоли отладки никаких сообщний нет, но вот что я приметил: выставив точки останова при отладке, получается так, что сигнал из
void Th_1::run()
{
for (int i=1; i<=100; i++)
{
sleep(1);
emit progress(100);
}
}
void ThSub_1::SetProgress_th_2(int progress)
{
emit progress_th_2(progress);
}
читай про реализацию QT сигналов в многопоточных приложениях и проверяй области видимости. может, у тебя process банально разрушается до того момента, как его успеют вызвать, или ещё где-то какие-нибудь локальные переменные задействованы.
Привет.
Ваша проблема в том, что все вызовы connect связывают сигналы и слоты объектов, находящихся в одном потоке ( да, сам объект потока находится в том потоке, в котором он был создан ) и это вызывает соединение типа Qt::DirectConnection, а не желаемое Вам Qt::QueuedConnection.
Для того, чтобы реализовать желаемое поведение можно поступить следующим образом ( рассмотрим простейший случай - два потока ).
1. Создать дочерний поток (ДП).
2. Создать в дочернем потоке объект с сигналом "прогресс".
3. Связать сигнал дочернего потока "прогресс" с сигналом созданного объекта "прогресс".
4. Связать сигнал объекта со слотом главного потока.
5. Вызывать сигнал ДП.
Для дважды дочерний потока ( ДДП ) аналогично создается объект, он связывается с сигналом ДДП, а затем с сигналом ДП, он вызовет свой объект, который свяжется с главным потоком асинхронно.
void MainWindow::on_pushButton_clicked()
{
ThMain_1 *MAIN_1 = new ThMain_1;
connect(MAIN_1,SIGNAL(progress(int)),this,SLOT(on_progressBar_valueChanged(int)));
MAIN_1->start();
}
void MainWindow::on_progressBar_valueChanged(int value)
{
ui->progressBar->setValue(value);
}
//2
void ThMain_1::run()
{
ThSub_1 *THSUB_1 = new ThSub_1;
connect(THSUB_1,SIGNAL(progress(int)),this,SIGNAL(progress(int)));
THSUB_1->start();
}
//3
void ThSub_1::run()
{
Th_1 *TH_1 = new Th_1;
connect(TH_1,SIGNAL(progress(int)),this,SIGNAL(progress(int)));
TH_1->start();
}
//вычисления (для теста полставил вместо вычислений)
void Th_1::run()
{
for (int i=1; i<=100; i++)
{
sleep(1);
emit progress(i);
}
}
Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)