Russian Qt Forum
Ноябрь 25, 2024, 16:06 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: QTimer::singleShot и удаление объекта  (Прочитано 4370 раз)
grig_p
Новичок

Offline Offline

Сообщений: 11


Просмотр профиля
« : Июль 09, 2021, 16:46 »

Здравствуйте!
Есть некий виджет, который асинхронно, с определенной периодичностью получает данные и отображает их на себе и зажигает индикатор их приема. После получения данных, через, скажем 100 мсек, этот индикатор должен быть погашен. Я это сделал так:

Код:
void MyWidget::getData(DataType *data)
{
    ....

     //! Зажжем индикатор
     ui->Indicator->setValue(1);

    //! Погасим индикатор через 100 мс
    QTimer::singleShot(100, [=]
    {
            ui->Indicator->setValue(0);
    });
    ....


Все прекрасно работает до удаления виджета. Возникает нерегулярный сбой.
Поставил ловушки:

Код:

MyWidget::~MyWidget()
{
    qDebug() << "destroy";
    delete ui;
}

void MyWidget::getData(DataType *data)
{
    ....

     //! Зажжем индикатор
     ui->Indicator->setValue(1);

    //! Погасим индикатор через 100 мс
    QTimer::singleShot(100, [=]
    {
            qDebug() << "singleshot";
            ui->Indicator->setValue(0);
    });
    ....

 Выводит в консоль:
singleshot
singleshot
singleshot
destroy
singleshot

и сбой.
Как правильно обойти эту проблему?
Придумал вариант поставить семафор:

Код:

class MyWidget ...
{

    bool m_isFinish {false};
}


MyWidget::~MyWidget()
{
    qDebug() << "destroy";
    m_isFinish = true;
    delete ui;
}

void MyWidget::getData(DataType *data)
{
    ....

     //! Зажжем индикатор
     ui->Indicator->setValue(1);

    //! Погасим индикатор через 100 мс
    QTimer::singleShot(100, [=]
    {
            if (!m_isFinish)
            {
                qDebug() << "singleshot";
                ui->pbPulse->setValue(0);
            }
    });
    ....

только правильно ли это?
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #1 : Июль 09, 2021, 16:56 »

Просто добавьте объект QTimer в класс и при разрушении виджета разрушайте и таймер.
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #2 : Июль 09, 2021, 17:15 »

Цитата: cpp
QTimer::singleShot(100, this, [this]
    {
            qDebug() << "singleshot";
            ui->Indicator->setValue(0);
    });

?
Записан

ArchLinux x86_64 / Win10 64 bit
grig_p
Новичок

Offline Offline

Сообщений: 11


Просмотр профиля
« Ответ #3 : Июль 09, 2021, 17:36 »

Просто добавьте объект QTimer в класс и при разрушении виджета разрушайте и таймер.
Спасибо, попробую!


Цитата: cpp
QTimer::singleShot(100, this, [this]
    {
            qDebug() << "singleshot";
            ui->Indicator->setValue(0);
    });

?

Не понял, что не так
А такого у меня нет: 100, this, [this]
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #4 : Июль 09, 2021, 17:37 »

Цитата: cpp
QTimer::singleShot(100, this, [this]
    {
            qDebug() << "singleshot";
            ui->Indicator->setValue(0);
    });

?
Захват указателя this никак не блокирует разрущение объекта. Это на shared_ptr. Улыбающийся
Записан
sergek
Гипер активный житель
*****
Offline Offline

Сообщений: 872


Мы должны приносить пользу людям.


Просмотр профиля
« Ответ #5 : Июль 10, 2021, 10:12 »

Просто добавьте объект QTimer в класс и при разрушении виджета разрушайте и таймер.
Что это изменит, если singshort является статической функцией?
Записан

Qt 5.13.0 Qt Creator 5.0.1
Win10, Ubuntu 20.04
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #6 : Июль 10, 2021, 10:43 »

Просто добавьте объект QTimer в класс и при разрушении виджета разрушайте и таймер.
Что это изменит, если singshort является статической функцией?
Это позволит ее не использовать, т.к. она не управляемая после запуска.
Записан
sergek
Гипер активный житель
*****
Offline Offline

Сообщений: 872


Мы должны приносить пользу людям.


Просмотр профиля
« Ответ #7 : Июль 10, 2021, 11:56 »

С этим согласен. Но TC это понял? 
Записан

Qt 5.13.0 Qt Creator 5.0.1
Win10, Ubuntu 20.04
grig_p
Новичок

Offline Offline

Сообщений: 11


Просмотр профиля
« Ответ #8 : Июль 12, 2021, 10:20 »

Спасибо всем ответившим. Надеюсь, что понял.

Код:
QTimer *m_timer;
...
m_timer = new QTimer();

...

m_timer.singleShot(100, [=]
    {
            ui->Indicator->setValue(0);
    });

...

delete m_timer;

После
Код:
delete m_timer;
singleShot сработает?
Записан
sergek
Гипер активный житель
*****
Offline Offline

Сообщений: 872


Мы должны приносить пользу людям.


Просмотр профиля
« Ответ #9 : Июль 12, 2021, 10:59 »

Нет, не поняли)) Синглшот - статическая функция, а это значит, что она не принадлежит к созданному вами объекту, и не прекратит свою работу после его уничтожения. Собственно, вызовы m_timer.singleShot и QTimer::singleShot семантически ничем не отличаются.
Если вам так нужен однократный запуск таймера, то используйте методы setSingleShot и start.
Записан

Qt 5.13.0 Qt Creator 5.0.1
Win10, Ubuntu 20.04
grig_p
Новичок

Offline Offline

Сообщений: 11


Просмотр профиля
« Ответ #10 : Июль 12, 2021, 11:32 »

спасибо
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.052 секунд. Запросов: 23.