描述,在停车场外设计红绿灯十字路口,实现两辆车A和B,A车路线过红绿灯不进停车场,B车过红绿灯且进入停车场,可循环进行
效果图
红绿灯为四个或者可以成为两对,因为同一条路两边的红绿灯显示效果是一样的,红绿灯的控制函数如下
void MainWindow::wheel1(){
QImage image6(":/picture/yellow.jpg");
ui->Yellow_1->setPixmap(QPixmap::fromImage(image6));
ui->Yellow_4->setPixmap(QPixmap::fromImage(image6));
ui->Yellow_5->setPixmap(QPixmap::fromImage(image6));
ui->Yellow->setPixmap(QPixmap::fromImage(image6));
ui->Yellow_1->hide();
ui->Yellow->hide();
ui->Yellow_4->hide();
ui->Yellow_5->hide();
QImage image7(":/picture/green.jpg");
ui->Green_1->setPixmap(QPixmap::fromImage(image7));
ui->Green->setPixmap(QPixmap::fromImage(image7));
ui->Green_4->setPixmap(QPixmap::fromImage(image7));
ui->Green_5->setPixmap(QPixmap::fromImage(image7));
ui->Green_1->hide();
ui->Green->hide();
//ui->Green_4->show();
//ui->Green_5->show();
QImage image8(":/picture/red.jpg");
ui->Red_1->setPixmap(QPixmap::fromImage(image8));
ui->Red->setPixmap(QPixmap::fromImage(image8));
ui->Red_4->setPixmap(QPixmap::fromImage(image8));
ui->Red_5->setPixmap(QPixmap::fromImage(image8));
ui->Red_4->hide();
ui->Red_5->hide();
}
void MainWindow::run()
{
settimer1 = 20;
settimer2 = -1;
settimer3 = 3;
settimer4 = 20;
settimer5 = -1;
settimer6 = 3;
ui->lcdNumber_1->setDigitCount(2);
ui->lcdNumber_1->setMode(QLCDNumber::Dec);
ui->lcdNumber_1->setSegmentStyle(QLCDNumber::Filled);
ui->lcdNumber->setDigitCount(2);
ui->lcdNumber->setMode(QLCDNumber::Dec);
ui->lcdNumber->setSegmentStyle(QLCDNumber::Filled);
ui->lcdNumber_4->setDigitCount(2);
ui->lcdNumber_4->setMode(QLCDNumber::Dec);
ui->lcdNumber_4->setSegmentStyle(QLCDNumber::Filled);
ui->lcdNumber_5->setDigitCount(2);
ui->lcdNumber_5->setMode(QLCDNumber::Dec);
ui->lcdNumber_5->setSegmentStyle(QLCDNumber::Filled);
ui->lcdNumber_1->display(settimer1);
ui->lcdNumber->display(settimer1);
ui->lcdNumber_4->display(settimer4);
ui->lcdNumber_5->display(settimer4);
timer = new QTimer();
timer->setInterval(1000);
timer->start();
connect(timer,SIGNAL(timeout()),this, SLOT(onTimerOutA()));
connect(timer,SIGNAL(timeout()),this, SLOT(onTimerOutB()));
//connect(this,SIGNAL(greenflag),this, SLOT(throughLight()));
wheel1();
}
void MainWindow::onTimerOutA(){
cout<<"settimer1="<lcdNumber_1->display(settimer3);
ui->Green_1->hide();
ui->Yellow_1->show();
ui->Red_1->hide();
ui->lcdNumber->display(settimer3);
ui->Green->hide();
ui->Yellow->show();
ui->Red->hide();
if(settimer3==0)
{
ui->Green_1->show();
//ui->red->hide();
ui->Yellow_1->hide();
ui->Green->show();
//ui->red->hide();
ui->Yellow->hide();
settimer2 = 20;
settimer1=-1;
settimer3=3;
ui->lcdNumber_1->display(settimer2);
ui->lcdNumber->display(settimer2);
timer->setInterval(1000);
timer->start();
}
}
else if(settimer1>0)
{
settimer1--;
ui->Red_1->show();
ui->Yellow_1->hide();
ui->Green_1->hide();
ui->lcdNumber_1->display(settimer1);
ui->Red->show();
ui->Yellow->hide();
ui->Green->hide();
ui->lcdNumber->display(settimer1);
}
if(settimer2==0)
{
settimer3--;
ui->lcdNumber_1->display(settimer3);
ui->Green_1->hide();
ui->Yellow_1->show();
ui->Red_1->hide();
ui->lcdNumber->display(settimer3);
ui->Green->hide();
ui->Yellow->show();
ui->Red->hide();
if(settimer3==0)
{
ui->Red->show();
//ui->red->hide();
ui->Yellow->hide();
ui->Red_1->show();
//ui->red->hide();
ui->Yellow_1->hide();
settimer1 = 20;
settimer2=-1;
settimer3=3;
ui->lcdNumber_1->display(settimer1);
ui->lcdNumber->display(settimer1);
timer->setInterval(1000);
timer->start();
}
}
else if(settimer2>0)
{
settimer2--;
ui->lcdNumber_1->display(settimer2);
ui->Green_1->show();
ui->Yellow_1->hide();
ui->Red_1->hide();
ui->lcdNumber->display(settimer2);
ui->Green->show();
ui->Yellow->hide();
ui->Red->hide();
if(car_stateA==STOP)
{
car_stateA=RUN;throughLightA();
}
}
}
void MainWindow::onTimerOutB()
{
cout<<"settimer4="<lcdNumber_4->display(settimer6);
ui->Red_4->hide();
ui->Green_4->hide();
ui->Yellow_4->show();
ui->lcdNumber_5->display(settimer6);
ui->Red_5->hide();
ui->Green_5->hide();
ui->Yellow_5->show();
if(settimer6==0)
{
ui->Green_5->show();
//ui->red->hide();
ui->Yellow_5->hide();
ui->Green_4->show();
//ui->red->hide();
ui->Yellow_4->hide();
settimer4 = 20;
settimer5=-1;
settimer6=3;
ui->lcdNumber_4->display(settimer4);
ui->lcdNumber_5->display(settimer4);
timer->setInterval(1000);
timer->start();
}
}
else if(settimer5>0)
{
settimer5--;
ui->lcdNumber_4->display(settimer5);
ui->Red_4->show();
ui->Green_4->hide();
ui->Yellow_4->hide();
ui->lcdNumber_5->display(settimer5);
ui->Red_5->show();
ui->Green_5->hide();
ui->Yellow_5->hide();
}
if(settimer4==0)
{
settimer6--;
ui->lcdNumber_4->display(settimer6);
ui->Red_4->hide();
ui->Green_4->hide();
ui->Yellow_4->show();
ui->lcdNumber_5->display(settimer6);
ui->Red_5->hide();
ui->Green_5->hide();
ui->Yellow_5->show();
if(settimer6==0)
{
ui->Red_4->show();
//ui->red->hide();
ui->Yellow_4->hide();
ui->Red_5->show();
//ui->red->hide();
ui->Yellow_5->hide();
settimer5 = 20;
settimer4=-1;
settimer6=3;
ui->lcdNumber_4->display(settimer5);
ui->lcdNumber_5->display(settimer5);
timer->setInterval(1000);
timer->start();
}
}
else if(settimer4>0)
{
settimer4--;
ui->Red_4->hide();
ui->Yellow_4->hide();
ui->Green_4->show();
ui->lcdNumber_4->display(settimer4);
ui->Red_5->hide();
ui->Yellow_5->hide();
ui->Green_5->show();
ui->lcdNumber_5->display(settimer4);
if(car_stateB==STOP)
{
car_stateB=RUN;throughLightB();
}
}
}
若出现B车红灯停止后绿灯在继续前进但是红绿灯静止,必然是if的逻辑出了问题
停车场的实现在上一篇博客已经挂出了代码,这里详细解释一下
栅栏开关上,出和入原理相同
首先,是判断何时开启与关闭,方法为获取小车的坐标,当期等于某一相对参考坐标时,触发FencesEnterOn();函数,开启栅栏。而何时关闭的思路和它是一样的,当小车过了栅栏到达某一相对参考坐标时,触发FencesEnterOff();
然后就是栅栏如何开启,在ui界面里,假设栅栏是line,那么通过line的height减去某一值来实现将线缩短,模拟栅栏开启,同理加上这一值恢复。这段方法里采用的是栅栏所横跨道路两边的坐标相减获取这一distance。这里要注意一下,这个值不能等于定义的栅栏的height,这样整条线就消失了,在运行时,是不会产生栅栏的长短变化的
实现其的代码如下
//红外检测入口栅栏打开
void MainWindow::FencesEnterOn()
{
int distanceInEnterDoor = ui->Roadentance_2->y()-ui->Roadentance_1->y();
ui->fencesEnter->setGeometry(ui->fencesEnter->x(),
ui->fencesEnter->y(),
ui->fencesEnter->width(),
ui->fencesEnter->height() - distanceInEnterDoor);
}
//红外检测入口栅栏关闭
void MainWindow::FencesEnterOff()
{
int distanceInEnterDoor = ui->Roadentance_2->y()-ui->Roadentance_1->y();
ui->fencesEnter->setGeometry(ui->fencesEnter->x(),
ui->fencesEnter->y(),
ui->fencesEnter->width(),
ui->fencesEnter->height()+distanceInEnterDoor);
}
//检测入口栅栏何时打开
void MainWindow::FencesPowerRu(int car_x,int car_y)
{
int fences_x = ui->fencesEnter->x();
int car_h = ui->Car_2->height();
for(int i=car_x; i-car_h>fences_x+5; --i)
{
ui->Car_2->setGeometry(i,car_y,
ui->Car_2->width(),
ui->Car_2->height());
sleep(20);
}
FencesEnterOn();
}
//红外检测入口栅栏何时关闭
void MainWindow::RedEnterCheckRu(int car_x,int car_y)
{
if(car_x + ui->Car_2->height() == ui->enterRed->x())
FencesEnterOff();
}
//红外检测出口栅栏打开
void MainWindow::FencesExitOn()
{
int distanceInExitDoor = ui->Roadexit_2->y()-ui->Roadexit_1->y();
ui->fencesExit->setGeometry(ui->fencesExit->x(),
ui->fencesExit->y(),
ui->fencesExit->width(),
ui->fencesExit->height()-distanceInExitDoor);
}
//红外检测出口栅栏关闭
void MainWindow::FencesExitOff()
{
int distanceInExitDoor = ui->Roadexit_2->y()-ui->Roadexit_1->y();
ui->fencesExit->setGeometry(ui->fencesExit->x(),
ui->fencesExit->y(),
ui->fencesExit->width(),
ui->fencesExit->height()+distanceInExitDoor);
}
//检测出口栅栏何时打开
void MainWindow::FencesPowerChu(int car_a,int car_b)
{
int fences_x = ui->fencesExit->x();
int car_h = ui->Car_2->height();
for(int i=car_a; i-car_h>fences_x+5; --i)
{
ui->Car_2->setGeometry(i,car_b,
ui->Car_2->width(),
ui->Car_2->height());
sleep(11);
}
FencesExitOn();
}
//红外检测出口栅栏何时关闭
void MainWindow::RedEnterCheckChu(int car_x,int car_y)
{
if(car_x + ui->Car_2->height() == ui->exitRed->x())
FencesExitOff();
}
再说出入口显示的实现,由于出入口显示的思路和原理也相同,这里以入口为例。
这部分的实现在原理上有所偷懒,在小车通过扫描点的时候是才给小车加上了信息,而不是小车自带信息然后被扫描出来。核心在于信息的切割与设置扫描点。当坐标到达时进行ShowToXX();将信息展示出来
//设置小车文本信息
QString MainWindow::setCarInfo(QString carName,QString money,QString brand,QString park )
{
QString info = carName+" "+money+" "+brand+" "+park+" ";
//ui->Car_1->setText(info);
return info;
}
//切割小车信息
void MainWindow::splitCarInfor(QString carInfo,vector& v)
{
string str = carInfo.toStdString();
while(1)
{
int idx = str.find(" ");
if(idx==-1)
{
break;
}
string s = str.substr(0,idx);
v.push_back(s);
str = str.substr(idx+1,str.length());
}
}
//获取系统时间
string MainWindow::getSysTime()
{
QDateTime local(QDateTime::currentDateTime());
mLocalTime = local.toString().toStdString();
return mLocalTime;
}
//入口扫描车的信息
void MainWindow::scanCar()
{
QString carInfo = setCarInfo("A-00000","10RMB","BWM","P3");
if(ui->Car_2->x() == ui->ScanBtn_1->x())
{
// QString carInfo = ui->Car_1->text();
showToEnter(carInfo);
}
}
//出口扫描仪扫描获取小车信息
void MainWindow::scanCarExit()
{
QString carInfo = setCarInfo("A-00000","10RMB","BWM","P3");
if(ui->Car_2->x()+ui->Car_2->height() == ui->ScanBtn_2->x())
{
// QString carInfo = ui->Car_1->text();
showToExit(carInfo);
}
}
//入口显示
void MainWindow::showToEnter(QString carInfo)
{
vector carSpliteInfo; //小车的信息划分存储
splitCarInfor(carInfo,carSpliteInfo);
vector v;
v.push_back("车牌:");
v.push_back("停车费:");
v.push_back("车型:");
v.push_back("车位:");
string s ;
string sub;
for(int i=0;iEntrancelabel->setText(s.c_str());
}
//出口显示
void MainWindow::showToExit(QString carInfo)
{
vector carSpliteInfo; //小车的信息划分存储
splitCarInfor(carInfo,carSpliteInfo);
vector v;
v.push_back("车牌:");
v.push_back("停车费:");
v.push_back("车型:");
v.push_back("车位:");
string s ;
string sub;
for(int i=0;iExitlabel->setText(s.c_str());
}
//停车时间
void MainWindow::stopCarTime(unsigned int msec)
{
sleep(msec);
}
补充一点。通过前面可以看出,在小车行进的时候再触发按钮,小车极有可能会“错乱”因此,在控制小车的行动的函数开头加上
ui->CarADriveBtn->setAttribute(Qt::WA_TransparentForMouseEvents, true);
ui->CarBDriveBtn->setAttribute(Qt::WA_TransparentForMouseEvents, true);
进行按钮的“透明化”或者锁定
在行动函数的末尾加上
ui->CarADriveBtn->setAttribute(Qt::WA_TransparentForMouseEvents, false);
ui->CarBDriveBtn->setAttribute(Qt::WA_TransparentForMouseEvents, false);
进行按钮的恢复
最后控制小车行动的函数这里不再赘述,完整程序中可以自行理解。
完整程序
链接:https://pan.baidu.com/s/19HEvFLaj3_S4LY4REnwZ_g
提取码:x4ui