今天我们接着上一篇文章继续完善我们的一个小程序。QT5.14——模拟交通灯(一)
红绿灯交替
先来简单说一下是实现得原理,在上一篇文章的界面布局中我们已经知道红绿灯其实就是一张PNG图片,所以我们实现红绿灯的亮和灭就是通过图片的显示与否来实现的。这就用到QT中的hide()
和show()
函数。当然这和真实的红绿灯是有所区别的,我们在这里仅是简单的模拟,所以不必太较真,当然自己也可以在进行修改,模拟的更加真实。
- 红绿灯时间设置:红灯、绿灯25S,黄灯3S
- 初始状态东西通行,南北等待
我们先看看怎么显示和隐藏图片,我们在初始化函数中加入西面的代码片段:
//南北等待
ui->red_n->show(); //red_n是我定义的那个lable的objectName,表示北方向红灯,下面以此类推
ui->green_n->hide();
ui->yellow_n->hide();
ui->red_s->show();
ui->green_s->hide();
ui->yellow_s->hide();
//东西通行
ui->green_e->show();
ui->red_e->hide();
ui->yellow_e->hide();
ui->green_w->show();
ui->red_w->hide();
ui->yellow_w->hide();
效果图:
接下来做红绿灯的交替:
- 在mainwindow.h头文件中声明一些函数和定义一些变量。
public:
void LightTime();//红绿灯时间交替
private slots:
void doProcessTimeOut1();//南北
void doProcessTimeOut2();//东西
private:
Ui::MainWindow *ui;
QTimer *myTimer;
//两组红绿灯时间参数(1:南北 2:东西)
int count_red1;
int count_green1;
int count_yellow1;
int count_red2;
int count_green2;
int count_yellow2;
void Init();
};
- 实现函数功能
void MainWindow::LightTime(){
//初始化变量
count_red1 = 25;
count_green1 = -1;
count_yellow1 = 3;
count_red2 = -1;
count_green2 = 25;
count_yellow2 = 3;
//显示红绿灯时间
ui->lcd_e->display(count_green2);
ui->lcd_w->display(count_green2);
ui->lcd_n->display(count_red1);
ui->lcd_s->display(count_red1);
myTimer = new QTimer();
myTimer->start(1000); //启动QTimer
connect(myTimer,SIGNAL(timeout()),
this,SLOT(doProcessTimeOut1()));//绑定槽
connect(myTimer,SIGNAL(timeout()),
this,SLOT(doProcessTimeOut2()));//绑定槽
}
void MainWindow::doProcessTimeOut1(){
//如果红灯时间到,黄灯亮
if(count_red1 == 0){
count_yellow1--;
ui->lcd_n->display(count_yellow1);
ui->yellow_n->show();
ui->green_n->hide();
ui->red_n->hide();
ui->yellow_s->show();
ui->green_s->hide();
ui->red_s->hide();
ui->lcd_s->display(count_yellow1);
//如果黄灯时间到,绿灯亮
if(count_yellow1 == 0){
count_green1 = 25;
count_yellow1 = 3;
count_red1 = -1;
ui->lcd_n->display(count_green1);
ui->lcd_s->display(count_green1);
//重启定时器
myTimer->start(1000);
ui->green_n->show();
ui->yellow_n->hide();
ui->red_n->hide();
ui->green_s->show();
ui->yellow_s->hide();
ui->red_s->hide();
}
}
//如果红灯还有时间
else if(count_red1 > 0){
count_red1--;
ui->red_n->show();
ui->green_n->hide();
ui->yellow_n->hide();
ui->lcd_n->display(count_red1);
ui->red_s->show();
ui->green_s->hide();
ui->yellow_s->hide();
ui->lcd_s->display(count_red1);
}
//如果绿灯时间到,黄灯亮
if(count_green1 == 0){
count_yellow1--;
ui->green_n->hide();
ui->red_n->hide();
ui->yellow_n->show();
ui->green_s->hide();
ui->red_s->hide();
ui->yellow_s->show();
//如果黄灯时间到
if(count_yellow1 == 0){
count_green1 = -1;
count_red1 = 25;
count_yellow1 = 3;
//重启定时器
myTimer->start(1000);
ui->red_n->show();
ui->yellow_n->hide();
ui->green_n->hide();
ui->red_s->show();
ui->yellow_s->hide();
ui->green_s->hide();
}
}
//如果绿灯还有时间
else if(count_green1 > 0){
count_green1--;
ui->lcd_n->display(count_green1);
ui->green_n->show();
ui->yellow_n->hide();
ui->red_n->hide();
ui->lcd_s->display(count_green1);
ui->green_s->show();
ui->yellow_s->hide();
ui->red_s->hide();
//一会的小车代码
}
}
void MainWindow::doProcessTimeOut2(){
//如果绿灯时间到,黄灯亮
if(count_green2 == 0){
count_yellow2--;
ui->lcd_w->display(count_yellow2);
ui->yellow_w->show();
ui->green_w->hide();
ui->red_w->hide();
ui->yellow_e->show();
ui->green_e->hide();
ui->red_e->hide();
ui->lcd_e->display(count_yellow2);
//如果黄灯时间到,红灯亮
if(count_yellow2 == 0){
count_green2 = -1;
count_yellow2 = 3;
count_red2 = 25;
ui->lcd_w->display(count_red2);
ui->lcd_e->display(count_red2);
//重启定时器
myTimer->start(1000);
ui->green_w->hide();
ui->yellow_w->hide();
ui->red_w->show();
ui->green_e->hide();
ui->yellow_e->hide();
ui->red_e->show();
}
}
//如果绿灯还有时间
else if(count_green2 > 0){
count_green2--;
ui->red_w->hide();
ui->green_w->show();
ui->yellow_w->hide();
ui->lcd_w->display(count_green2);
ui->red_e->hide();
ui->green_e->show();
ui->yellow_e->hide();
ui->lcd_e->display(count_green2);
//一会小车代码
}
//如果红灯时间到,黄灯亮
if(count_red2 == 0){
count_yellow2--;
ui->green_w->hide();
ui->red_w->hide();
ui->yellow_w->show();
ui->green_e->hide();
ui->red_e->hide();
ui->yellow_e->show();
//如果黄灯时间到
if(count_yellow2 == 0){
count_green2 = 25;
count_red2 = -1;
count_yellow2 = 3;
ui->lcd_w->display(count_green2);
ui->lcd_e->display(count_green2);
//重启定时器
myTimer->start(1000);
ui->red_w->hide();
ui->yellow_w->hide();
ui->green_w->show();
ui->red_e->hide();
ui->yellow_e->hide();
ui->green_e->show();
}
}
//如果红灯还有时间
else if(count_red2 > 0){
count_red2--;
ui->lcd_w->display(count_red2);
ui->green_w->hide();
ui->yellow_w->hide();
ui->red_w->show();
ui->lcd_e->display(count_red2);
ui->green_e->hide();
ui->yellow_e->hide();
ui->red_e->show();
}
}
这里一定不要忘记调用LightTime()
函数,不然,你懂的!!
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
// setWindowFlags(windowFlags()&~Qt::WindowMaximizeButtonHint); // 禁止最大化按钮
ui->setupUi(this);
Init();
LightTime();
}
到此为止,红绿灯的交替已经完成了。
小车移动
- 小车速度控制,我们通过一个延时函数进行实现。
在mainwindow.h文件中加入头文件,声明一个sleep()
函数。
#include <QTime>
private slots:
void doProcessTimeOut1();//南北
void doProcessTimeOut2();//东西
void sleep(unsigned int msec);//延时函数,控制小车速度
实现函数:
//延时函数,控制小车速度
void MainWindow::sleep(unsigned int msec)
{
QTime newTime = QTime::currentTime().addMSecs(msec);
while(QTime::currentTime() < newTime)
QCoreApplication::processEvents(QEventLoop::AllEvents,100);
}
- 小车的运动实现用到了一个关键函数
setGeometry(int x, int y, int w, int h)
。
官方文档解释:
void QWidget::setGeometry(int x, int y, int w, int h)
This is an overloaded function.//这是一个重载函数。
This corresponds to setGeometry(QRect(x, y, w, h)).//这对应于setGeometry(QRect(x,y,w,h))。
Note: Setter function for property geometry. //注:属性几何的Setter函数。
QRect::QRect(int x, int y, int width, int height)
Constructs a rectangle with (x, y) as its top-left corner and the given width and height.
//构造一个以(x,y)为左上角、给定宽度和高度的矩形。
了解了如何使用这个函数之后,我们才能知道如何让小车行走。
声明函数及变量:
#define STOP 1
#define RUN 2
public:
void LightTime();//红绿灯时间交替
void carup_run();//小车正常向北行驶
void carup_stop();//小车向北停止
void up_through();//遇到红绿灯情况
void carleft_run();//小车正常向西行驶
void carleft_stop();//小车向西停止
void left_through();//遇到红绿灯情况
private:
int carup_state;//向北行驶小车状态
int carleft_state;//向西行驶小车状态
界面布局中加入四条Line,用来控制小车遇到红灯的停止,加入一个按钮,控制小车的启动。
函数功能实现:
void MainWindow::carup_run(){
carup_state = RUN;
ui->car_up->setGeometry(ui->car_up->x(),ui->car_up->y(),
ui->car_up->width(),
ui->car_up->height());
//向上走
for(int i=ui->car_up->y();i+ui->car_up->height()>=ui->stopline_s->y()+120;--i)
{
ui->car_up->setGeometry(ui->car_up->x(),i,
ui->car_up->width(),
ui->car_up->height());
sleep(10);
}
if(count_red1>0) carup_stop();
if(count_green1>=0) up_through();
}
void MainWindow::carup_stop(){
carup_state = STOP;
ui->car_up->setGeometry(ui->car_up->x(),ui->car_up->y(),
ui->car_up->width(),
ui->car_up->height());
}
void MainWindow::up_through(){
for(int i=ui->car_up->y();i+ui->car_up->height()>0;--i)
{
ui->car_up->setGeometry(ui->car_up->x(),i,
ui->car_up->width(),
ui->car_up->height());
sleep(10);
}
}
在void MainWindow::doProcessTimeOut1()
中插入
//一会的小车代码
if(carup_state == STOP){
carup_state = RUN;
up_through();
}
按钮槽函数:
void MainWindow::on_btn_start_clicked()
{
carup_run();
}
到此就可以实现南北通行小车行驶,东西小车实现方法按照同样的方式即可实现,代码不再展示。
这样QT模拟交通灯的小程序就已经实现了。
存在问题:两辆小车不能同时行走,程序不够完善!有兴趣的可以自行改进,也欢迎找我进行探讨!
喜欢的可以点个赞再走哦!!!