Изменить скорость с помощью таймера в QT создателе - PullRequest
0 голосов
/ 14 января 2019

Я пытаюсь переместить прямоугольную рамку поверх фонового изображения по траектории линии. Я использую Qtimer в QT создатель. Я использую openCV для взаимодействия с изображениями. Чтобы переместить его, я вызываю функцию generate_video() с интервалом времени.

1.) Я хочу изменить скорость, с которой движется прямоугольник. Для этого я использую горизонтальный ползунок в QT с именем horizontalSlider_speed. По сути, я понижаю интервал, с которым я звоню generate_video(). Когда я увеличиваю ползунок, я могу увеличить скорость, но я могу уменьшить скорость с более высокой скорости, даже если переместу ползунок до минимума.

2.) Я также записываю его, используя VideoWriter. Но он пропускает кадры, даже если я установил FPS на 120.

#include <QTimer>
MainWindow *MainWindowPtr;
using namespace cv;
int heightImg,widthImg,intensity,initialX,initialY,xSin;
int velocity=1;
Mat imageBack,imageObject,frame;
extern void generate_video();
QTimer *timer;
VideoWriter outputVideo;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
 ui->setupUi(this);
    imageBack= imread(filenameImg);
    outputVideo.open("outcpp.avi",CV_FOURCC('M','J','P','G'),24, 
    Size(imageBack.cols,imageBack.rows));
}

void MainWindow::on_pushButton_Generate_clicked()
{
    QTimer *timer = new QTimer;

    // make the connection using the timer variable
    connect(timer, &QTimer::timeout, this, &generate_video);

    // start the timer object by first dereferencing that object first
    timer->setInterval(100-MainWindowPtr->ui->horizontalSlider_speed->value());

    timer->start();
}

void generate_video()
{
    heightImg = MainWindowPtr->ui->lineEdit_Height->text().toInt();
    widthImg = MainWindowPtr->ui->lineEdit_Width->text().toInt();

imageBack= imread(filenameImg);

    cvtColor(imageBack, imageBack, cv::COLOR_RGB2GRAY);

    //draw rectangular object
    rectangle(imageBack,Point(initialX,initialY),Point(initialX+widthImg,initialY+heightImg),Scalar(intensity),-1,8,0);
    imshow("image",imageBack);

    //line trajectory

    if(initialX>640)
    initialX=0;
    else
    initialX+=2;

    //start recording
    if(recordFlag==1)
    {
        cv::cvtColor(imageBack, frame, cv::COLOR_GRAY2BGR);
        outputVideo.write(frame);
    }

}

void MainWindow::on_pushButton_Record_clicked()
{
 recordFlag=1; //start recording
}

Ответы [ 2 ]

0 голосов
/ 14 января 2019

Отлично, вы нашли ошибку самостоятельно! : -)

Вы создавали новую QTimer каждый раз, когда нажимали «Создать». Все эти таймеры постоянно срабатывали, потому что ни один из них не был остановлен.

Решение действительно заключается в использовании одного таймера, но вы можете пойти на шаг дальше, чем в своем ответе:

Вам нужно подключить его только один раз (в конструкторе MainWindow).

Затем в on_pushButton_Generate_clicked просто установите интервал на текущее требуемое значение и запустите таймер.

Если вы создаете свой таймер с помощью new QTimer(this), он становится QObject дочерним элементом вашего MainWindow и автоматически удаляется при уничтожении MainWindow. Это предотвращает возможные сбои, когда таймер пытается вызвать интервал ожидания generate_video(), хотя ваш MainWindow уже удален.

Кроме того, если вы хотите воспроизвести анимацию только один раз, вы можете просто остановить таймер, когда initialX достигнет 640.

0 голосов
/ 14 января 2019

Я нашел решение, используя Qtimer disconnect. Кроме того, нам не нужно объявлять это каждый раз, когда я нажимаю кнопку. Итак QTimer *timer = new QTimer; следует переместить в MainWindow::MainWindow() как timer = new QTimer, поскольку мы уже объявили его как глобальный. Поэтому новый код должен быть таким:

void MainWindow::on_pushButton_Generate_clicked()
{
    timer->disconnect();

    // make the connection using the timer variable
    connect(timer, &QTimer::timeout, this, &generate_video);

    // start the timer object by first dereferencing that object first
    timer->setInterval(100-MainWindowPtr->ui->horizontalSlider_speed->value());

    timer->start();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...