Russian Qt Forum

Qt => Вопросы новичков => Тема начата: smirnoff от Май 10, 2011, 19:38



Название: Таймер в консольном приложении. Базы данных.
Отправлено: smirnoff от Май 10, 2011, 19:38
Доброго всем времени суток.

Есть задача реализовать выгрузку неких данных в БД MSSQL по определенному интервалу. Реализация должна без проблем запускаться в linux и windows.

Для этого дабы не писать gui хочу реализовать консольное приложение.
Встал вопрос как реализовать таймер и функцию-обработчик события?

Код:
QTimer::singleShot(2000, &a, SLOT(f()));
не катит. Пишет что
Код:
No such slot QCoreApplication::f() in ...
Необходимо реализовать класс унаследованный от QCoreApplication в котором определить слот и таймер?

Как реализовать таймер?


Название: Re: Таймер в консольном приложении. Базы данных.
Отправлено: shirushizo от Май 10, 2011, 20:42
QCoreApplication переопределять не обязательно. Лучше создай свой класс, определи в нем все необходимые функции, а в main.cpp  оставь коннект к базе и настройки (кодировку и прочее).


Название: Re: Таймер в консольном приложении. Базы данных.
Отправлено: smirnoff от Май 10, 2011, 20:51
Вот так:
Код:
class tmr
{

public:
   void shot()
   {
      QTimer::singleShot(2000, NULL, SLOT(quit()));
   }

};

Однако почему-то в main пишу
Код:
tmr::shot();
ошибка...


Название: Re: Таймер в консольном приложении. Базы данных.
Отправлено: Пантер от Май 10, 2011, 20:54
А зачем ты NULL используешь???
QTimer::singleShot(2000, QCoreApplication::instance (), SLOT(quit()));
Где класс определяешь? Q_OBJECT не забудь.


Название: Re: Таймер в консольном приложении. Базы данных.
Отправлено: smirnoff от Май 10, 2011, 21:00
Весь код:
Код:
#include <QtCore/QCoreApplication>
#include <QTimer>
#include <iostream>

class tmr
{

public:
   void shot()
   {
      QTimer::singleShot(2000, QCoreApplication::instance(), SLOT(f()));
   }

public slots:
   void f();

};


void tmr::f()
{
  std::cout << "display test string";
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    tmr s;
    s.shot();

    return a.exec();
}

А почему
Код:
QCoreApplication::instance()
если у меня слот в моем классе а не в QCoreApplication?

Так нельзя. Пишет, что
Код:
No such slot QCoreApplication::f() in ...


Название: Re: Таймер в консольном приложении. Базы данных.
Отправлено: twp от Май 10, 2011, 21:21
ну так ты шлешь сигнал в QCoreApplication::instance() у него нет слота f(). Раз слот f() объявлен в tmr то ему и на до слать сигнал, и не забыть про Q_OBJECT как тебе уже выше написали:
Код:
class tmr
{
  Q_OBJECT
public:
   void shot()
   {
      QTimer::singleShot(2000, this, SLOT(f()));
   }

public slots:
   void f();
};


Название: Re: Таймер в консольном приложении. Базы данных.
Отправлено: smirnoff от Май 10, 2011, 21:24
ну так ты шлешь сигнал в QCoreApplication::instance() у него нет слота f(). Раз слот f() объявлен в tmr то ему и на до слать сигнал, и не забыть про Q_OBJECT как тебе уже выше написали:
Код:
class tmr
{
  Q_OBJECT
public:
   void shot()
   {
      QTimer::singleShot(2000, this, SLOT(f()));
   }

public slots:
   void f();
};

Так не работает:
Цитировать
D:/modul/modul-build-desktop/../modul/main.cpp:-1: In member function 'void tmr::shot()':
D:/modul/modul-build-desktop/../modul/main.cpp:11: ошибка: no matching function for call to 'QTimer::singleShot(int, tmr* const, const char*)'
c:\QtSDK\Desktop\Qt\4.7.3\mingw\include\QtCore/qtimer.h:78: candidates are: static void QTimer::singleShot(int, QObject*, const char*)

Ругается на
Код:
QTimer::singleShot(2000, this, SLOT(f()));


Название: Re: Таймер в консольном приложении. Базы данных.
Отправлено: twp от Май 10, 2011, 21:31
да, забыл написать что для работы сигналов/слотов класс должен наследоваться прямо или косвенно от QObject. в общем пробуй так
Код:
class tmr : public QObject
{
  Q_OBJECT
public:
   void shot()
   {
      QTimer::singleShot(2000, this, SLOT(f()));
   }

public slots:
   void f();
};
вот чтиво по этой теме
http://habrahabr.ru/blogs/qt_software/50812/ (http://habrahabr.ru/blogs/qt_software/50812/)


Название: Re: Таймер в консольном приложении. Базы данных.
Отправлено: smirnoff от Май 10, 2011, 22:02
Вот так все работает:
Код:
#include <QtCore/QCoreApplication>
#include <QTimer>
#include <QObject>
#include <iostream>

class Tmr : public QObject
{
   Q_OBJECT
public:
   Tmr()
   {
       QTimer::singleShot(2000, this, SLOT(shot()));
   }

public slots:
   void shot();
};

void Tmr::shot()
{
  std::cout << "display test string";
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    //Tmr s;
    //s.shot();

    return a.exec();
}

Но стоит в main создать объект класса
Код:
Tmr s;
s.shot();

как летят ошибки:
Цитировать
D:/modul/modul-build-desktop/debug/main.o:-1: In function `Tmr':
D:\modul\modul-build-desktop/../modul/main.cpp:11: ошибка: undefined reference to `vtable for Tmr'
D:/modul/modul-build-desktop/debug/main.o:-1: In function `~Tmr':
D:\modul\modul-build-desktop/../modul/main.cpp:7: ошибка: undefined reference to `vtable for Tmr'
:-1: ошибка: collect2: ld returned 1 exit status

В чем проблема?

P.S. Пример кода на http://habrahabr.ru/blogs/qt_software/50812/ (http://habrahabr.ru/blogs/qt_software/50812/) нерабочий ))) Сделал класс как описано там... При создании объекта класса - ошибка!


Название: Re: Таймер в консольном приложении. Базы данных.
Отправлено: mutineer от Май 10, 2011, 22:53
Попробуй вынести описание и реализацию своего класса в отдельные *.cpp и *.h файлы


Название: Re: Таймер в консольном приложении. Базы данных.
Отправлено: twp от Май 11, 2011, 11:42
Поскольку определение класса Tmr находится в cpp-файле, нужно явно включить moc-файл. Если бы определение Tmr было в *.h то не было бы никаких проблем. В общем пробуй так
Код:
#include <QtCore/QCoreApplication>
#include <QTimer>
#include <QObject>
#include <iostream>

class Tmr : public QObject
{
   Q_OBJECT
public:
   Tmr()
   {
       QTimer::singleShot(2000, this, SLOT(shot()));
   }

public slots:
   void shot();
};

void Tmr::shot()
{
  std::cout << "display test string";
}

#include "tmr.moc"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    Tmr s;
    s.shot();

    return a.exec();
}


Название: Re: Таймер в консольном приложении. Базы данных.
Отправлено: smirnoff от Май 11, 2011, 16:02
Всем спасибо. Заработало так:

main.cpp:
Код:
#include <QtCore/QCoreApplication>
#include <modul.h>

#include <iostream>

void Tmr::shot()
{
  std::cout << "display test string";
}

void Tmr::atimer(int msec)
{
    QTimer::singleShot(msec, this, SLOT(shot()));
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    Tmr tobj;
    tobj.atimer(10000);

    return a.exec();
}

modul.h:
Код:
#ifndef MODUL_H
#define MODUL_H

#include <QObject>
#include <QTimer>

class Tmr : public QObject
{
   Q_OBJECT
public:
   Tmr()
   {
   }

public slots:
   void shot();
   void atimer(int msec);
};

#endif // MODUL_H

Думаю у меня скоро еще возникнут вопросы )))