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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Вопрос по реализации будильника в программе  (Прочитано 11302 раз)
Noir
Гость
« : Июнь 07, 2009, 03:52 »

Добрый день!

подскажите, пожалуйста, как прикрутить будильник в данной программе? перепробовал разные варианты, пытался всунуть QTimer::singleshot в метод getAlarmTime, но, однако, не получается Грустный По идее, нужна ежесекундная проверка на соответствие текущего времени заданному пользователем, но никак не могу додуматься, как это реализовать ...

widget.cpp
Код:
#include <QtGui>
#include "widget.h"

void Timer::updateTime()
{
    QTime time = QTime::currentTime();
    QString text = time.toString("hh:mm");
    lcd->display(text);
}

void Timer::playAlarm()
{
    QMessageBox::information(this, "Alarm", "Good Morning");
    // добавить воспроизведение мелодии
}

void Timer::getAlarmTime()
{
    bool OK;
    int hours = QInputDialog::getInt(this, "Input Hours",
                                 "Hour: ", 12, 0, 23, 1, &OK);

    int minutes = QInputDialog::getInt(this, "Input Minutes",
                                 "Minutes: ", 30, 0, 59, 1, &OK);
}

Timer::Timer()
{
    timer = new QTimer;

    set = new QPushButton("Set");
    quit = new QPushButton("Quit");

    set->setMinimumSize(160, 20);
    quit->setMinimumSize(160, 20);

    lcd = new QLCDNumber;
    lcd->setSegmentStyle(QLCDNumber::Flat);
    lcd->setFrameStyle(2);
    lcd->setMinimumSize(160, 50);

    layout = new QVBoxLayout;

    layout->setMargin(10);
    layout->setSpacing(10);

    layout->addWidget(lcd);
    layout->addWidget(set);
    layout->addWidget(quit);

    this->setLayout(layout);

    QObject::connect(timer, SIGNAL(timeout()), this, SLOT(updateTime()));
    timer->start(500);

    updateTime();

    QObject::connect(quit, SIGNAL(clicked()),
                     qApp, SLOT(quit()));

    QObject::connect(set, SIGNAL(clicked()),
                     this, SLOT(getAlarmTime()));
}

PS. Да, исполнение задания времени будильника крайне халтурно, но ничего не поделать, я слишком новичок..
« Последнее редактирование: Июнь 07, 2009, 03:54 от Noir » Записан
ритт
Гость
« Ответ #1 : Июнь 07, 2009, 04:55 »

слабенько, слабенько...не вижу даже установки таймера.
а в остальном - всё довольно примитивно - я бы сделал циклический таймер и по таймауту сравнивал бы текущее время с предустаноленным. таким макаром в будущем можно завести множество будильников на одном таймере.
секундный таймаут имело бы устанавливать только для ежесекундного обновления счётчика (или часов); либо же можно ограничиться интервалом порядка, скажем, 10-20 секунд...
Записан
Noir
Гость
« Ответ #2 : Июнь 07, 2009, 06:31 »

слабенько, слабенько...не вижу даже установки таймера.
а в остальном - всё довольно примитивно - я бы сделал циклический таймер и по таймауту сравнивал бы текущее время с предустаноленным. таким макаром в будущем можно завести множество будильников на одном таймере.
секундный таймаут имело бы устанавливать только для ежесекундного обновления счётчика (или часов); либо же можно ограничиться интервалом порядка, скажем, 10-20 секунд...

Спасибо за ответ

На самом деле, делал уже вот так:
Код:
void Timer::playAlarm()
{
    QMessageBox::information(this, "Alarm", "Good Morning");
    // добавить воспроизведение мелодии
}

void Timer::getAlarmTime()
{
    bool OK;
    int alarm_hour = QInputDialog::getInt(this, "Input Hours",
                                 "Hour: ", 12, 0, 23, 1, &OK);

    int alarm_minute = QInputDialog::getInt(this, "Input Minutes",
                                 "Minutes: ", 30, 0, 59, 1, &OK);

    QTime qtime_time = QTime::currentTime();

    QString qstring_hour = qtime_time.toString("hh");
    QString qstring_minute = qtime_time.toString("mm");

    int current_hour = qstring_hour.toInt();
    int current_minute = qstring_hour.toInt();

    int delay_hour;

    if (current_hour > alarm_hour)
    {
        delay_hour = ((24 - current_hour) + alarm_hour);
    } else if ((current_hour == alarm_hour) && (current_minute < alarm_minute))
    {
        delay_hour = 0;
    } else if ((current_hour == alarm_hour) && (current_minute > alarm_minute))
    {
        delay_hour = 23;
    } else
        delay_hour = (alarm_hour - current_hour);

    int delay_minute;

    if (current_minute > alarm_minute)
    {
        delay_minute = ((60 - current_minute) + alarm_minute);
    } else
    {
        delay_minute = (alarm_minute - current_minute);
    }

    int delay = (((alarm_hour * 3600) + (alarm_minute * 60)) * 1000);

    QTimer::singleShot(delay, this, SLOT(playAlarm()));
}

Но, по окончанию работы таймера слот playAlarm() никак не хочет вызываться. Не пойму совершенно, что не так =\
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #3 : Июнь 07, 2009, 08:33 »

Посмотри пример: %QTDIR%\examples\widgets\analogclock
там таймер каждую секунду перерисовывает часы. Ну а ты будешь вместо перерисовки исполнять какие-то действия.
Записан

Юра.
Noir
Гость
« Ответ #4 : Июнь 07, 2009, 13:34 »

Посмотри пример: %QTDIR%\examples\widgets\analogclock
там таймер каждую секунду перерисовывает часы. Ну а ты будешь вместо перерисовки исполнять какие-то действия.

простите, а чем отличается таймер аналоговых часов в экзампле
Код:
     QTimer *timer = new QTimer(this);
     connect(timer, SIGNAL(timeout()), this, SLOT(update()));
     timer->start(1000);

от написанного в конструкторе (см. первый пост)

Код:
    QObject::connect(timer, SIGNAL(timeout()), this, SLOT(updateTime()));
    timer->start(500);

я уже пробовал вместо QTime::singleShot запускать отдельный таймер, типа
Код:
    
    ...
    QObject::connect(alarm_timer, SIGNAL(timeout()), this, SLOT(playAlarm()));
    alarm_timer->start(delay);

но после задания желаемого времени будильника приложение "неожиданно закрывается", т.е., по видимому, сегфолт..
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #5 : Июнь 07, 2009, 15:38 »

>>простите, а чем отличается таймер аналоговых часов в экзампле
тем, что в примере ему начзначается родитель, и после удаления родителя, его детё (таймер) будет тоже удалено. Т.е. высвободится память.

>>приложение "неожиданно закрывается"
Закоментируй весь код в слоте, и проверь как программа себя вести будет.
Записан

Юра.
Noir
Гость
« Ответ #6 : Июнь 07, 2009, 17:03 »

>>приложение "неожиданно закрывается"
Закоментируй весь код в слоте, и проверь как программа себя вести будет.

Код:
void Timer::playAlarm()
{
    //QMessageBox::information(this, "Alarm", "Good Morning");
    // добавить воспроизведение мелодии
}

если это то, что вы имели ввиду, то ничего ровным счетом не изменилось.
Записан
igor_bogomolov
Гость
« Ответ #7 : Июнь 07, 2009, 17:07 »

Timer::Timer()
    QObject::connect(alarm_timer, SIGNAL(timeout()), this, SLOT(playAlarm()));

Сигналы и слоты
Цитировать
Все классы, содержащие сигналы и слоты, должны упомянуть макрос Q_OBJECT в начале своей декларации. Также они должны происходить (прямо или косвенно) от QObject.
Записан
Noir
Гость
« Ответ #8 : Июнь 07, 2009, 17:29 »

Timer::Timer()
    QObject::connect(alarm_timer, SIGNAL(timeout()), this, SLOT(playAlarm()));

Сигналы и слоты
Цитировать
Все классы, содержащие сигналы и слоты, должны упомянуть макрос Q_OBJECT в начале своей декларации. Также они должны происходить (прямо или косвенно) от QObject.

Если я вас правильно понял, то это есть:
widget.h
Код:
class Timer : public QWidget
{
    Q_OBJECT
...
}
Записан
igor_bogomolov
Гость
« Ответ #9 : Июнь 07, 2009, 17:52 »

Попробуй немного переделать конструктор класса

Код
C++ (Qt)
Timer(QWidget *parent = 0);
 
Timer::Timer(QWidget *parent) : QWidget(parent)
{
   ....
}
Записан
Noir
Гость
« Ответ #10 : Июнь 07, 2009, 18:03 »

Попробуй немного переделать конструктор класса

Код
C++ (Qt)
Timer(QWidget *parent = 0);
 
Timer::Timer(QWidget *parent) : QWidget(parent)
{
   ....
}

переделал:
widget.h
Код
C++ (Qt)
class Timer : public QWidget
{
   Q_OBJECT
 
public:
   Timer(QWidget *parent = 0);
...
}
 

widget.cpp
Код
C++ (Qt)
void Timer::getAlarmTime()
{
   ...
   QTimer::singleShot(delay, this, SLOT(playAlarm()));
}
 

Код
C++ (Qt)
Timer::Timer(QWidget *parent) : QWidget(parent)
{
  ...
  QObject::connect(set, SIGNAL(clicked()),
                    this, SLOT(getAlarmTime()));
}

программа на синглшот все еще не реагирует вообще никак, а если использовать обычный таймер - опять же вылетает.
Записан
igor_bogomolov
Гость
« Ответ #11 : Июнь 07, 2009, 18:08 »

Если хочешь, приатач проект, я посмотрю что не так
Записан
Noir
Гость
« Ответ #12 : Июнь 07, 2009, 18:13 »

Если хочешь, приатач проект, я посмотрю что не так

ну, вот... Спасибо вам большое заранее  Подмигивающий
Записан
sLiva
Гость
« Ответ #13 : Июнь 07, 2009, 18:56 »

Если хочешь, приатач проект, я посмотрю что не так

ну, вот... Спасибо вам большое заранее  Подмигивающий

Глубоко не смотрел но сразу же дебагом увидел неправильный расчет задержки delay, которая при задание будильника на минуту показывает delay_minute = 34, delay = 71580000

Проверяй расчет задержки...
Записан
igor_bogomolov
Гость
« Ответ #14 : Июнь 07, 2009, 18:57 »

Ну ты конечно начудил с расчетом времени. Текущее время 19,30. Завожу на 19,31. deley = 70260000  Шокированный

Подправил тебе. Диалог выбора времени сам доделаешь, идея и так должна быть понятна. Сейчас выставляешь требуемое время, и нажимаешь крестик. В нужное время будильник сработает Улыбающийся

---
Да, расчет паузы тоже сам доделаешь. Сейчас можно менять только секунды. Пользуйся QTimeEdit
« Последнее редактирование: Июнь 07, 2009, 19:03 от igor_bogomolov » Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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