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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: обработка событий & qapplication  (Прочитано 7990 раз)
demaker
Птица говорун
*****
Offline Offline

Сообщений: 962


Просмотр профиля
« : Июнь 07, 2016, 11:19 »

Есть класс потока в котором создается и запускается таймер.
По таймауту создается событие и кладется в цикл обработки.
Обработчик событий описан в главном окне приложения.
Код
C++ (Qt)
 
void Thread::run (){
     QEventloop loop;
     QTimer timer;
     connect(&timer,SIGNAL(timeout()),this,SLOT(createEvent()),Qt::DirectConnection);
     timer.start(defaultTime);
     loop.exec();
}
 
void Thread::createEvent(){
     Event *event = new Event();
     QApplication::postEvent(objReceiver,event);
}
 
void Thread::setObjRecever(QObject * obj){
     objReceiver = obj;
}
 
//___________________________________________
 
static const int my_type  = 1099;
class Event : public QEvent {
 
public:
      Event() : QEvent((QEvent::Type)my_type){}
      void incCounter(int *var){ (*var)++;}
}
 
//____________________________________________
 
MainWindow:: MainWindow(QWidget*parent) :QMainWindow(parent),
                      ui(new Ui:: MainWindow)
{
     counter =0;
    thread  = new Thread();
    thread->setObjRecever(this);
    thread->start();
}
 
void MainWindow::customEvent(QEvent *e){
 
       if(event->type() == my_type){
           Event  *event = staic_cast<Event*>(e);
           event->incCounter(&counter);
           ui->lcdNumber->display(counter);
      }
      QMainWindow:: customEvent(e);
}
 

Я поставил defaultTime = 50 ,т.е таймер срабатывает 20 раз в секунду .
В минуту 1200.

А на экране у меня через минуту в lcdNumber выводится толко 973-980,
т.е события не успевают обрабатываться Непонимающий






« Последнее редактирование: Июнь 07, 2016, 16:53 от demaker » Записан
_OLEGator_
Гость
« Ответ #1 : Июнь 07, 2016, 17:59 »

Все тормозится интерфейсом - что непонятного то.
В итоге скорость работы прямо зависит от скорости работы графики.
Решение - обновляй данные в интерфейсе реже - раз в секунду например.
Записан
demaker
Птица говорун
*****
Offline Offline

Сообщений: 962


Просмотр профиля
« Ответ #2 : Июнь 07, 2016, 19:08 »

Т.е  главный  поток обработки событий
не успевает обработатывать сообщения,
которые ему посылает другой поток.
Ясно Улыбающийся
« Последнее редактирование: Июнь 07, 2016, 21:10 от demaker » Записан
demaker
Птица говорун
*****
Offline Offline

Сообщений: 962


Просмотр профиля
« Ответ #3 : Июнь 07, 2016, 21:09 »

А тогда еще маленький вопрос. Улыбающийся
Если я останавливаю поток, который записывает сообщения в главный цикл обработки.
То главный цикл обработки сообщений должен обработать все сообщения,
которые стоят в очереди , правильно?
Тогда почему этого происходит?

Все равно за минуту 1200 не выводит. По идее поток должен накидать за минуту. Непонимающий
« Последнее редактирование: Июнь 07, 2016, 21:11 от demaker » Записан
_OLEGator_
Гость
« Ответ #4 : Июнь 07, 2016, 21:16 »

Нет. Не правильно.
У очереди есть размер - если она переполняется, то часть сообщений может теряться.
Записан
Bepec
Гость
« Ответ #5 : Июнь 07, 2016, 21:16 »

Вы уберите все обращения к ui в customEvent.
И обновляйте данные в отдельном слоте, допустим раз в 1 секунду.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Июнь 08, 2016, 07:39 »

Зачем нужно было затевать customEvent - хз, достаточно было просто сигнала. Слабо верится что lcdNumber не справляется с перерисовкой за 20 ms (вагон времени). Это легко проверить напр так
Код
C++ (Qt)
void MainWindow::customEvent(QEvent *e)
{
       if(event->type() == my_type){
           Event  *event = staic_cast<Event*>(e);
           if ((counter % 1000) == 0)
             qDebug() << counter << QTime::currentTime();
           event->incCounter(&counter);
//            ui->lcdNumber->display(counter);
      }
      QMainWindow:: customEvent(e);
}
Потом раскомментировать display и сравнить
Записан
demaker
Птица говорун
*****
Offline Offline

Сообщений: 962


Просмотр профиля
« Ответ #7 : Июнь 08, 2016, 08:25 »

Зачем нужно было затевать customEvent - хз, достаточно было просто сигнала.
Согасен, что достаточно было сигнала.
Или можно было значение счетчика скидывать в отдельную
переменную, защищенную  мьютексами, и брать значение из нее раз в секунду и обновлять lcdNumber.

Просто хотелось попробовать как все это работает.
И вопрос, если достаточно сигналов, тогда вообще зачем или в каком случае целесообразно
использовать customEvent  и кидать сообщения в главный цикл???
Записан
demaker
Птица говорун
*****
Offline Offline

Сообщений: 962


Просмотр профиля
« Ответ #8 : Июнь 08, 2016, 08:29 »

Цитата: Bepec link=topic=30тываться 205.msg222936#msg222936 date=1465323411
Вы уберите все обращения к ui в customEvent.
И обновляйте данные в отдельном слоте, допустим раз в 1 секунду.

Т.е  сообщения успевали бы обрабатываться, если бы ни Ui, правильно?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Июнь 08, 2016, 08:56 »

И вопрос, если достаточно сигналов, тогда вообще зачем или в каком случае целесообразно
использовать customEvent  и кидать сообщения в главный цикл???
Затрудняюсь привести такой случай

Т.е  сообщения успевали бы обрабатываться, если бы ни Ui, правильно?
Время проверки этого в отладчике меньше времени написания поста, не говоря уже о достоверности  Улыбающийся
Записан
demaker
Птица говорун
*****
Offline Offline

Сообщений: 962


Просмотр профиля
« Ответ #10 : Июнь 08, 2016, 09:42 »

И вопрос, если достаточно сигналов, тогда вообще зачем или в каком случае целесообразно
использовать customEvent  и кидать сообщения в главный цикл???
Затрудняюсь привести такой случай

Тогда интересно зачем Шлее описывает в своей книги подобный пример. Непонимающий
Так для общего знакомства  Улыбающийся чтобы было.
Записан
demaker
Птица говорун
*****
Offline Offline

Сообщений: 962


Просмотр профиля
« Ответ #11 : Июнь 08, 2016, 10:06 »

Зачем нужно было затевать customEvent - хз, достаточно было просто сигнала. Слабо верится что lcdNumber не справляется с перерисовкой за 20 ms (вагон времени). Это легко проверить напр так
Код
C++ (Qt)
void MainWindow::customEvent(QEvent *e)
{
       if(event->type() == my_type){
           Event  *event = staic_cast<Event*>(e);
           if ((counter % 1000) == 0)
             qDebug() << counter << QTime::currentTime();
           event->incCounter(&counter);
//            ui->lcdNumber->display(counter);
      }
      QMainWindow:: customEvent(e);
}
Потом раскомментировать display и сравнить

Проверил добавил вывод времени при старте и при значении счетчика 1200 и
закоментил вывод значения счетчика на графику.
И разница оказалось равной 1минута 15секунд = 75 секунд;  Шокированный
Так что дело не в Ui похоже или нет Непонимающий
Если не в Ui тогда в чем Непонимающий
« Последнее редактирование: Июнь 08, 2016, 10:33 от demaker » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

Проверил добавил вывод времени при старте и при значении счетчика 1200 и
закоментил вывод значения счетчика на графику.
И разница оказалось равной 1минута 15секунд = 75 секунд;  Шокированный
Так что дело не в Ui похоже или нет Непонимающий
Если не в Ui тогда в чем Непонимающий
Впечатление что Вы просто где-то насвистели в коде Улыбающийся (напр 16 в не 20). Выкладывайте тестовый проект
Записан
demaker
Птица говорун
*****
Offline Offline

Сообщений: 962


Просмотр профиля
« Ответ #13 : Июнь 08, 2016, 10:59 »

Вот проект
время таймаута 50мс т.е в секунду таймер срабатывает 20раз, а
в минуту соответственно 1200.
« Последнее редактирование: Июнь 08, 2016, 12:23 от demaker » Записан
Bepec
Гость
« Ответ #14 : Июнь 08, 2016, 12:42 »

 Плачущий
К сожалению у таймера имеется погрешность в +- 15 мс. Т.к. и linux и windows ОС НЕ реального времени.
В чём мы можем убедиться просто выведя время срабатывания слота таймера. Это раз.

Цитировать
Time tymeout =  QTime("12:35:28.513")
1
Time tymeout =  QTime("12:35:28.576")
2
Time tymeout =  QTime("12:35:28.639")
3
Time tymeout =  QTime("12:35:28.700")
4
Time tymeout =  QTime("12:35:28.763")
5
Time tymeout =  QTime("12:35:28.825")

Во 2 время обработки event'a выше вызова просто функции. Насколько - хз, тут уже надо смотреть глубже.
Т.е. ставя время сработки в 50 мс, будьте готовы ожидать срабатывание в 65 мс + неизвестное время обработки евента.

PS если вам нужна такая точность - вы явно выбрали не ту ОС Веселый Хотя вроде можно достигнуть точности +-1мс, но уже платформозависимыми функциями. (информация не проверенная)
« Последнее редактирование: Июнь 08, 2016, 12:44 от Bepec » Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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