Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: многопоточность QThread
Форум на CrossPlatform.RU > Библиотеки > Qt > Qt Ввод/Вывод, Сеть. Межпроцессное взаимодействие
Страницы: 1, 2
eldar85
пробую написать простенькую многопоточную программку, но она выдает сообщение об ошибке

ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 22fe34. Receiver '' (of type 'QProgressBar') was created in thread 5d70b8", file kernel\qcoreapplication.cpp, line 347
Invalid parameter passed to C runtime function.
Invalid parameter passed to C runtime function.
ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 22fe28. Receiver '' (of type 'QProgressBar') was created in thread 5d70b8", file kernel\qcoreapplication.cpp, line 347
Invalid parameter passed to C runtime function.
Invalid parameter passed to C runtime function.

вот пример кода

#include <QApplication>
#include <QLabel>
#include <QtGui>

#include "thread.h"



int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
  
    QProgressBar *bar1 = new QProgressBar;
    QProgressBar *bar2 = new QProgressBar;
    
   MyThread thread1(bar1);
   MyThread thread2(bar2);
   thread1.start(QThread::NormalPriority);
   thread2.start(QThread::LowPriority);

    
bar1->show();
bar2->show();
    return app.exec();
}


thread.h

#ifndef THREAD_H
#define THREAD_H
#include <qapplication.h>
#include <qthread.h>
#include <qprogressbar.h>
#include <qgridlayout.h>
#include <qlabel.h>

// ======================================================================
class MyThread : public QThread {
    QProgressBar* m_pprb;

public:
    MyThread(QProgressBar* pprb) : QThread()
                                 , m_pprb(pprb)
    {
    }

    void run()
    {
        for(int i = 0; i <= 100000000; ++i) {
            m_pprb->setValue(i / 1000000);
        }
    }
};


#endif // THREAD_H


ну и про файл

SOURCES += main.cpp
CONFIG        += qt warn_on release thread
TARGET        = Threads
TEMPLATE    = app
HEADERS += thread.h


окно выскакивает с такой ошибкой:
this applicatoin has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

правда в книге вот эта строка
m_pprb->setValue(i / 1000000);

выглядела так:
m_pprb->setProgress(i / 1000000);

но setProgress не существует, похоже она была чем то заменена))
eldar85
капец, разобрался почему не работает))))
у меня в файле про указано
CONFIG        += qt warn_on release thread

а я компилил в дебаге)))
eldar85
хоть программа и работает, но все же примерно через раз вылетает, предлогая закрыть программу...
в чем может быть проблема?)
fsMark
Цитата(eldar85 @ 12.4.2010, 16:21) *
хоть программа и работает, но все же примерно через раз вылетает, предлогая закрыть программу...
в чем может быть проблема?)



Все операции с GUI надо выполнять в основном потоке, в твоем случае дополнительный поток например может слать сигнал прогресбару находящемуся в основном потоке.
eldar85
так в GUI не катит многопоточность??? а если второй поток будет выполняться выводя на экран уже в по окончанию работы ??? так нормально будет?
Litkevich Yuriy
Цитата(eldar85 @ 12.4.2010, 21:10) *
так в GUI не катит многопоточность???
Цитата(eldar85 @ 12.4.2010, 21:10) *
выводя на экран
выод на экран - рисование

подробности тут: Рисование в потоках
Ну а графический интерфейс, он нарисован.
eldar85
спасибо) буду изучать и пробывать))
eldar85
мне вот интересно, а сколько потоков допустимо за раз запускать, чтобы комп не начинал пыхтеть как ошпаренный?))
SABROG
Цитата(eldar85 @ 16.4.2010, 22:39) *
мне вот интересно, а сколько потоков допустимо за раз запускать, чтобы комп не начинал пыхтеть как ошпаренный?))


По количеству ядер на проце. Выше этого числа уже прироста не будет никакого, только бесполезная трата оперативки и расходы на переключение между потоками.
eldar85
т.е. если у меня двух ядерник, то лучше всего не более двух потоков использовать, я правельно понял?)))
ufna
Цитата(SABROG @ 16.4.2010, 22:56) *
По количеству ядер на проце. Выше этого числа уже прироста не будет никакого, только бесполезная трата оперативки и расходы на переключение между потоками.


Ну не согласен. "Вторые" и следующие потоки должны выполнять свои действия параллельно, чтобы не тормозить отрисовку. Как реализовать нормальное действие, когда нужно параллельно, чтобы для юзера это никак не сказывалось:

- провести отрисовку несколько десятков изображений
- просчитать маршрут по карте
- считать и обработать данные с устройства с четко заданным интервалом и вести контроль местоположения на карте

при этом общее устройство - это PNA?
eldar85
мне бы нужно хотябы два-три потока сделать, но опять же чтобы не напрягало систему до безпредела)) но почему то все советуют, что если нет крайней необходимости во многопоточности, то ее вообще лучше изключить)) но мне бы все же хотелось чтобы моя прога была многопоточная - это интереснее будет думаю)) мне нужна скорость высокая выполнения, допустим прога должна провести за один запуск 100 циклов с целой кучей всякой хрени в них, так вот, будет бустрее если она будет выполняться в нескольких потоках или в одном?)
Litkevich Yuriy
Цитата(eldar85 @ 18.4.2010, 20:53) *
будет бустрее если она будет выполняться в нескольких потоках или в одном?)
если процессор один (одноядерный), то всё равно все процессы в нём выполняются последовательно. Т.е. многопоточность не увеличивает скорость. А так как ОСьке придётся ещё и переключать потоки, то будет медленнее, чем в один поток
ufna
да, именно так. Когда обработка идет "надо сделать все", то количество потоков увеличивать имеет смысл только в н-ядерных процессорах, либо "чтобы не вешало GUI".
eldar85
понятно, спасибо))
я просто чем был удивлен, скачал тут недавно программу прокси-чекер, так она 15 потоков сразу использует))) причем работает достаточно быстренько - а у меня двух ядерный бук 2,2Ггрц и оперативки 3гбайт.
а я попробывал на кьюти написать самый простенький пример из трех потоков, как комп начал вешаться, вентилятор на проце дико заревел аж))))))
eldar85
здравствуйте, еще раз решил поднять тему многопоточности. по моему то что я сделал не многопоточно работает, такое ощущение что в один поток все бахает.

вот класс потока:
class Thread : public QThread
{
    Q_OBJECT
public:
  Thread()
  {
  }



  void run(int i);


};




#endif // THREADS_H


вот описание функции run();

void Thread::run(int i)
{

QString sait = list[i];  \\"http://google.ru", "http://ya.ru", "http://mail.ru", "http://google.ru" и так далее

        curl->load(sait)->exec(); //Это загрузка гугла через курл





finished();

}



int mainWindow::Start()
{
  

a = list.length();
Thread thread;

    for(int i=0; i<a; i++)
    {



    thread.run(i);
    thread.start();
  

    }


    return 0;
}






особенно мне не нравится вот эта надпись в консоли - QThread: Destroyed while thread is still running
вроде все что должен выполнил(все страницы загрузил), а в консоль вывел эту шнягу. подскажите пожалуйста что не так...
и главное страицы загружаются все равно как то по очереди... я правильно запускаю потоки в цикле или нет?
SABROG
thread.run(i);


Нельзя так запускать поток, метод run() только для переопределения.
eldar85
а как можно?)
я вот сделал вот так сейчас
void mainWindow::Start()
{
Thread thread;
list1 << "1" << "2" << "3"<< "4" << "5" << "6"<< "7" << "8" << "9"<< "10" << "11" << "12"<< "13" << "14" << "15";
list2 << "101" << "102" << "103"<< "104" << "105" << "106"<< "107" << "108" << "109"<< "110" << "111" << "112"<< "113" << "114" << "115";
QString q1;
QString q2;
        for(int i=0; i<14; i++)
{
q1 = list1[i];
q2 = list2[i];

    thread.run(q1, q2);
    thread.start();
}


}

void Thread::run(QString str1, QString str2)
{
       qDebug() << str1 << str2;
}

прога то нормально все завершит, то вылетает.
и в консоли всегда вот это - QThread: Destroyed while thread is still running

если все что делается в потоках должно делаться в функции run(); то как же в нее передать параметры которые я в главном окне получаю, те что введены в текстовое поле???

и вот так тоже вылетает
void mainWindow::Start()
{
Thread thread;
list1 << "1" << "2" << "3"<< "4" << "5" << "6"<< "7" << "8" << "9"<< "10" << "11" << "12"<< "13" << "14" << "15";
list2 << "101" << "102" << "103"<< "104" << "105" << "106"<< "107" << "108" << "109"<< "110" << "111" << "112"<< "113" << "114" << "115";

        for(int i=0; i<14; i++)
{
q1 = list1[i];
q2 = list2[i];

    thread.run();
    thread.start();
}


}

void Thread::run()
{
       makeFunktion(q1, q2);
}

void Thread::makeFunktion(QString str1, QString str2)
{
        qDebug() << str1 << str2;
}


как же мне тогда соединить slot Start() с кнопки на окне приложения и run()?????? уже даже эти переменные
QString q1;
QString q2;
QStringList list1;
QStringList list2;
как глобальные переменные и вылетает все равно. что не так??? может как то потоки нужно контралировать??

ставлю ожидание небольшое то не вылетает, но почему то в консоль все в двух экземплярах выводит
        for(int i=0; i<14; i++)
{
q1 = list1[i];
q2 = list2[i];

    thread.run();
    thread.start();
    Sleep(100);

}




"1" "101"
"1" "101"
"2" "102"
"2" "102"
"3" "103"
"3" "103"
"4" "104"
"4" "104"
"5" "105"
"5" "105"
"6" "106"
"6" "106"
"7" "107"
"7" "107"
"8" "108"
"8" "108"
"9" "109"
"9" "109"
"10" "110"
"10" "110"
"11" "111"
"11" "111"
"12" "112"
"12" "112"
"13" "113"
"13" "113"
"14" "114"
"14" "114"

зато вот эта хрень пропала из консоли QThread: Destroyed while thread is still running

и вообще такое ощущение что все в один поток работает, если я ставлю в функцию nakeFunktion() ожидание в пару секунд, то каждый вывод в консоли как раз и происходит каждые 2 секунды, но потоки же должны работать в одно время или почти в одно и вывод должен происходить быстрее... по моему я не так вызываю потоки...
Litkevich Yuriy
eldar85, ты должен вызывать только Thread::start(). Он, в свою очередь, вызывает run()
Под "переопределить метод" понимается, создать в наследнике точно такую же функцию, не изменяя её сигнатуры (имени и типа аргументов)
eldar85
но мне нужно чтобы каждый поток работал с функцией makeFunktion(QString q1, QString q2) ; но с разными переменными, например мне нужно передать в функцию makeFunktion(QString q1, QString q2) ; два параметра, но в каждом потоке они должны быть разными. значит run() вызывать вообще не нужно, хммм))) ок, буду пробывать, потому что так как я сделал прога вылетает))) спасибо за совет, попробую отпишусь)

но в метод run()
{
//я же могу что угодно накидать для выполнения? правильно?
}

а я правильно в цикле потоки вызываю если оттуда метод run() убрать из цикла? или каждый поток должен называться по разному???
 for(int i=0; i<8; i++)
{



    thread.start();


    

}



я хочу сделать чтобы с главного окна можно было в спинбоксе поставить сколько потоков будет работать. и соответственно не могу каждый поток подписать так:
Thread thread1;
Thread thread2;
Thread thread3;
......
потому что точно не знаю сколько поставлю потоков, возможно захочу 2, а возможно 10...
ну это так к слову, мне бы научиться их вызывать, весь гугл перерыл, но кругом описано как сделать две кнопки и чтобы нажал одну пошел первый поток, нажал вторую пошел второй поток... мне нужно в цикле их запускать ...

попробывал не вызывать метод run() прога тут же вылетает.
void mainWindow::Start()
{
Thread thread;
list1 << "1" << "2" << "3"<< "4" << "5" << "6"<< "7" << "8" << "9"<< "10" << "11" << "12"<< "13" << "14" << "15";
list2 << "101" << "102" << "103"<< "104" << "105" << "106"<< "107" << "108" << "109"<< "110" << "111" << "112"<< "113" << "114" << "115";


        for(int i=0; i<5; i++)
{
          
    thread.start();

}


}

void Thread::run()
{
       makeFunktion(q1, q2);


}

void Thread::makeFunktion(QString str1, QString str2)
{

  
  Sleep(1000);
  qDebug() << q1 << q2;
      
}

ставлю ожидание в секунду, так как при выполнении операций там и больше могут задержки быть, и сразу вылетает.
Litkevich Yuriy
Цитата(eldar85 @ 11.6.2010, 5:16) *
//я же могу что угодно накидать для выполнения? правильно?
именно для этого он и сделан. Собственно говоря, он-то и выполняется в другом потоке.
eldar85
все равно что то не то получается... если я запускаю в цикле запуск потоков, то (на мой взгляд судя по сообщению в консоли QThread: Destroyed while thread is still running запускаетс один и тот же поток столько раз сколько я поставил в цикле
) происходит вылет программы и выводится результат лишь последнего потока.
void mainWindow::Start()
{
Thread thread;
list1 << "1" << "2" << "3"<< "4" << "5" << "6"<< "7" << "8" << "9"<< "10" << "11" << "12"<< "13" << "14" << "15";
list2 << "101" << "102" << "103"<< "104" << "105" << "106"<< "107" << "108" << "109"<< "110" << "111" << "112"<< "113" << "114" << "115";
q3 = text1->toPlainText();
qDebug() << q3;
        for(int i=0; i<5; i++)
{
            q1 = list1[i];
            q2 = list2[i];

    thread.start();

}
text->append(q3);

}

void Thread::run()
{
       makeFunktion(q1, q2);


}

void Thread::makeFunktion(QString str1, QString str2)
{

  
  Sleep(1000);
  qDebug() << q1 << q3;
       // qDebug() << str1 << str2;
}


eldar85
вообще ничего не пойму, как же мне хотябы 5 потоков в одно время то запустить??? чтобы они выполняли одну функцию, но с с двумя разными перемеными QString????
SABROG
Тема больше для раздела "Qt Ввод/Вывод, Сеть. Межпроцессное взаимодействие".

eldar85, читай документацию, ты задаешь такие вопросы, ответ на которые можно получить за 10 минут просто посмотрев примеры и почитав описание к классу QThread.
eldar85
так вот именно что про QThread написано всего то:
всего один пример
 class MyThread : public QThread
{
public:
     void run();
};

void MyThread::run()
{
     QTcpSocket socket;
     // connect QTcpSocket's signals somewhere meaningful
     ...
     socket.connectToHost(hostName, portNumber);
     exec();
}

и тот не объясняет как можно много потоков в одно время запустить... ну есть тут метод ран, сразу 10 потоков к примеру запустить что бы с фукцией моей работали... ничего не описано)
Litkevich Yuriy
создаёшь десять экземпляров класса MyThread, всем командуешь run(), вот тебе 10 потоков
eldar85
спасибо)
eldar85
вновь взялся за потоки, выяснил как их запускать в цикле:
Thread thread[10];

for( int n = 0; n < 4; n++)
    {
        thread[n].start();
        Sleep(10);
    }

for( int n = 0; n < 4; n++)
    {
        thread[n].wait();

        Sleep(10);
    }

и функция run()
void Thread::run()
{
       makeFunktion("1", "2");
       Sleep(10000);
       makeFunktion("3", "4");



}

одно как то не сходится, пока идет это ожидание в 10сек, главное окно висит все это время... не пойму, вроде вызвал потоки, и по идее же все происходит в разных потоках, почему главный то поток виснет...
Алексей1153
Sleep(10); - это же, вроде, 10мс :)

А разве основной поток может завершиться, пока выполняются дочерние ? Кроме того, если завершить основной, то дочерние сдохнут сразу
BRE
Цитата(eldar85 @ 21.6.2010, 15:01) *
одно как то не сходится, пока идет это ожидание в 10сек, главное окно висит все это время... не пойму, вроде вызвал потоки, и по идее же все происходит в разных потоках, почему главный то поток виснет...


Вот скажи, что делает этот код и для чего ты его написал? ;)
for( int n = 0; n < 4; n++)
    {
        thread[n].wait();

        Sleep(10);
    }

eldar85
если не сделать
thread[n].wait();

то поток просто убивается не доработав до конца, а тут запускается ожидание пока поток не будет закончен, в принципе работает нормально в таком плане...
я не говорил что мне нужно закрыть окно, я имел вввиду что оно виснет пока потоки не выполнят все действия до конца. я даже не могу перетащить окно, оно висит пока не будет все выполнено.
а Sleep(10); это просто чтобы между потоками какой то маленький промежуток был, хотя это не обязательно.
BRE
Цитата(eldar85 @ 21.6.2010, 15:25) *
если не сделать
thread[n].wait();

то поток просто убивается не доработав до конца, а тут запускается ожидание пока поток не будет закончен, в принципе работает нормально в таком плане...
я не говорил что мне нужно закрыть окно, я имел вввиду что оно виснет пока потоки не выполнят все действия до конца. я даже не могу перетащить окно, оно висит пока не будет все выполнено.

Этот код, как раз и блокирует главный (GUI) поток, до тех пор, пока не отработают все запущенные потоки.
Определись/разберись, что тебе нужно, и либо убери этот цикл (потоки будут работать!) или терпи блокирование GUI.
eldar85
убрав второй цикл все потоки тут же убиваются после того как закончиться первый цикл и все, получается просто ничего не работает. если убрать из ран() ожидание в 10 сек, то конечно все почти нормально, и то в консоли пишет что потоки убиты до того как они были закончены.
а если у меня в ран будет что то очень долго выполняться то поток просто будет убит ничего не сделав...
BRE
Цитата(eldar85 @ 21.6.2010, 15:37) *
убрав второй цикл все потоки тут же убиваются после того как закончиться первый цикл и все, получается просто ничего не работает. если убрать из ран() ожидание в 10 сек, то конечно все почти нормально, и то в консоли пишет что потоки убиты до того как они были закончены.
а если у меня в ран будет что то очень долго выполняться то поток просто будет убит ничего не сделав...

Потому что объекты Thread нужно создавать в куче (используя new), а не на стеке!
eldar85
большое вам спасибо, наконец то получилось)))
вот код
Thread *thread = new Thread[10];

for( int n = 0; n < 10; n++)
    {
    thread[n].start();

    }

и главное окно не виснет, полностью активно пока выполняется процесс)))) еще раз спасибо)
eldar85
все же сложность одна осталась с многопоточностью, я никак не пойму как можно сделать так чтобы метод ран использовал главное окно для вывода на него информации:
сделал функцию для вывода на экран vivod(), в функции knopka() по нажатию кнопки запускается процесс, получается метод run() это другой класс Thread, а остальные все объекты относятся к классу mainWidow, возможно очень глупый вопрос, согласен, но я уже перерыл много инфы и что только не попробывал и никак не дойдет как же сделать из метода run() запуск функции vivod().
и пробывал vivod() сделать функцией другом в классе Thread friend void mainWindow::vivod(); но реакции ноль...
помогите разобраться, ну никак не разберусь...

void mainWindow::vivod(QString str)
{
    ui->textEdit->append(str);
}

void mainWidoww::knopka()
{
    Thread *thread = new Thread[10];
    for(g=0; g<10; g++)
    {
        thread[g].start();
        Sleep(100);
    }
}

//===============================================================================

void Thread::run()
{
                 //вот тут как поместить функцию vivod() ?????


    qDebug() << "gggg";
}


вот в документации приводится пример
void MyThread::run()
{
     QTcpSocket socket;
     // connect QTcpSocket's signals somewhere meaningful
     ...
     socket.connectToHost(hostName, portNumber);
     exec();
}


получается тут в каждом потоке объявляется новый объект QTcpSocket socket;
я так же делал со своим объектом и в консоли вывод что один и тот же объект уже был создан в другом потоке


вот так попробывал
void Thread::run()
{
    mainWindow main;
main.vivod("fff");


    qDebug() << "gggg";
}


в итоге консоль выдала:

QObject::setParent: Cannot set parent, new parent is in a different thread
QObject::setParent: Cannot set parent, new parent is in a different thread
QObject::setParent: Cannot set parent, new parent is in a different thread
QObject::setParent: Cannot set parent, new parent is in a different thread
QObject::setParent: Cannot set parent, new parent is in a different thread
QObject::setParent: Cannot set parent, new parent is in a different thread
QObject::setParent: Cannot set parent, new parent is in a different thread
QObject::setParent: Cannot set parent, new parent is in a different thread
gggg
QObject::setParent: Cannot set parent, new parent is in a different thread
QObject::setParent: Cannot set parent, new parent is in a different thread
QObject::setParent: Cannot set parent, new parent is in a different thread
QObject::setParent: Cannot set parent, new parent is in a different thread
QObject::setParent: Cannot set parent, new parent is in a different thread
QObject::setParent: Cannot set parent, new parent is in a different thread
QObject::setParent: Cannot set parent, new parent is in a different thread
QObject::setParent: Cannot set parent, new parent is in a different thread
gggg
QObject::setParent: Cannot set parent, new parent is in a different thread
QObject::setParent: Cannot set parent, new parent is in a different thread
QObject::setParent: Cannot set parent, new parent is in a different thread
QObject::setParent: Cannot set parent, new parent is in a different thread
QObject::setParent: Cannot set parent, new parent is in a different thread
QObject::setParent: Cannot set parent, new parent is in a different thread
QObject::setParent: Cannot set parent, new parent is in a different thread
QObject::setParent: Cannot set parent, new parent is in a different thread
gggg

.............................................
Алексей1153
Цитата
чтобы метод ран использовал главное окно для вывода на него информации


[offtop]
довольно кровавый метод... (Хотя, мы тут в обливионе и не такое творим...)
[/offtop]

Ну а если серьёзно, то что мешает сделать в главном окне слот, а в потоке кидать сигналы ? И при чём тут создание объекта главного окна в каждом потоке - зачем ?
eldar85
да я тоже думал об этом, только не совсем разберусь как это сделать...
получается в главном окне слот нужно сделать pablic slots???
и еще впрос, какой сигнал кидать в потоке??? я сильно путаюсь еще в сигналах...
Алексей1153
eldar85, там вроде пофиг, приватный он или открытый, точно не помню.

А путаешься в них зря - типы функций сигнала и слота должны быть одинаковые, вот и всё

Перед запуском потока нужно connect его сигнал со слотом главного окна

(С сигналами тут вообще многое упрощается :) В студии приходится передавать в поток указатель на внешний объект)
eldar85
вот создал я паблик слот в главном окне

public slots:
         void vivod(QString str);


затем в срр его описал
void mainWindow::vivod(QString str)
{
    ui->textEdit->append(str);
}



и теперь метод run()

void Thread::run()
{
   connect()  //вот тут я не пойму что именно будет давать сигналы моему слоту


    qDebug() << "gggg";

}


можете объяснить???

или мне коннект делать в цикле с запуском потоков??
Алексей1153
нет, как-то вот так
class MyThread: .... (главное, что public QObject)
{
    Q_OBJECT

public signals:
    void vivod(QString str);

public://<<<
    void run();

};

class CMainWin: .... (главное, что public QObject)
{
    Q_OBJECT

public slots:
    void vivod(QString str);

public://<<<
    void knopka();

};



void CMainWin::knopka()
{
    Thread *thread = new MyThread[10];
    for(g=0; g<10; g++)
    {
        connect(&MyThread[g],MyThread.vivod , this, vivod);

        thread[g].start();
        Sleep(100);
    }
}


void MyThread::run()
{
    emit vivod("12345");
}


за ошибки в коде не ручаюсь, писал прямо в посте, а на память ещё всего не помню )
eldar85
большое спасибо, сейчас буду пробывать, потом отпишусь))))

нет, получается вообще чет непонятное, он на сигнал vivod() из Thread ругается теперь
first defined heremultiple definition of `Thread::vivod1(QString)'
multiple definition of `Thread::run()'
Алексей1153
eldar85, я не знаю иерархию твоих инклудов. Прицепил бы проект ? )
eldar85
спасибо тебе за совет, все получилось))))))))))))))))
ошибка была в твоем коде лишь в том что ты метод run() сделал как сигнал, его нужно просто объявлять как обычную функцию, а остальное все отлично, еще раз спасибо, наконец то хоть что то прояснилось, да еще и почитал про сигналы со слотами побольше... я как то им мало придавал значения... это было моей глупостью)))
Алексей1153
Ага, вижу косяк, спецификатор доступа не переопределил
public signals:
    void vivod(QString str);

public://<<<
    void run();
eldar85
все работает отлично, вот только еще с одним бы разобраться, допустим я запустил десять потоков в таком плане


void mainWindow::vivod(QString str)
{
    ui->textEdit->append(str);
}

void mainWindow::knopka()
{
    Thread *thread = new Thread[10];

    for(g=0; g<10; g++)
    {
        connect(&thread[g],SIGNAL(vivod1(QString)), this, SLOT(vivod(QString)));
        WOW = "good ";
        WOW.append(QString::number(g));

        thread[g].start();
        Sleep(1000);
    }
}

//===============================================================================

void Thread::run()
{

emit vivod1(WOW);


    qDebug() << "gggg";

}


так вот, в текстовое поле все выводиться лишь после того как все потоки закончатся, а нельзя ли сделать так чтобы поток выполнил свое действие и вывел на экран свое значение, и так далее, а то к примеру у меня один поток может выполняться 2 секунды, а другой возможно несколько минут и тогда получиться что они друг друга будут ожидать пока все не закончаться, а если их сделать 20...100 то вообще как то будет не к стати... может знаете как так сделать???
я тут в цикле специально секунду поставил ожидание, чтобы посмотреть как будет выводиться и вот и вышло что пока не пройдет 10 сек то на текстовое поле нифига ничего не выводиться... только когда все потоки все сделают...
Алексей1153
попробуй processEvents()

void Thread::run()
{

    emit vivod1(WOW);
    qDebug() << "gggg";//<<ещё бы штамп времени сюда бацнуть )))

    /*QApplication::*/processEvents(); //<<< обработать сообщения
}

Litkevich Yuriy
eldar85, ты всё же сделай примитивный проект, окно с кнопкой и меткой, при нажатии на кнопку в метку помести текст "начали", затем запускай потоки, которые что-то будут делать, например большие циклы. По завершении потоков выводи в метку "закончили".
Если с таким приложением будут проблемы - выкладывай в форум.
eldar85
а все, я разобрался почему))) дело было в том что я ставил ожидание в секунду в цикле запуска потоков, в итоге главное окно ждало когда закончиться цикл и только после этого обновляло окошко ... если ожидание из цикла убрать и поставить в метод run() то тогда все cool...
да проект то и так не сложный, примерно так как вы и сказали, одна кнопка, одно текстовое поле и класс для потоков...
главное что я понял что задерживало вывод в тектовое поле, это долбынный цикл)) и поставил за одно в него qApp->procecEvent(): вот и все))
большое спасибо за помощ))
Алексей1153
Цитата(eldar85 @ 26.6.2010, 0:39) *
поставил за одно в него qApp->procecEvent():

кстати, функция статическая, можно

QApplication::processEvents();

вернее, даже

QCoreApplication::processEvents();
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.