Russian Qt Forum

Qt => Многопоточное программирование, процессы => Тема начата: andrew.k от Июль 06, 2012, 14:10



Название: Очередь событий потока
Отправлено: andrew.k от Июль 06, 2012, 14:10
Есть слот, который отрабатывает в отдельном потоке.
В определенный момент из основного потока в этот посылается сигнал.
Он не обрабатываетя, пока не завершится этот слот.
Как "протолкнуть" этот сигнал? что-то вроде processEvents() только для потока


Название: Re: Очередь событий потока
Отправлено: OKTA от Июль 06, 2012, 14:16
Qt::DirectCOnnect не канает разве?


Название: Re: Очередь событий потока
Отправлено: LisandreL от Июль 06, 2012, 14:37
Как "протолкнуть" этот сигнал? что-то вроде processEvents() только для потока
processEvents() и работает применительно к тому потоку, в котором вызывается. Используйте его.


Название: Re: Очередь событий потока
Отправлено: mutineer от Июль 06, 2012, 14:45
Как "протолкнуть" этот сигнал? что-то вроде processEvents() только для потока

"Протолкунуть" - это прервать текущий слот и отреагировать на сигнал?


Название: Re: Очередь событий потока
Отправлено: andrew.k от Июль 06, 2012, 15:44
Qt::DirectCOnnect не канает разве?
Ну вообще канает конечно, но это не совсем то.
У QEventLoop есть метод processEvents. Но так как я не наследовался от QThread, то у меня нет доступа к его экземпляру. Поэтому никак не вызвать.


Название: Re: Очередь событий потока
Отправлено: andrew.k от Июль 06, 2012, 15:45
Как "протолкнуть" этот сигнал? что-то вроде processEvents() только для потока
processEvents() и работает применительно к тому потоку, в котором вызывается. Используйте его.
Т.е. если я вызову внутри слота работающего в неосновном потоке qApp->processEvents(), будут обработаны события текущего потока, а события основного потока будут не тронуты?


Название: Re: Очередь событий потока
Отправлено: andrew.k от Июль 06, 2012, 15:46
Как "протолкнуть" этот сигнал? что-то вроде processEvents() только для потока

"Протолкунуть" - это прервать текущий слот и отреагировать на сигнал?
Ну не совсем прервать, просто чтобы связанный с сигналом слот отработал.
И выполнение слота продолжилось (обычная логика processEvents)


Название: Re: Очередь событий потока
Отправлено: mutineer от Июль 06, 2012, 15:50
Как "протолкнуть" этот сигнал? что-то вроде processEvents() только для потока
processEvents() и работает применительно к тому потоку, в котором вызывается. Используйте его.
Т.е. если я вызову внутри слота работающего в неосновном потоке qApp->processEvents(), будут обработаны события текущего потока, а события основного потока будут не тронуты?

Цитировать
Processes all pending events for the calling thread according to the specified flags until there are no more events to process.
Ну судя по доке обрабатываются сигналы вызывающего потока. К тому же этот метод статический


Название: Re: Очередь событий потока
Отправлено: andrew.k от Июль 06, 2012, 16:02
Как "протолкнуть" этот сигнал? что-то вроде processEvents() только для потока
processEvents() и работает применительно к тому потоку, в котором вызывается. Используйте его.
Т.е. если я вызову внутри слота работающего в неосновном потоке qApp->processEvents(), будут обработаны события текущего потока, а события основного потока будут не тронуты?

Цитировать
Processes all pending events for the calling thread according to the specified flags until there are no more events to process.
Ну судя по доке обрабатываются сигналы вызывающего потока. К тому же этот метод статический
Ты прав. Не замечал, что он статический)
Вроде работает. Видимо, это и есть то, что я искал.


Название: Re: Очередь событий потока
Отправлено: inforse от Октябрь 24, 2012, 09:04
Скажите пожалуйста. У меня идет конект к базе, я вызываю форму. С помощью ProcessEvent форма вырисовывается, но "замораживается" На действия пользователя окно не откликается. Подскажите можно ли как-то при выполнении процесса, форму разморозить? Процесс запускаю Qprocess->start.
Код:
    stat_bd ->setText("Соединение..");
    this->setWindowTitle(QObject::tr("Статистика использования БД"));
    this->show();
    qApp->processEvents(QEventLoop::AllEvents);

    if (!db.open()) {


Название: Re: Очередь событий потока
Отправлено: Bepec от Октябрь 24, 2012, 10:33
startDetached


Название: Re: Очередь событий потока
Отправлено: inforse от Октябрь 24, 2012, 11:20
Но startDetached вызывает всплывающие окна в системе.

Я не много не правильно сформулировал вопрос. Есть два момента.

В моем коде при установлении соединения с БД окно замораживается "db.open" можно как-то этого избежать? Вычитал что открытие соединения в потоке, не поможет, так как для него создается свое собственное соединение.

И другой момент, вот при выполнении последовательно запускающихся процессов, окно тоже замораживается. Причем если запускаешь один, все нормально, окно реагирует, аесли ставишь в очередь другой, то пока не выполнится его не отпускает. ProcessEvent вставлял не помогло(



Название: Re: Очередь событий потока
Отправлено: Bepec от Октябрь 24, 2012, 13:50
StartDetached запускает процесс отдельно от вашего приложения. Независимо.

И что за "всплывающие окна", я незнаю. И не видел их. И вообще не знаю что вы запускаете.

А соединение с базой вроде спокойно переносится в другой поток, но точно не ручаюсь.


Название: Re: Очередь событий потока
Отправлено: Igors от Октябрь 24, 2012, 14:59
И другой момент, вот при выполнении последовательно запускающихся процессов, окно тоже замораживается. Причем если запускаешь один, все нормально, окно реагирует, аесли ставишь в очередь другой, то пока не выполнится его не отпускает. ProcessEvent вставлял не помогло(
По-моему QProcess::start и QProcess::startDetached - здесь без разницы т.к. процессы запускаются асинхронно и управление возвращается вызывающему (даже если ОС еще занимается запуском). Показываем код - а то что-то мутно на словах выходит


Название: Re: Очередь событий потока
Отправлено: andrew.k от Октябрь 25, 2012, 18:11
И другой момент, вот при выполнении последовательно запускающихся процессов, окно тоже замораживается. Причем если запускаешь один, все нормально, окно реагирует, аесли ставишь в очередь другой, то пока не выполнится его не отпускает. ProcessEvent вставлял не помогло(
По-моему QProcess::start и QProcess::startDetached - здесь без разницы т.к. процессы запускаются асинхронно и управление возвращается вызывающему (даже если ОС еще занимается запуском). Показываем код - а то что-то мутно на словах выходит
подписываюсь под этими словами.
Но чувствую, что если мы увидим код, мурашки пойдут по коже)


Название: Re: Очередь событий потока
Отправлено: inforse от Октябрь 26, 2012, 09:43
Код:
QModelIndexList currentSelection = tableWidget->selectionModel()->selectedIndexes();
    for ( int i = 0; i < currentSelection.count(); ++i){
        if ( currentSelection.at(i).column() == 1 ) {continue;}
        int roow = currentSelection.at(i).row();
        nameBase = tableWidget->item(roow, 0)->text();
        qDebug() << nameBase;

        emit proc();

void sevice::reindex()
{
    QString rex = ("g");
    rex = rex.arg(nameBase, dbNamer, pr);

    //textBrowser->clear();
    textBrowser->append(rex);

    serviceP.start(rex);
    cansel->setEnabled(true);
В начале я вынимаю параметры которые выделены, и запускаю процесс serviceP.start(rex), вот если параметр всего один, он замечательно выполняется, окно не замораживается. Если запускаются два процесса, последовательно (параллельно он не запускает их) то окно замораживается до выполения обоих. waitforfinished тоже самое. Я контралирую процесс, и вывожу информацию с него в TextBrowser. Если использовать startDetached, то в винде всплывает cmd, с сообщениями о ходе выполнения процесса, и эти сообщения у меня не перехватываются
Код:
connect(&serviceP, SIGNAL(readyReadStandardOutput()), this, SLOT(updateOutputTextEdit()));
void sevice::updateOutputTextEdit()
{
    QByteArray newData = serviceP.readAllStandardOutput();
    QString text = textBrowser->toPlainText() + QString::fromLocal8Bit(newData);
    textBrowser->setPlainText(text);
    scrolDown();

}


Название: Re: Очередь событий потока
Отправлено: Igors от Октябрь 26, 2012, 13:25
В начале я вынимаю параметры которые выделены, и запускаю процесс serviceP.start(rex), вот если параметр всего один, он замечательно выполняется, окно не замораживается. Если запускаются два процесса, последовательно (параллельно он не запускает их) то окно замораживается до выполения обоих. waitforfinished тоже самое.
Наверное "если процесс всего один" т.к. "параметры" - это аргументы командной строки. Ну ладно, не суть.
Главное что бросается в глаза: чего Вы используете один экземпляр класса QProcess (serviceP) и ожидаете от него выполнения 2 и более процессов ??? Делайте QProcess на каждый запуск и храните указатели на них в контейнере, напр
Код
C++ (Qt)
serviceP.push_back(new QProcess());
serviceP.back()->start(rex);
 


Название: Re: Очередь событий потока
Отправлено: inforse от Октябрь 26, 2012, 15:04
Ну хорошо, только я не запускаю более одного действия, я жду когда завершится первый процесс, затем запускаю его с другим аргументом. И все это время форма "заморожена".


Название: Re: Очередь событий потока
Отправлено: Igors от Октябрь 26, 2012, 15:29
Ну хорошо, только я не запускаю более одного действия, я жду когда завершится первый процесс, затем запускаю его с другим аргументом. И все это время форма "заморожена".
Вы давеча писали
вот если параметр всего один, он замечательно выполняется, окно не замораживается.
Так как Вас понять?  :)

Можно ли использовать один экземпляр QProcess для запуска процессов одного за другим? Этого я не знаю, и даже не хочу знать :). Это здесь совершенно не нужно, даже с одним процессом гораздо выгоднее работать через указатель, напр
Код
C++ (Qt)
QProcess * theProc = 0;
..
if (theProc) {   // ага, процесс еще живет
..                
}
else {
theProc = new QProcess();  // создаем и запускаем
theProc->start(arg);
}
..
delete theProc;  // отработал, удаляем и зачищаем указатель
theProc = 0;
 


Название: Re: Очередь событий потока
Отправлено: andrew.k от Октябрь 26, 2012, 15:49
Ну хорошо, только я не запускаю более одного действия, я жду когда завершится первый процесс, затем запускаю его с другим аргументом. И все это время форма "заморожена".
Вы давеча писали
вот если параметр всего один, он замечательно выполняется, окно не замораживается.
Так как Вас понять?  :)

Можно ли использовать один экземпляр QProcess для запуска процессов одного за другим? Этого я не знаю, и даже не хочу знать :). Это здесь совершенно не нужно, даже с одним процессом гораздо выгоднее работать через указатель, напр
Можно. В этом нет ничего страшного. Главное первый должен завершиться, перед использованием второго.

Плюс запуск процесса занимает время. Поэтому неплохо использовать функцию waitForStarted
Цитировать
Note: Processes are started asynchronously, which means the started() and error() signals may be delayed. Call waitForStarted() to make sure the process has started (or has failed to start) and those signals have been emitted.
А после waitForFinished, если это необходимо.

А по приведенному фрагменту кода вообще понять что-то сложно.