Russian Qt Forum

Qt => Вопросы новичков => Тема начата: QPeter от Февраль 28, 2014, 02:02



Название: Таймер с обратным отсчетом
Отправлено: QPeter от Февраль 28, 2014, 02:02
Возникла необходимость создать таймер, по истечении времени которого будут происходить некоторые действия. Пытался создать глобальную переменную, и присвоить ей значение вводимое в TimeEdit,  и чтоб по нажатию кнопки время начинало уменьшаться в  другом поле TimeEdit(если будет легче сделать чтоб вместо timeEdit был другой элемент отображения, то можно заменить). Ну и собственно когда таймер будет на 00:00 сделать некоторые действия. Могу представить алгоритм всего этого, он собственно совсем не сложный, а с реализацией туго как то..(

Код:
class Widget : public QWidget
{
...
    QTimer t1;//создание глобальной переменной
Код:
 QObject::connect(ui->timeEdit, SIGNAL(timeChanged(QTime)), t1, SLOT(setTime(QTime)));//неправильное присвоение значения.)
    QObject::connect(ui->pbStart, SIGNAL(clicked()), this, SLOT(Timer()));
Код:
void Widget::Timer()
{
   do{
        t1->addSecs(-100);//уменьшение значения таймера
    }while(t1==0);

    ui->tabWidget_2->setCurrentIndex(2);//какие то действия
  }

С учётом моей неспособности точно излагать свои мысли покажу всё наглядно:
1)(http://cs617629.vk.me/v617629502/3a31/JITRIxMNZiI.jpg)
2)(http://cs617629.vk.me/v617629502/3a28/LZcec3ZY48U.jpg)


Название: Re: Таймер с обратным отсчетом
Отправлено: OKTA от Февраль 28, 2014, 07:25
Читаем документацию на QTimer:

Код:
Example for a one second (1000 millisecond) timer (from the Analog Clock example):
     QTimer *timer = new QTimer(this);
     connect(timer, SIGNAL(timeout()), this, SLOT(update()));
     timer->start(1000);
From then on, the update() slot is called every second.


interval : int
This property holds the timeout interval in milliseconds.
The default value for this property is 0. A QTimer with a timeout interval of 0 will time out as soon as all the events in the window system's event queue have been processed.
Setting the interval of an active timer changes its timerId().
Access functions:
int interval () const
void setInterval ( int msec )


Название: Re: Таймер с обратным отсчетом
Отправлено: QPeter от Март 01, 2014, 17:52
А объявлять переменную нужно в заголовочном файле или в исходнике? Просто мне же нужно будет использовать переменную потом в других функциях, поэтому наверное следовало бы объявить ей глобально в заголовочном файле, но тогда как к ней привязать этот connect?
 И как правильно присвоить значение то которое вводится в timeEdit к переменной?
Код:
 
QTimer* t3=new QTimer(this);
connect(t3, SIGNAL(timeout()), this, SLOT(update()));
t3->start(1000);


QObject::connect(ui->timeEdit, SIGNAL(timeChanged(QTime)), t3, SLOT(setTime(QTime)));
- так???


Название: Re: Таймер с обратным отсчетом
Отправлено: QPeter от Март 02, 2014, 23:41
 :'( :'( :'(

Помогите сделать таймер с обратным отсчётом с использованием timeEdit..(


Название: Re: Таймер с обратным отсчетом
Отправлено: kambala от Март 03, 2014, 00:41
давай составим алгоритм действий, а ты его сам реализуешь.

- слот нажатия кнопки: считать введенное время (на твоей картинке это №1) и поместить его в оставшееся время (№3); запустить таймер, срабатывающий каждую секунду (1000 мс).
- слот срабатывания таймера: считать время из оставшегося (№3), отнять от него 1 с (1000 мс), записать полученный результат в оставшееся время (№3); если результат равен нулю, остановить таймер.


Название: Re: Таймер с обратным отсчетом
Отправлено: QPeter от Март 03, 2014, 01:49
Алгоритм я себе давно представить смог, даже рисовал, с реализацией проблемы и работой  с timeEdit.
Цитировать
- слот нажатия кнопки: считать введенное время (на твоей картинке это №1) и поместить его в оставшееся время (№3);
Код:
QObject::connect(ui->timeEdit_2, SIGNAL(timeChanged(QTime)), ui->timeEdit, SLOT(setTime(QTime)));
Цитировать
запустить таймер, срабатывающий каждую секунду (1000 мс).
Код:
    
    QTimer* countdown=new QTimer(this);//время в верхнем углу
    connect(countdown, SIGNAL(timeout()),this,SLOT(update_time_down()));
    countdown->start(1000);
И тут уже возникает вопрос, мне же нужна глобальная переменная, получается её нужно в заголовочном файле объявлять. И тогда как, где connect правильно прописывать? Или надо вообще ещё одну переменную создать Qtime и к ней значения присваивать потом?

Цитировать
- слот срабатывания таймера: считать время из оставшегося (№3), отнять от него 1 с (1000 мс), записать полученный результат в оставшееся время (№3); если результат равен нулю, остановить таймер.
Код:
void Widget::update_time_down()
{
[u]//считать время из оставшегося (№3)- как это сделать?[/u]
countdown.addSecs(-1000);//предполагаю что это тоже не самая правильная реализация, тк значение наверное должно чему то присваиваться или оно и так сработает??
[u]записать полученный результат в оставшееся время (№3);- так же как и с присвоением переменной значения в timeEdit, как это сделать?[/u]
if(countdown==0)
{
     connect(countdown, SIGNAL(timeout()),this,SLOT(stop()));//вроде это делается как то так
}
}


Название: Re: Таймер с обратным отсчетом
Отправлено: OKTA от Март 03, 2014, 09:50
Вы о какой переменной?  ???


Название: Re: Таймер с обратным отсчетом
Отправлено: QPeter от Март 03, 2014, 12:51
к которой нужно присваивать значение из timeEdit.


Название: Re: Таймер с обратным отсчетом
Отправлено: OKTA от Март 03, 2014, 12:55
Можно и переменную, но тяжко советовать что-либо, пока неизвестно, как там у тебя внутри все устроено)


Название: Re: Таймер с обратным отсчетом
Отправлено: QPeter от Март 03, 2014, 12:57
Всё устроено примитивно)

https://drive.google.com/file/d/0B_y-nG4qALcOREdIakhfc2J1TmM/edit?usp=sharing  - собран в qt 5.2.1
https://drive.google.com/file/d/0B_y-nG4qALcOQl9Xc3U4SldkN2s/edit?usp=sharing - собран в 4.8


Название: Re: Таймер с обратным отсчетом
Отправлено: QPeter от Март 03, 2014, 13:11
А кстати как пере собрать проект, который был создан в qt 4.8, в qt 5.2? А то кучу ошибок выдает.


Название: Re: Таймер с обратным отсчетом
Отправлено: OKTA от Март 03, 2014, 13:14
Если все так, то читайте время прямо из гуи, когда надо.
А чтобы пересобрать, надо взять и почитать что-нибудь типа http://qt-project.org/wiki/Transition_from_Qt_4.x_to_Qt5


Название: Re: Таймер с обратным отсчетом
Отправлено: QPeter от Март 03, 2014, 13:20
Цитировать
Если все так, то читайте время прямо из гуи, когда надо
-как, как  это сделать???

Ооо спасибо)
...а на русском нету? А то Google Translate не совсем идеально переводит)
 ::) ::)


Название: Re: Таймер с обратным отсчетом
Отправлено: kambala от Март 03, 2014, 13:32
переменную таймера сделать полем класса, таймер создай и законнекть в конструкторе, в слотах только вызывай ему старт/стоп (это просто вызов соответствующего метода). все остальное решается чтением документации (нахождением нужных методов), это я за тебя делать не буду.

время читается не из таймера, а из таймэдита.


Название: Re: Таймер с обратным отсчетом
Отправлено: QPeter от Март 03, 2014, 13:41
Так  а вы мне можете сказать как переменной присвоить значение из timeEdit ? как то так?
Код:
 QTimer* countdown=new QTimer(this);//время в верхнем углу
    connect(countdown, SIGNAL(timeout()),this,SLOT(update_time_down()));
    countdown->start(1000);
connect(ui->timeEdit, SIGNAL(timeChange(QTime)), countdown, SLOT(setTime(QTime)))


Название: Re: Таймер с обратным отсчетом
Отправлено: OKTA от Март 03, 2014, 14:08
А что мешает попробовать так сделать?  ???


Название: Re: Таймер с обратным отсчетом
Отправлено: kambala от Март 03, 2014, 14:46
я же сказал: почитай какие у таймэдита (и его предков) есть методы, тут не надо никаких сигналов. когда ты читаешь текст из текстэдита, ты же не сигналами пользуешься.

первый и последний раз (тут даже догадаться можно): QTime time () const.


Название: Re: Таймер с обратным отсчетом
Отправлено: Igors от Март 03, 2014, 15:14
[off]
Цитировать
..самая младшая - пика, самая старшая - черва, а есть еще "5" - без козыря... и.т.д.
Процедура обучения та же самая - и столь же мучительна  :)
[/off]


Название: Re: Таймер с обратным отсчетом
Отправлено: Alexu007 от Март 06, 2014, 09:11
Я написал эту прогу с глобальными переменными и и глобальным таймером - всё работает. Но когда я попытался сделать из "быдлокода" объектно-ориентированный, а именно: переменные из глобальных поместить в объявление класса в private, а сам таймер вместо глобального создавать в конструкторе класса - компилятор в слотах и обработчиках кнопок перестал его видеть.
 
widget.cpp:106: ошибка: 'myTimer' was not declared in this scope

Что ему не хватает?


Название: Re: Таймер с обратным отсчетом
Отправлено: OKTA от Март 06, 2014, 09:15
Покажи код - быстрее будет.


Название: Re: Таймер с обратным отсчетом
Отправлено: kambala от Март 06, 2014, 12:45
видно таймер не является полем класса. ты наверное его сделал локальной переменной в конструкторе.


Название: Re: Таймер с обратным отсчетом
Отправлено: Alexu007 от Март 06, 2014, 15:46
Код
C++ (Qt)
#include "widget.h"
#include "ui_widget.h"
 
 
 
 
//QTimer* myTimer = new QTimer();
 
 
 
Widget::Widget(QWidget *parent) :
   QWidget(parent),
   ui(new Ui::Widget)
{
   ui->setupUi(this);
 
   ui->lcdNumber->setNumDigits(8);
 
   QTimer* myTimer = new QTimer();
 
   QObject::connect(ui->pushButton_1, SIGNAL(clicked()), this, SLOT(MyEventButton_1()));
   QObject::connect(ui->pushButton_2, SIGNAL(clicked()), this, SLOT(MyEventButton_2()));
 
   QObject::connect(myTimer, SIGNAL(timeout()), this, SLOT(MyEventHandlerTimer()));
}
 
 
 
 
Widget::~Widget()
{
   delete myTimer;
   delete ui;
}
 
...
...

Вот так, как закомментировано - глобальный таймер - работает. Если создание таймера перенести в конструктор - не видит. Как его сделать полем класса? Если в класс в private поместить QTimer* myTimer; а в конструктор класса     QTimer* myTimer = new QTimer(); - то компилируется и запускается. Но при нажатии кнопки "старт" - там где запускается таймер - программа вылетает.

Sorry, сам догадался. В класс нада QTimer* myTimer;, а в конструктор myTimer = new QTimer();


Название: Re: Таймер с обратным отсчетом
Отправлено: QPeter от Март 07, 2014, 01:51
А не сложно весь проект целиком скинуть?)


Название: Re: Таймер с обратным отсчетом
Отправлено: Alexu007 от Март 07, 2014, 07:18
Бедненький! Вы всё мучаетесь с этим таймером! Это практически самое простое, что можно запрограммировать в Qt, ну после "Hello World" ессно. Всего-то несколько строчек кода написать нада...

Выложить весь проект целиком, к сожалению, не могу - это было бы некорректно по отношению к другим участникам форума.

Вам нужно самому научиться работать с кнопкой (на форме должна же быть хоть одна кнопка: "Старт") и с таймером. Это очень просто. Легко гуглится. В этом же форуме есть раздел "Готовые решения". Там в самом начале есть несколько выложенных мной (Alexu007) проектов - открывайте какой попроще (например который преобразует "123" в "сто двадцать три") и смотрите, как там реализована работа с кнопкой. Вам для начала нужно сделать форму с кнопкой и меткой label, чтобы при нажатии кнопки в label появлялся любой текст: "Hello World" - классика. Если сделаете это, я вам помогу с таймером.


Название: Re: Таймер с обратным отсчетом
Отправлено: QPeter от Март 07, 2014, 13:14
Это- то я сделаю запросто. У меня проблема именно при работе с переменными типа времени.


Название: Re: Таймер с обратным отсчетом
Отправлено: Alex Custov от Март 07, 2014, 13:22
Это- то я сделаю запросто. У меня проблема именно при работе с переменными типа времени.

Ты не знаешь С++, а уже хочешь писать на Qt. Твоё будущее стандартно - насилование форума бесконечными стандартными вопросами. В твоих же силах его изменить.


Название: Re: Таймер с обратным отсчетом
Отправлено: QPeter от Март 07, 2014, 13:36
https://drive.google.com/file/d/0B_y-nG4qALcOYW03MDZJQzJGSU0/edit?usp=sharing
Вот если уж не верите.

Цитировать
Ты не знаешь С++, а уже хочешь писать на Qt. Твоё будущее стандартно - насилование форума бесконечными стандартными вопросами. В твоих же силах его изменить.
Возможно, но всё же мои обстоятельства складываются так, что по-другому я пока не могу.
Конечно нельзя во всех своих бедах винить кого-то кроме себя, но нынешняя система образования - ооочень далека от совершенства. И по итогам обучения  студентам выставляют довольно высокие требования к итоговой разработке. Основное из этих требований, "чтоб всё было красиво". По мне так Qt самый удачный вариант для разработки приложения с приятным пользовательским интерфейсом. И в общем пока всё не сделаю, буду наверное всех мучать, прости те уж бедолагу.


Название: Re: Таймер с обратным отсчетом
Отправлено: OKTA от Март 07, 2014, 14:06
Лучшее образование - самообразование  ;D


Название: Re: Таймер с обратным отсчетом
Отправлено: QPeter от Март 07, 2014, 14:59
Цитировать
Лучшее образование - самообразование 
На самом деле- да..) Единственное что при изучении самостоятельно, ты не ставишь себе строгие временные рамки, по выходу из которых обучение может закончится.)


Название: Re: Таймер с обратным отсчетом
Отправлено: OKTA от Март 07, 2014, 15:09
 ??? а как же учиться всю жизнь  ???


Название: Re: Таймер с обратным отсчетом
Отправлено: Alexu007 от Март 07, 2014, 15:15
Это- то я сделаю запросто. У меня проблема именно при работе с переменными типа времени.
Я cделал вот так:

Код
C++ (Qt)
   #include <QTime>
   #include <QTimer>
 
...
...
 
   int hor = ui->lineEdit_hour->text().toInt();
   int min = ui->lineEdit_min-> text().toInt();
   int sec = ui->lineEdit_sec-> text().toInt();
 
   QString text = QTime(hor, min, sec).toString("hh:mm:ss");
 
   ui->lcdNumber->display(text);

А это в обработчике timeout таймера:

Код
C++ (Qt)
       ...
       ...
 
           sec--;
           if(sec < 0) {min--; sec = 59;}
           if(min < 0) {hor--; min = 59;}
 
       ....
       ...



Название: Re: Таймер с обратным отсчетом
Отправлено: QPeter от Март 07, 2014, 16:49
OKTA видимо я не ясно выразился.)
Если вдруг ты чего не будешь успевать изучить или если просто появятся какие нибудь дела и не до учебы будет, и позже осознав что ты давно не учился, сможешь всегда сесть и продолжить обучение. Так сказать сам себе учитель, а если учишься в каком то учебном заведении, данная возможность отсутствует или имеет ограниченное количество времени.)


Название: Re: Таймер с обратным отсчетом
Отправлено: QPeter от Март 07, 2014, 16:55
Alexu007 получается у тебя 3 lineEdit в которых ты по очереди вводишь сначала часы, потом минуты, затем секунды? Далее присваиваешь это всё целочисленным переменным и запихиваешь в lcd дисплей?

Я думал ты сделал с timeEdit.(


Название: Re: Таймер с обратным отсчетом
Отправлено: Alexu007 от Март 07, 2014, 19:26
Вроде как timeEdit это ввод даты и времени со встроенным календарём - слишком мощно для простого таймера.


Название: Re: Таймер с обратным отсчетом
Отправлено: QPeter от Март 07, 2014, 21:46
в timeEdit вводится только время. А дата, время, календарь есть только в "Date/Time Edit".
А как значение из timeEdit вытащить не знаешь? Чтоб было так же как у тебя, только вместо 3 полей-одно.


Название: Re: Таймер с обратным отсчетом
Отправлено: gil9red от Март 07, 2014, 21:56
в timeEdit вводится только время. А дата, время, календарь есть только в "Date/Time Edit".
А как значение из timeEdit вытащить не знаешь? Чтоб было так же как у тебя, только вместо 3 полей-одно.
http://qt-project.org/doc/qt-4.8/qdatetimeedit.html#time-prop


Название: Re: Таймер с обратным отсчетом
Отправлено: kambala от Март 07, 2014, 22:40
А как значение из timeEdit вытащить не знаешь? Чтоб было так же как у тебя, только вместо 3 полей-одно.
первый и последний раз (тут даже догадаться можно): QTime time () const.


Название: Re: Таймер с обратным отсчетом
Отправлено: Alexu007 от Март 08, 2014, 07:48
Вот, нагуглил, может пригодится:

http://f1-delphi.ru/books/qt_4_programmirovanie_gui_na_s/realizatsiya_polzovatelskix_de/3.html

Код
C++ (Qt)
06 QTime time = timeEdit->time();
07 int secs = (time.minute() * 60) + time.second();



Название: Re: Таймер с обратным отсчетом
Отправлено: kambala от Март 08, 2014, 10:52
а количество часов ты решил проигнорировать? ;)


Название: Re: Таймер с обратным отсчетом
Отправлено: Alexu007 от Март 08, 2014, 15:42
Достаточно 1 раз увидеть, как это делается с секундами, дальше дело техники. Ставишь точку после time и выбираешь из списка то что нужно.