K
K
Kirill H2016-12-15 22:01:53
Qt
Kirill H, 2016-12-15 22:01:53

Why aren't Qt slots processed?

There is a program, now I am remaking it for myself. Basically, there are functions:

QObject::connect(&timer, SIGNAL(timeout()), &scene, SLOT(advance()));
timer.start(1000 / 33);

They should not be processed in main, but packaged in their "TAaquarium" class.
The problem is that for some reason everything compiles, but apparently the slot or signal doesn't work.
In Qt not long ago, I'm trying to figure it out, but something is still not clear at this point.
Here is the code:
main.cpp
#include <QtWidgets>
#include <math.h>
#include "TFish.h"
#include "TAquarium.h"

int main(int argc, char **argv)     //Обязательно должны быть переаны "argc" - число аргументов Ком. Стр. и второй аргумент - их массив.
{
    QApplication app(argc, argv);   //QApplication управляет ресурсами приложения, например, задавая тип шрифта или курсора. Обязателен в графическом приложении Qt.
    qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));    //Точка рандома от которой будут генерироваться случайные значения, заданая системным временем. (После используется в mouse.cpp)

    QGraphicsScene scene;   //Класс QGraphicsScene предоставляет поверхность для управления большим числом графических 2D элементов.
    scene.setSceneRect(-300, -300, 600, 600);   //Описывает позицию и размеры окна сцены.

    scene.setItemIndexMethod(QGraphicsScene::NoIndex);  //Отключает индексирование анимированных элементов ускоряя работу приложения.

    TAquarium myAquarium;
    myAquarium.Init(&scene);

    QGraphicsView view(&scene);     //Отриссовывает сцену.
    view.setRenderHint(QPainter::Antialiasing);     //Улучшает качество рендеринга картинки, а конкретно "гладкого" отображения растровых изображений
    view.setBackgroundBrush(QPixmap(":/images/cheese.jpg"));       //Кисть для отрисовки баграунда сцены.

    view.setCacheMode(QGraphicsView::CacheBackground);      //Для ускорения отрисовки, текстуры кешируются, в данном случаи кешируется баграунд.
    //Определяет какая область должна обновлять своё содержимое.
    //В данном случаи пеерисовывает только то, что отображается в рамке окна.
    view.setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
    view.setDragMode(QGraphicsView::ScrollHandDrag);    //Повидение курсора, в данном случаи, если поле имеет скролл барры, то можно двигать сцену "рукой"

    view.setWindowTitle(QT_TRANSLATE_NOOP(QGraphicsView, "Aquarium"));    //Название запущенного окна
    view.resize(400, 300);      //Размер окна при запуске
    view.show();    //Отрисовка сцены.

//    QTimer timer;   //Класс таймера.

    //Тут надо понять механнику работы слотов и сигналов, (Второй абзац "Signals and Slots"): http://doc.qt.io/qt-4.8/signalsandslots.html#signals-and-slots
        //Как можно сделать не сложный вывод, 'SIGNAL(timeout())' - сигнал передаётся, когда таймер закончит своё действие
        //Слот 'advance()' - принемает значение, эта команда дважды вызывает все элементы:
            //1. Первый раз вызывает объекты с значением '0' (грубо говоря - инициализирует их).
            //2. Второй раз со значением '1', уже отображаются.
//    QObject::connect(&timer, SIGNAL(timeout()), &scene, SLOT(advance()));   //Переопределите эту функцию для обновления элемента если вам нужна простая анимация, контролируемая сценой.
//    timer.start(1000 / 33);     //От этого параметра зависит с какой частотой, обновляется сцена, т.е. как часто стартует таймер: 1000/33 ~ 30.3 милисекунд, т.е. получаем ~30 к/с.
    myAquarium.Run(&scene);

    return app.exec();      //Запускает основной цикл выполнения, ждёт завершения работы программы, либо функцию 'quit()'.
}

TAquarium.h
#ifndef TAQUARIUM_H
#define TAQUARIUM_H

#include <QGraphicsItem>
#include <QtWidgets>

class TAquarium
{
    static const int FishCount = 10;

public:

    TAquarium();

    void Init(QGraphicsScene * scene);
    void Run(QGraphicsScene * scene);
//    void Done();
};

#endif // TAQUARIUM_H

TAquarium.cpp
#include "TAquarium.h"
#include "TFish.h"
#include "math.h"

TAquarium::TAquarium()
{

}

void TAquarium::Init(QGraphicsScene * scene)
{
    for (int i = 0; i < FishCount; ++i) {              //Цикл по созданию мышей.
        TFish *fish = new TFish;                       //Указатель на новый объект "Мышь".
        fish->setPos(::sin((i * 6.28) / FishCount) * 200,     //Задаёт позицию для нового элемента "Мышь", по псевдослучайным координатам.
                      ::cos((i * 6.28) / FishCount) * 200);
        scene->addItem(fish);   //Добавляет объект "Мышь", на сцену, со всеми его потомками.
    }
}

void TAquarium::Run(QGraphicsScene * scene)
{
    QTimer timer;   //Класс таймера.
    //Тут надо понять механнику работы слотов и сигналов, (Второй абзац "Signals and Slots"): http://doc.qt.io/qt-4.8/signalsandslots.html#signals-and-slots
        //Как можно сделать не сложный вывод, 'SIGNAL(timeout())' - сигнал передаётся, когда таймер закончит своё действие
        //Слот 'advance()' - принемает значение, эта команда дважды вызывает все элементы:
            //1. Первый раз вызывает объекты с значением '0' (грубо говоря - инициализирует их).
            //2. Второй раз со значением '1', уже отображаются.


    QObject::connect(&timer, SIGNAL(timeout()), scene, SLOT(advance()));   //Переопределите эту функцию для обновления элемента если вам нужна простая анимация, контролируемая сценой.
    timer.start(1000 / 33);     //От этого параметра зависит с какой частотой, обновляется сцена, т.е. как часто стартует таймер: 1000/33 ~ 30.3 милисекунд, т.е. получаем ~30 к/с.
}

Answer the question

In order to leave comments, you need to log in

2 answer(s)
J
Jacob E, 2016-12-15
@KirillHelm

timer is created on the stack, after exiting the function it is deleted, there will be no signal.

R
RabraBabr, 2016-12-16
@RabraBabr

It should be something like this.
TAquarium.h

class TAquarium
{
    static const int FishCount = 10;

public:

    QTimer *timer;

    TAquarium();

    void Init(QGraphicsScene * scene);
    void Run(QGraphicsScene * scene);
};

Further so
TAquarium.cpp
void TAquarium::Run(QGraphicsScene * scene)
{
    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()),
              this, SLOT(OnTimerEvent()));
    timer->start(30);
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question