c++ - 在 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
}
解决方案
太好了,你自己发现了这个错误!:-)
QTimer
每次单击“生成”时,您都在创建一个新的。所有这些计时器都在不断地触发,因为没有一个被停止。
解决方案确实是使用单个计时器,但您可以比您的答案更进一步:
您只需要连接一次(在您的MainWindow
构造函数中)。
然后,在 中on_pushButton_Generate_clicked
,只需将时间间隔设置为当前所需值并启动计时器。
如果你用 来创建你的计时器new QTimer(this)
,它会成为QObject
你的一个孩子,并在被销毁MainWindow
时自动删除。MainWindow
这可以防止当计时器尝试调用超时槽时可能发生的崩溃,generate_video()
尽管你MainWindow
已经被删除了。
此外,如果您只想播放一次动画,您可以在initialX
达到 640 时停止计时器。
推荐阅读
- function - 函数链接时遇到 None 可以立即返回吗?
- firebase - 如何使用 Rest API Javascript 向 Firestore 数据库添加新文档
- php - 如何同时使用 Digest 和 Basic Auth
- c# - 字符串到六进制字符串增加长度
- spring-boot - 如何在运行服务器时删除springboot中的登录页面(http://localhost:8080/login)同时在eclipse中导入Gradle项目
- winapi - 如何使用cabinet.dll API 调用将文件从VBA 添加到cab 文件?
- bazel - 执行从 bazel 规则作为参数传递的打字稿文件
- html - 如何让这个电话(样机)图像越过它的父容器?所以它看起来像在设计示例中
- c++ - 在继承层次结构中从成员函数销毁和重新创建当前对象
- c# - 从 json 获取项目并将其作为 Blazor wasm 中的参数传递