Witam. Jest może w C++ funkcja która będzie wywoływała inną funkcję co pewien czas? Wiem że są sleep oraz delay. Ale mnie chodzi raczej aby zawsze co np 1 sekundę była wywoływana jakaś funkcja niezależnie od tego co dzieje się w programie. Taki wątek który wykonuje operacje co pewien czas.
- Rejestracja:ponad 10 lat
- Ostatnio:ponad 7 lat
- Postów:39
Jak to zrobiłeś? Ja mam podobny problem.
Mianowicie: zrobiłem klasę diody, wsadziłem 7 diod w moduł(osobna klasa) i cały moduł wyświetlam w mainwindow. I tak z poziomu mainwindow włączam lub wyłączam kontrolki modul->setOn(index). Przy tym mechaniźmie chcę pozostać i jednocześnie rozbudować diodę o mruganie. W tym celu dioda ma zmienna mode (1-swiatlo ciagle, 2-migowe wolne, 3-migowe szybkie). mode oczywiście ustawiam za pośrednictwem modulu. Niestety w przypadku mode > 1 obiekt i tak zachowuje się tak samo jak w sytuacji przy mode = 1; czyli timer albo nie startuje albo nie daje sygnalu, albo(i raczej na pewno) ja coś źle rozumiem.
dioda.h
#ifndef DIODA_H
#define DIODA_H
#include <QWidget>
#include <QPainter>
#include <QTimer>
#define FAST_DELAY 250
#define SLOW_DELAY 500
class dioda : public QWidget{
Q_OBJECT
private:
void paintEvent(QPaintEvent *);
void blink(int delay);
QColor paintColor;
QColor onColor;
QColor offColor;
bool state;
int shift;
int radius;
int mode;
QTimer *timer;
public:
dioda();
void setOnColor(QColor color);
void setOffColor(QColor color);
bool setMode(int i);
void setShift(int s);
void setRadius(int r);
public slots:
void setOn();
void setOff();
};
#endif // DIODA_H
dioda.cpp
#include "dioda.h"
dioda::dioda(){
offColor = Qt::gray;
onColor = Qt::white;
paintColor = offColor;
shift = 10;
radius = 10;
state = false;
mode = 1;
timer = new QTimer(this);
connect(timer,SIGNAL(timeout()),this,SLOT(setOn()));
}
void dioda::paintEvent(QPaintEvent *){
QPainter dioda(this);
dioda.setRenderHints(QPainter::SmoothPixmapTransform | QPainter::Antialiasing);
QRadialGradient gradient(shift+radius/2, shift+radius/2, radius/2, shift+radius/4, shift+radius/4);
paintColor == Qt::black ? gradient.setColorAt(0.2, Qt::darkGray) : gradient.setColorAt(0.2, Qt::white);
gradient.setColorAt(0.8, paintColor);
gradient.setColorAt(1.0, Qt::black);
dioda.setPen((QPen(Qt::black, 0, Qt::SolidLine, Qt::RoundCap, Qt::MiterJoin)));
dioda.setBrush(QBrush(gradient));
dioda.drawEllipse(shift,shift,radius,radius);
}
void dioda::setOnColor(QColor color){
onColor = color;
repaint();
}
void dioda::setOffColor(QColor color){
onColor = color;
repaint();
}
bool dioda::setMode(int i){
if(i<1 || i>3) return false;
mode = i;
/*if(i>1) {
timer = new QTimer(this);
connect(timer,SIGNAL(timeout()),this,SLOT(setOn()));
}*/
return true;
}
void dioda::setOn(){
switch(mode){
case 1:
paintColor = onColor;
state = true;
repaint();
break;
case 2:
blink(SLOW_DELAY);
break;
case 3:
blink(FAST_DELAY);
break;
default:break;
}
}
void dioda::setOff(){
paintColor = offColor;
state = false;
repaint();
}
void dioda::setShift(int s){
shift = s;
repaint();
}
void dioda::setRadius(int r){
radius = r;
repaint();
}
void dioda::blink(int delay){
if(state) paintColor = offColor;
else paintColor = onColor;
repaint();
//timer->setInterval(delay);
//timer->setSingleShot(true);
timer->start(delay);
}
modul.cpp - fragment przykładu sterowania kontrolką led
led = new dioda();
led->setMode(2);
led->setOn();

- Rejestracja:ponad 13 lat
- Ostatnio:prawie 3 lata
- Postów:4882
temat jest stary, wiec watpie zeby Ci odpowiedzial
mozesz zrobic to na dwa sposoby
- (lepszy) uruchom osobny watek ktory bedzie sobie odliczal czas i co jakis N wywolywal ta funkcje
- gdzies w jakies funkcji ktora wykonuje sie co kazdy obieg programu wrzuc to samo co trzeba napisac w 1
napisanie kodu bedzie praktycznie takie samo, jednak jest roznica gdzie go "umiescisz"
- Rejestracja:ponad 10 lat
- Ostatnio:ponad 7 lat
- Postów:39
Nigdy nie używałem jeszcze wątków. Proponujesz abym utworzył klasę dziedziczącą po QThread która z każdym shotem swojego prywatnego timera będze wywoływał funkcję setOn() z klasy dioda, a obiekt nowej klasy tworzyć wewnątrz obiektu diody, tak?
mainwindow
->modul
->dioda
->wątek
(?)
@Edit
uzależniłem się od zmienej state ale w metodzie blink jej niezmieniałem. wystarczyło dodać state=!state;
void dioda::blink(int delay){
if(state) paintColor = offColor;
else paintColor = onColor;
state=!state;
repaint();
//timer->setInterval(delay);
//timer->setSingleShot(true);
timer->start(delay);
}
i działa ale tylko w ostatnim utworzonym obiekcie tego typu - dlaczego?

- Rejestracja:prawie 11 lat
- Ostatnio:ponad 3 lata
- Lokalizacja:Szczecin
- Postów:500
przykładowe użycie timera,
QTimer* timer = new QTimer;
timerHandles_[addr] = std::unique_ptr<QTimer>(timer); // mapa, która trzyma timer
timerTasks_[timer] = f; // mapa, która trzyma zadanie dla timera (std::function<void()> const&)
connect(timer, SIGNAL(timeout()),
this, SLOT(repeatLastMessage())); // funkcja handlująca sygnał timeout, sygnał ten jest emitowany co czas, który podasz w start.
timer->start(msec); // start
te mapy mam dlatego, aby móc obsłużyć kilka timerów w 1 funkcji handlującej (repeatLastMessage()), na podstawie obiektu który wyemitował sygnał (QObject::sender()), wybierasz zadanie dla timera

- Rejestracja:prawie 11 lat
- Ostatnio:ponad 3 lata
- Lokalizacja:Szczecin
- Postów:500
// nagłówek, musi być bo qt moc nie ogarnie tego w main
#ifndef OBJ_H
#define OBJ_H
#include <memory>
#include <QObject>
#include <QTimer>
class Obj : public QObject
{
Q_OBJECT
public:
explicit Obj() : timer_(nullptr) {}
void startMyTimer(int msecs);
public slots:
void repeatTask();
private:
std::unique_ptr<QTimer> timer_;
};
void Obj::startMyTimer(int msecs)
{
if(timer_) {
return;
} else {
timer_ = std::make_unique<QTimer>();
QObject::connect(timer_.get(), SIGNAL(timeout()),
this, SLOT(repeatTask()));
timer_->start(msecs); // start
}
}
void Obj::repeatTask()
{
std::cout << "Timer here !\n";
}
#endif // OBJ_H
// main
#include <iostream>
#include <QCoreApplication>
#include "obj.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Obj obj;
obj.startMyTimer(2000);
a.exec();
}
zbuduj sobie projekt i zobacz jak to działa