QTimer с QPaintEvent

Я создал небольшое приложение QT, которое перерисовывает круг в произвольном месте. Что я хотел бы сделать, так это повторить метод заданное количество раз, что рисует круг каждую секунду с использованием QTimer.

Я не уверен, как это сделать.

Вот мой main.cpp

int main(int argc, char *argv[]) {
    // initialize resources, if needed
    // Q_INIT_RESOURCE(resfile);

     srand (time(NULL));
    QApplication app(argc, argv);

    widget f;
    f.show();

    return app.exec();
}

widget.cpp

#include "widget.h"

widget::widget()
{
   widget.setupUi(this);
}
void widget::paintEvent(QPaintEvent * p)
{
QPainter painter(this);
//**code


   printcircle(& painter); //paints the circle

    //**code
}

void paintcircle(QPainter* painter)
{
   srand (time(NULL));
   int x = rand() %200 + 1;
   int y = rand() %200 + 1;

   QRectF myQRect(x,y,30,30);
   painter->drawEllipse(myQRect);


    }


widget::~widget()
{}

widget.h

#ifndef _WIDGET_H
#define _WIDGET_H

class widget : public QWidget {
    Q_OBJECT
public:
    widget();
    virtual ~widget();

public slots:
    void paintEvent(QPaintEvent * p);  
    private:
    Ui::widget widget;
};

#endif  /* _WIDGET_H */

Как мне создать Qtimer для повторения метода printcricle().

Спасибо


person Leo    schedule 18.04.2014    source источник


Ответы (2)


Вы можете создать таймер в конструкторе класса виджета следующим образом:

 QTimer *timer = new QTimer(this);
 connect(timer, SIGNAL(timeout()), this, SLOT(update()));
 timer->start(1000);

т.е. он будет вызывать событие рисования виджета каждую секунду.

person vahancho    schedule 18.04.2014

Правильно, есть несколько вещей, которые нужно изменить в вашем коде, чтобы выполнить это:

  • Вперед объявить QTimer

  • Добавить член QTimer

  • Включите заголовок QTimer.

  • Установите непрерывный QTimer в конструкторе вашего класса виджета.

  • Убедитесь, что вы установили соединение со слотом update, чтобы перерисовка была запланирована циклом событий.

  • Вам нужно добавить счетчик для заданного времени, так как в QTimer нет такой функции.

  • Вам нужно инициализировать эту переменную до нуля.

  • Вам нужно увеличивать это в каждом вызове слота.

  • Вам нужно перестать излучать сигнал тайм-аута для QTimer.

Чтобы добиться всего вышеперечисленного, ваш код должен выглядеть примерно так:

виджет.cpp

#include "widget.h"

#include <QTimer>

// Could be any number
const static int myPredeterminedTimes = 10;

widget::widget()
    : m_timer(new QTimer(this))
    , m_count(0)
{
    widget.setupUi(this);
    connect(m_timer, SIGNAL(timeout()), SLOT(update()));
    timer->start(1000);
}
void widget::paintEvent(QPaintEvent * p)
{
QPainter painter(this);
//**code


   printcircle(& painter); //paints the circle

    //**code
}

void widget::paintcircle(QPainter* painter)
{
   srand (time(NULL));
   int x = rand() %200 + 1;
   int y = rand() %200 + 1;

   QRectF myQRect(x,y,30,30);
   painter->drawEllipse(myQRect);


    }


widget::~widget()
{}

виджет.h

#ifndef _WIDGET_H
#define _WIDGET_H

class QTimer;

class widget : public QWidget {
    Q_OBJECT
public:
    widget();
    virtual ~widget();

public slots:
    void paintEvent(QPaintEvent * p);  
    private:
    Ui::widget widget;

private:
    QTimer *m_timer;
    int m_count;
};

#endif  /* _WIDGET_H */
person lpapp    schedule 19.04.2014
comment
Использование QPainter вне paintEvent(QPaintEvent *) не будет работать ( qt-project.org/faq /ответ/ ). Правильным будет подключить сигнал таймера к слоту update(), а затем заставить paintEvent() сделать там соответствующий рисунок. Кроме того, динамическое выделение нового объекта QPainter при каждом вызове (и никогда его удаление) в конечном итоге съест всю вашу оперативную память. - person Jeremy Friesner; 19.04.2014
comment
@JeremyFriesner: исправлено. - person lpapp; 19.04.2014