Форум программистов, компьютерный форум, киберфорум
C++ Qt
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.52/88: Рейтинг темы: голосов - 88, средняя оценка - 4.52
7 / 7 / 2
Регистрация: 17.10.2009
Сообщений: 325

Выполнение слота присоединённого к таймеру в потоке

25.08.2016, 11:18. Показов 19173. Ответов 37
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте, подскажите пожалуйста, возможно ли выполнение слота присоединённого к таймеру в потоке. Почитал и вычитал, что запустить таймер в другом потоке нельзя, что и пишет мне вывод в консоль. Но мне нужно что-бы выполнение кода было именно в таймере и именно в другом потоке. Вот код:
C++ (Qt)
1
2
3
4
5
6
7
//    QThread exec_Ping;
//    QObject::connect(&exec_Ping, SIGNAL(started()), SLOT(run()));
timer = new QTimer;
QObject::connect(timer, SIGNAL(timeout()), this, SLOT(timer_overflow()));
timer->start(4500);
//    timer->moveToThread(&exec_Ping);
//    exec_Ping.start();
Соответственно пытался
C++ (Qt)
1
timer->start(4500);
написать в реализации фунции run();
Подскажите вообще никак, или, может можно запустить вне потока, а потом в поток запихнуть?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
25.08.2016, 11:18
Ответы с готовыми решениями:

QTimer запус слота по таймеру
Как сделать чтобы после определенного события запускался таймер и после этого таймера выполнялся Слот? Но если это событие повторяется, то...

Запуск метода по таймеру в отдельном потоке
Доброго времени суток! Господа знатоки помогите начинающему. Есть метод получения почты public void GetLastMails() { ...

Отправка данных по таймеру в отдельном потоке
Добрый день, интересует такая вещь, нужно сделать передачу файла с данными каждые 5 секунд. При этом нужно чтобы человек продолжал работать...

37
137 / 107 / 23
Регистрация: 06.10.2008
Сообщений: 451
26.08.2016, 19:12
Студворк — интернет-сервис помощи студентам
Прошу прощения, инет глючил (ошибка копипаста).
Вместо proc нужно - myProcesses[i]
1
7 / 7 / 2
Регистрация: 17.10.2009
Сообщений: 325
29.08.2016, 07:22  [ТС]
mevn, попробовал, как Вы советовали, ошибка:
Code
1
2
3
/home/u0807/QtApplication_раб/main.cpp:129: ошибка: no matching function for call to 'myClass::connect(QSharedPointer<QProcess>&, const char*, const char*)'
                     QObject::connect(myProcesses[Count_Ellipse - 1], SIGNAL(finished(cod_Exit, QProcess::ExitStatus)), SLOT(slotPingClosed()));
                                                                                                                                              ^
Вот код:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
...................
QVector< QSharedPointer<QProcess> > myProcesses;
...................
void myClass::timer_overflow() {
    int i;
    if (items_V.count() > 0) {
        for (i = 0; i < items_V.count(); i++) {
            if (myProcesses[i]->atEnd()) {
                myProcesses[i]->start(ping_Around, Argumentses[i]);
            }
        }
    }
}
......................
 
void myClass::slotPingClosed(int i) {
    if (items_V.count() > 0) {
//
//            myProcesses[i]->start(ping_Around, Argumentses[i]);
//            myProcesses[i]->waitForFinished();
        strlstPingResults_m[i].clear();
        strlstPingResults_m[i]<<myProcesses[i]->readAll();
        Sss[i] = strlstPingResults_m[i][0].split('\n');
 
        if (Sss[i].count() > 1) {
            count_Pack_Ch[i] = Sss[i][4].mid(23, 1);
        }
 
        if (count_Pack_Ch[i].count() > 0) {
            if (count_Pack_Ch[i] == "1") {
                items_V[i]->setBrush(QBrush(Qt::green));
            }
            else {
                items_V[i]->setBrush(QBrush(Qt::red));
            }
        }
        else {
            items_V[i]->setBrush(QBrush(Qt::red));
        }
    }
}
 
...................
int myClass::btnClicked_Add() {
..................
    myProcesses.resize(Count_Ellipse);
    myProcesses[Count_Ellipse - 1].reset(new QProcess());
    int cod_Exit;
    int C_E_M_O = Count_Ellipse - 1;
    QObject::connect(myProcesses[Count_Ellipse - 1], SIGNAL(finished(cod_Exit, QProcess::ExitStatus)), SLOT(slotPingClosed(C_E_M_O)));
.................
}
0
137 / 107 / 23
Регистрация: 06.10.2008
Сообщений: 451
29.08.2016, 07:32
Попробуйте вместо
C++ (Qt)
1
 QObject::connect(myProcesses[Count_Ellipse - 1], SIGNAL(finished(cod_Exit, QProcess::ExitStatus)), SLOT(slotPingClosed()));
написать
C++ (Qt)
1
 connect(myProcesses[Count_Ellipse - 1], SIGNAL(finished(int,QProcess::ExitStatus )),this, SLOT(slotPingClosed()));
Добавлено через 2 минуты
Или
C++ (Qt)
1
connect(myProcesses[Count_Ellipse - 1], SIGNAL(finished(int)),this, SLOT(slotPingClosed(int)));
1
7 / 7 / 2
Регистрация: 17.10.2009
Сообщений: 325
29.08.2016, 07:51  [ТС]
Спасибо, попробовал, та же ошибка. Посмотрите, как у меня объявлены myProcesses, и их как-то по другому надо в connect подавать?
0
93 / 93 / 33
Регистрация: 17.03.2012
Сообщений: 536
29.08.2016, 10:00
Лучший ответ Сообщение было отмечено fredwriter как решение

Решение

А откуда у QSharedPointer'a сигнал finished(...)?
У него такого нет.
Вы берете myProcesses[i], получаете QSharedPointer<QProcess>, а вам надо добраться до QProcess'а, причем до указателя/адреса этого объекта.
После этого вы можете к сигналу QProcess'а присоединить ваш слот.
C++ (Qt)
1
connect(myProcesses[Count_Ellipse - 1].data(), SIGNAL(finished(int)),this, SLOT(slotPingClosed(int)));
Или с параметрами, описанными выше сигнал вызывать.
1
7 / 7 / 2
Регистрация: 17.10.2009
Сообщений: 325
29.08.2016, 11:10  [ТС]
Спасибо, вроде работает, но как мне в функции slotPingClosed определить индеск процесса, который завершился?
Если так:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
public slots:
  void slotPingClosed(int i);
 
void myClass::timer_overflow() {
    int i;
    if (items_V.count() > 0) {
        for (i = 0; i < items_V.count(); i++) {
            if (myProcesses[i]->atEnd()) {
                myProcesses[i]->start(ping_Around, Argumentses[i]);
            }
//            myProcesses[i]->waitForFinished();
//            strlstPingResults_m[i].clear();
//            strlstPingResults_m[i]<<myProcesses[i]->readAll();
//            Sss[i] = strlstPingResults_m[i][0].split('\n');
        }
 
 
//        for (int i = 0; i < items_V.count(); i++) {
//            if (Sss[i].count() > 1) {
//                count_Pack_Ch[i] = Sss[i][4].mid(23, 1);
//            }
//        }
//        for (int i = 0; i < items_V.count(); i++) {
//            if (count_Pack_Ch[i].count() > 0) {
//                if (count_Pack_Ch[i] == "1") {
//                    items_V[i]->setBrush(QBrush(Qt::green));
 
//                }
//                else {
//                    items_V[i]->setBrush(QBrush(Qt::red));
//                }
//            }
//            else {
//                items_V[i]->setBrush(QBrush(Qt::red));
//            }
//        }
    }
}
 
 
void myClass::slotPingClosed(int i) {
 
    if (items_V.count() > 0) {
        strlstPingResults_m[i].clear();
        strlstPingResults_m[i]<<myProcesses[i]->readAll();
        Sss[i] = strlstPingResults_m[i][0].split('\n');
 
        if (Sss[i].count() > 1) {
            count_Pack_Ch[i] = Sss[i][4].mid(23, 1);
        }
 
        if (count_Pack_Ch[i].count() > 0) {
            if (count_Pack_Ch[i] == "1") {
                items_V[i]->setBrush(QBrush(Qt::green));
            }
            else {
                items_V[i]->setBrush(QBrush(Qt::red));
            }
        }
        else {
            items_V[i]->setBrush(QBrush(Qt::red));
        }
    }
}
C++ (Qt)
1
2
int C_E_M_O = Count_Ellipse - 1;
connect(myProcesses[Count_Ellipse - 1].data(), SIGNAL(finished(int)), this, SLOT(slotPingClosed(C_E_M_O)));
то в консоль вылазят сообщения:
Code
1
2
3
4
QObject::connect: No such slot myClass::slotPingClosed(C_E_M_O) in ../QtApplication_раб/main.cpp:438
QObject::connect: No such slot myClass::slotPingClosed(C_E_M_O) in ../QtApplication_раб/main.cpp:438
QObject::connect: No such slot myClass::slotPingClosed(C_E_M_O) in ../QtApplication_раб/main.cpp:438
QObject::connect: No such slot myClass::slotPingClosed(C_E_M_O) in ../QtApplication_раб/main.cpp:438
А если так
C++ (Qt)
1
2
3
4
void myClass::slotPingClosed(int) {
......
}
connect(myProcesses[Count_Ellipse - 1].data(), SIGNAL(finished(int)), this, SLOT(slotPingClosed(int)));
То как внутри slotPingClosed определить какой процесс завершился и по какому индексу выгружать вывод в strlstPingResults_m?
0
93 / 93 / 33
Регистрация: 17.03.2012
Сообщений: 536
29.08.2016, 11:41
Ну как вариант, если нужен сам процесс, могу предложить в слоте
C++ (Qt)
1
QProcess *process = dynamic_cast<QProcess *>(QObject::sender());
А вот индекс... можно поискать в векторе, например.
1
137 / 107 / 23
Регистрация: 06.10.2008
Сообщений: 451
29.08.2016, 11:41
Лучший ответ Сообщение было отмечено fredwriter как решение

Решение

Цитата Сообщение от fredwriter Посмотреть сообщение
как внутри slotPingClosed определить какой процесс завершился и по какому индексу выгружать вывод в strlstPingResults_m?
Как вариант после старта
C++ (Qt)
1
myProcess->setProperty("C_E_M_O", C_E_M_O);
Во время приема
C++ (Qt)
1
2
3
4
    QProcess *prog = qobject_cast<QProcess*> (sender());
    int ii = prog->property("C_E_M_O").toInt();
    ...
    delete prog;
1
7 / 7 / 2
Регистрация: 17.10.2009
Сообщений: 325
29.08.2016, 11:57  [ТС]
Цитата Сообщение от Slip. Посмотреть сообщение
А вот индекс... можно поискать в векторе, например.
У меня завершился конкретный процесс, то есть конкретный процесс в векторе дал сигнал finished(), и мне нужен его индекс, именно его. То есть можно в векторе поискать процесс, который дал такой сигнал? В теории может быть в векторе у меня несколько таких процессов по идее? Неужели нельзя в slot подать индеск процесса который я коннекчу?

Цитата Сообщение от mevn Посмотреть сообщение
myProcess->setProperty("C_E_M_O", C_E_M_O);
То есть если после старта дать процессу свойство то процесс можно вот так выковырять, а затем выковырять toInt(), это и будет индекс, мне это нравится, спасибо.
Цитата Сообщение от mevn Посмотреть сообщение
QProcess *prog = qobject_cast<QProcess*> (sender());
0
137 / 107 / 23
Регистрация: 06.10.2008
Сообщений: 451
29.08.2016, 11:58
Ой
C++ (Qt)
1
2
3
    ....
    prog = NULL;
    delete prog;
1
7 / 7 / 2
Регистрация: 17.10.2009
Сообщений: 325
30.08.2016, 04:32  [ТС]
Спасибо, теперь вроде работает, при отсутствии пинга программа не подвисает. Но возникла проблема. теперь, если последний ip в последнем process не пингуется, то его не удаётся удалить.
C++ (Qt)
1
2
3
4
5
6
7
Argumentses.remove(n_Del);
qDebug() << myProcesses[n_Del].data()->property("ind_P"); // выводит правильно
myProcesses.remove(myProcesses[n_Del].data()->property("ind_P").toInt()); // ни так
myProcesses.remove(n_Del); // ни так
count_Pack_Ch.remove(n_Del);
strlstPingResults_m.remove(n_Del);
Sss.remove(n_Del);
Ошибка, хотя такой индекс есть.
Code
1
ASSERT failure in QVector<T>::operator[]: "index out of range", file ../Qt/5.5/gcc_64/include/QtCore/qvector.h, line 401
Но, если он пингуется, то прекрасно удаляется.

C++ (Qt)
1
2
3
myProcesses.resize(Count_Ellipse);
myProcesses[Count_Ellipse - 1].reset(new QProcess());
connect(myProcesses[Count_Ellipse - 1].data(), SIGNAL(finished(int)), this, SLOT(slotPingClosed(int)));
0
93 / 93 / 33
Регистрация: 17.03.2012
Сообщений: 536
30.08.2016, 09:26
А может он у вас nullptr, этот последний?
Хотя в данном случае это вряд ли так.
А на какую строчку конкретно ругается?
Попробуйте вывести кол-во элементов.
По такому кусочку кода я понять не могу
0
7 / 7 / 2
Регистрация: 17.10.2009
Сообщений: 325
30.08.2016, 11:39  [ТС]
Ругается на 3-ю строчку, удаление, собственно.

C++ (Qt)
1
2
3
4
qDebug() << myProcesses[n_Del].data()->property("ind_P").toInt();
qDebug() << myProcesses.count();
qDebug() << n_Del;
myProcesses.remove(myProcesses[n_Del].data()->property("ind_P").toInt());
Вывод консоли:
Code
1
2
3
1
2
1
Еще перед ошибкой выводится сообщение
Code
1
QProcess: Destroyed while process ("/bin/ping") is still running
И ошибка возникает не всегда, и это сообщение не появляется, если нет ошибки.
То есть, возможно перед удалением процесс нужно остановить.
0
93 / 93 / 33
Регистрация: 17.03.2012
Сообщений: 536
30.08.2016, 12:07
Я так понимаю, вы берет индекс через свойство ind_P? А если у вас индексы вектора и ind_P не совпадают?
У вектора, кстати, есть метод indexOf(...);
И если вы делаете удаление указателя, делайте это, например, так:
C++ (Qt)
1
2
if (myPtr)
    delete myPtr;
Добавлено через 6 минут
И еще. Вы лучше когда новый процесс создаете, вы к сигналу финишед привяжите слот deleteLater();
Тогда вам и вручную удалять не надо будет
типа:
C++ (Qt)
1
connect(myProcesses[i].data, SIGNAL(finished(int exitCode, QProcess::ExitStatus exitStatus)), myProcesses[i].data, SLOT(deleteLater()));
0
137 / 107 / 23
Регистрация: 06.10.2008
Сообщений: 451
30.08.2016, 12:13
Возможно процесс был повторно запущен, (время таймера вышло), в этом случае можно поиграться с параметрами пинга: количество запусков, время ожидания.
0
7 / 7 / 2
Регистрация: 17.10.2009
Сообщений: 325
30.08.2016, 12:17  [ТС]
Цитата Сообщение от Slip. Посмотреть сообщение
И еще. Вы лучше когда новый процесс создаете, вы к сигналу финишед привяжите слот deleteLater();
Тогда вам и вручную удалять не надо будет
Я не удаляю при завершении процесса, у меня в векторе он должен храниться, пока пользователь не удалит QGraphicsEllipseItem этого процесса, а сам процесс может быть не активен.
Кстати, что скажете вот по этому поводу?
Цитата Сообщение от fredwriter Посмотреть сообщение
Еще перед ошибкой выводится сообщение
Код
QProcess: Destroyed while process ("/bin/ping") is still running
И ошибка возникает не всегда, и это сообщение не появляется, если нет ошибки.
То есть, возможно перед удалением процесс нужно остановить.
То есть, иногда последний process удаляется, даже если адресс не пингуется удаляется, и ни ошибки ни сообщения нет.

Добавлено через 2 минуты
Цитата Сообщение от mevn Посмотреть сообщение
Возможно процесс был повторно запущен, (время таймера вышло), в этом случае можно поиграться с параметрами пинга: количество запусков, время ожидания.
А нельзя процесс перед удалением тупо выубать?

Добавлено через 18 секунд
Если он уже не нужен.
0
137 / 107 / 23
Регистрация: 06.10.2008
Сообщений: 451
30.08.2016, 12:27
Можно попробовать проверить kill(); или terminate();

Добавлено через 3 минуты
Только перед вырубанием нужно сделать disconnect, а то возможно зацикливание
1
93 / 93 / 33
Регистрация: 17.03.2012
Сообщений: 536
30.08.2016, 14:19
А еще можно к удалению QGraphicsEllipseItem прицепить слот deleteLater() процесса
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
30.08.2016, 14:19

Действие по таймеру выполняется в отдельном или общем потоке
Добрый день! Если я ставлю в программу таймер и на tick вешаю функцию, то будет ли на время выполнения этой функции останавливаться...

Выполнение запроса по таймеру
что-то я накуралесил.. короче хотел вывести результат sql запроса в Label, но так чтоб результат там постоянно был виден, а вышло только по...

Выполнение цикла по таймеру
есть вот такой код: private Color ALL1; private void button_follow_Click(object sender, EventArgs e) { ...

Выполнение действия по таймеру
Здравствуйте, подскажите пожалуйста, надо по клику на кнопку показать Layaut, а через 4 секунды скрыть. Но при повторном нажатии время...

Выполнение заданий по таймеру
Здравствуйте! Есть несколько заданий, которые должны выполняться по времени. Использую Timer. Но он работает некорректно. Не всегда...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
38
Ответ Создать тему
Новые блоги и статьи
Nekobox - outbounds[0].transport: unknown transport type: raw
damix 01.10.2026
Фикс ошибки Правым кликом по серверу -> отладочная информация -> edit Заменить "net": "raw", на "net": "tcp", Нажать кнопку reload.
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru