本次实验涉及Qt中的绘图来绘制资源图片,使用 connect
信号连接手动控制图片的移动以及通过定时器来实现自动控制。
需求描述
如下图:当程序运行后,程序中的图片会自动向屏幕右侧移动,直至消失后再次出现在屏幕中,依此循环。期间可以通过按钮手动控制暂停和继续,也能通过手动调整相应位置。
最终效果图:
需求分析
- 控制区域应该区分开来分为手动/自动
- 若在自动时切换手动控制自动应不受影响
- 手动按钮应该支持长按加减位置
- 图片移动区域应不能超过屏幕最大宽度
- UI 界面设置最小尺寸,控制区和图片区域互不影响
备注:所使用Qt版本为5.14.2,Qt Creator版本为4.11.1
功能实现
上文提及到的定时器已在上次实验完成,以下便不再详细说明。
实验原理
首先创建一个 QDialog 窗口类型,需要勾选UI界面(Generate form),然后在UI中添加相应区域并添加所属控件。引入定时器来实现自动移动图片,PushButton 来手动控制。
资源图片载入
这里建议将需要加载的图片放在当前文件夹下,然后添加一个新的资源文件即可,剩下的都是默认操作,最好使用英文(名称、前缀、文件名),添加完成构建即可。
UI 界面
利用Stacked Widget
+ Radio Button
来区分自动和手动两种选择按钮,采用的是栅格化布局以及加上水平和垂直的弹簧使页面能够做到响应式。
相关代码
以下代码中,需要注意:
- 变量
result
应在 dialog.h 中声明为全局。 - 函数
paintEvent
应重写,否则绘图将会不显示。 - 控件
Stacked Widget
要注意填入setCurrentIndex
的索引值(index)。
widget.h:
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include <QTimer>
QT_BEGIN_NAMESPACE
namespace Ui { class Dialog; }
QT_END_NAMESPACE
class Dialog : public QDialog
{
Q_OBJECT
public:
Dialog(QWidget *parent = nullptr);
~Dialog();
// 绘图事件
void paintEvent(QPaintEvent *);
int result = 0; // 记录值
private:
Ui::Dialog *ui;
};
#endif // DIALOG_H
widget.cpp:
#include "dialog.h"
#include "ui_dialog.h"
#include <QDebug>
#include <QPainter> // 画家类
Dialog::Dialog(QWidget *parent)
: QDialog(parent)
, ui(new Ui::Dialog)
{
ui->setupUi(this);
/*********** 定时器对象 *************/
QTimer * timer = new QTimer(this);
timer->start(100); // 启动定时器 1s
connect(timer, &QTimer::timeout, [=](){
result += 20;
update(); // 更新图片位置
});
/********* 手/自(栈控件) **********/
ui->rBtnAuto->setChecked(true);
connect(ui->rBtnAuto, &QRadioButton::clicked, [=](){
// 自动 ->> 0
ui->stackedWidget->setCurrentIndex(0);
});
connect(ui->rBtnManual, &QRadioButton::clicked, [=](){
// 手动 ->> 1
ui->stackedWidget->setCurrentIndex(1);
});
/////////// 自动控制按钮 //////////
connect(ui->auto_btn, &QPushButton::clicked, [=](){
if(ui->auto_btn->text() == "暂停")
{
timer->stop();
ui->auto_btn->setText("启动");
}
else
{
timer->start();
ui->auto_btn->setText("暂停");
}
});
/////////// 手动控制按钮 //////////
ui->btnAdd->setAutoRepeat(true); //启用长按
ui->btnReduce->setAutoRepeat(true);
ui->btnAdd->setAutoRepeatDelay(200); //触发长按的时间
ui->btnReduce->setAutoRepeatDelay(200);
ui->btnAdd->setAutoRepeatInterval(20); //长按时click信号间隔
ui->btnReduce->setAutoRepeatInterval(20);
connect(ui->btnAdd, &QPushButton::clicked, [=](){
// 若是自动状态,则手动控制无效
if(ui->rBtnManual->isChecked() && ui->auto_btn->text() == "启动")
result += 10;
update(); // 更新图片位置
});
connect(ui->btnReduce, &QPushButton::clicked, [=](){
if(ui->rBtnManual->isChecked() && ui->auto_btn->text() == "启动")
result -= 10;
update(); // 更新图片位置
});
}
void Dialog::paintEvent(QPaintEvent *)
{
/************ 资源图片 **************/
// 重新回到屏幕
if(result > this->width())
// 露头
result = -200;
QPainter painter(this);
painter.drawPixmap(result, 20, 200, 200, QPixmap(":/img/plane.png"));
}
Dialog::~Dialog()
{
delete ui;
}
以上代码仅供参考。如若有任何问题和建议,还望大佬指正!
点赞~~
给你点个赞。程序员的想法总是这么棒!