首页 > 解决方案 > 在 QT creator 中使用计时器更改速度

问题描述

我正在尝试以直线轨迹在背景图像顶部移动一个矩形框。我在 QT creator 中使用 Qtimer。我正在使用 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
}

标签: c++qtopencvtimer

解决方案


太好了,你自己发现了这个错误!:-)

QTimer每次单击“生成”时,您都在创建一个新的。所有这些计时器都在不断地触发,因为没有一个被停止。

解决方案确实是使用单个计时器,但您可以比您的答案更进一步:

您只需要连接一次(在您的MainWindow构造函数中)。

然后,在 中on_pushButton_Generate_clicked,只需将时间间隔设置为当前所需值并启动计时器。

如果你用 来创建你的计时器new QTimer(this),它会成为QObject你的一个孩子,并在被销毁MainWindow时自动删除。MainWindow这可以防止当计时器尝试调用超时槽时可能发生的崩溃,generate_video()尽管你MainWindow已经被删除了。

此外,如果您只想播放一次动画,您可以在initialX达到 640 时停止计时器。


推荐阅读