Задать вопрос
KirillHelm
@KirillHelm

Почему не отрабатываются слоты Qt?

Есть программа, сейчас переделываю под себя. Суть такая, есть функции:
QObject::connect(&timer, SIGNAL(timeout()), &scene, SLOT(advance()));
timer.start(1000 / 33);

Они должны обрабатываться не в main, а упакованные в свой класс "ТАаквариум".
Проблема в том, что почему-то всё компилируется, но по видимому, слот или сигнал не работает.
В Qt не давно, пытаюсь разобраться, но что-то пока этот момент не ясен.
Вот код:

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 к/с.
}
  • Вопрос задан
  • 687 просмотров
Подписаться 1 Оценить 4 комментария
Решения вопроса 1
Zifix
@Zifix Куратор тега Qt
Barbatum
timer создан на стеке, после выхода из функции удаляется, сигнала не будет.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
RabraBabr
@RabraBabr
Надо, что то вроде так.
TAquarium.h
class TAquarium
{
    static const int FishCount = 10;

public:

    QTimer *timer;

    TAquarium();

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


Далее так
TAquarium.cpp
void TAquarium::Run(QGraphicsScene * scene)
{
    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()),
              this, SLOT(OnTimerEvent()));
    timer->start(30);
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы