当前位置: 首页 > news >正文

QT-模拟电梯上下楼

QT-模拟电梯上下楼

  • 一、演示效果
  • 二、核心程序
  • 三、下载链接


一、演示效果

在这里插入图片描述

二、核心程序

#include "ElevatorController.h"
#include <QGridLayout>
#include <QLabel>
#include <QGroupBox>
#include <QGridLayout>
#include <QPushButton>
#include <QDebug>
#include <QChar>
#include <QGuiApplication>
#include <QScreen>
#include <queue>ElevatorController::ElevatorController(Ui::MainWindow* u, int numElevators, int numFloors)
{// create/populate ui ComboBox elementsui = u;QStringList evs;for (int elevator = 1; elevator <= numElevators; ++elevator){evs << QString("Elevator: %1").arg(elevator);}ui->comboElevatorBox->addItems(evs);connect(ui->comboElevatorBox, qOverload<int>(&QComboBox::currentIndexChanged), this, &ElevatorController::elevatorSelected);evs.clear();for (int floorc = 1; floorc <= numFloors; ++floorc){evs << QString("Floor: %1").arg(floorc);}ui->comboFloorBox->addItems(evs);// buttons connectedconnect(ui->pushElevatorButton, &QPushButton::clicked, this, &ElevatorController::buttonElevatorSubmit);connect(ui->pushHelpButton, &QPushButton::clicked, this, &ElevatorController::buttonElevatorHelp);connect(ui->pushPlaceButton, &QPushButton::clicked, this, &ElevatorController::buttonPlaceOnFloor);connect(ui->pushMoveButton, &QPushButton::clicked, this, &ElevatorController::buttonMoveToElevator);connect(ui->pushAdd10FloorButton, &QPushButton::clicked, this, &ElevatorController::add10ToEachFloor);connect(ui->pushBuildingEmergencyButton, &QPushButton::clicked, this, &ElevatorController::triggerBuildingEmergency);connect(ui->pushEmergencyResetAllButton, &QPushButton::clicked, this, &ElevatorController::resetAllElevatorsEmergency);connect(ui->pushLeaveButton, &QPushButton::clicked, this, &ElevatorController::buttonLeaveElevator);// spin box buttons:connect(ui->spinBoxMove, qOverload<int>(&QSpinBox::valueChanged), this, &ElevatorController::moveComboBoxChange);connect(ui->spinBoxLeaveElevator, qOverload<int>(&QSpinBox::valueChanged), this, &ElevatorController::moveLeaveElevatorBoxChange);// combo box change:connect(ui->comboFloorBox, qOverload<int>(&QComboBox::currentIndexChanged), this, &ElevatorController::floorSelected);// keep in mind: "setWidget" and "setLayout" etc add to the ui tree, memory managed by Qt not Me :-)// widget to hold the grid layoutQWidget* elevatorWidget = new QWidget();ui->elevatorScrollArea->setWidget(elevatorWidget); // Set the content widget of the ElevatorController// QGridLayout* elevatorGridLayoutelevatorGridLayout = new QGridLayout(elevatorWidget);elevatorWidget->setLayout(elevatorGridLayout);// Add buttons or labels to the grid layout based on dimensionsfor (int floor = numFloors - 1; floor >= 0; floor--){for (int elevator = 1; elevator <= numElevators; ++elevator){// Create a QLabel for each positionQLabel* cube = new QLabel;cube->setText(" ");cube->setFixedSize(CUBE_SIZE, CUBE_SIZE);QString color = "gray";if(numFloors - floor - 1 == 0) // all ev's start at 0color = "red";cube->setStyleSheet(QString("background-color: %1").arg(color));// Add the widget to the grid layout at the specified positionelevatorGridLayout->addWidget(cube, floor, elevator);}Floor* flr = new Floor(floor + 1); // floor class is a part of the UI// Connect the signals from the Floor to the slots in the ElevatorControllerconnect(flr, &Floor::upButtonPressed, this, &ElevatorController::buttonPressedUp);connect(flr, &Floor::downButtonPressed, this, &ElevatorController::buttonPressedDown);// adds the floor at the start (far left)elevatorGridLayout->addWidget(flr, numFloors - floor - 1, 0);floors.push_back(flr);}// create elevatorsfor (int elevator = 1; elevator <= numElevators; ++elevator){Elevator* ev = new Elevator(elevator);elevators.push_back(ev);updateDisplays();// should be connecting slot in elevator to signals in elevator controllerconnect(this, &ElevatorController::resetEmergency, ev, &Elevator::resetEmergencyInElevator);connect(this, &ElevatorController::sendRequestToElevator, ev, &Elevator::pressButton);connect(this, &ElevatorController::helpButton, ev, &Elevator::helpButtonPressed);connect(this, &ElevatorController::moveElevatorToFloor, ev, &Elevator::moveTofloor);connect(this, &ElevatorController::removeElevatorPassengers, ev, &Elevator::removePassengers);connect(this, &ElevatorController::addElevatorPassengers, ev, &Elevator::addPassengers);connect(this, &ElevatorController::buildingEmergency, ev, &Elevator::emergency);connect(this, &ElevatorController::pressButton, ev, &Elevator::pressButton);connect(this, &ElevatorController::unpressButton, ev, &Elevator::unpressButton);connect(ev, &Elevator::floorChanged, this, &ElevatorController::elevatorFloorChanged);connect(ev, &Elevator::doorOpened, this, &ElevatorController::doorOpened);connect(ev, &Elevator::doorClosed, this, &ElevatorController::doorClosed);connect(ev, &Elevator::doorBlocked, this, &ElevatorController::doorBlocked);connect(ev, &Elevator::overloaded, this, &ElevatorController::overloaded);connect(ev, &Elevator::emergencyOnBoard, this, &ElevatorController::emergency);connect(ev, &Elevator::updateDisplays, this, &ElevatorController::updateDisplays);QThread* evThread = new QThread;ev->moveToThread(evThread);evThread->start();threads.push_back(evThread);}requestScanTimer = new QTimer(this);connect(requestScanTimer, &QTimer::timeout, this, &ElevatorController::scanRequestTree);requestScanTimer->start(SCAN_REQUEST_TREE_SECS);  // Scan backup request tree every 15 seconds, in case overflowqDebug() << "Elevator Controller Initialized";
}ElevatorController::~ElevatorController() // clean up floors
{for(int i = 0; i < floors.size(); i++)delete floors[i];requestScanTimer->stop();delete requestScanTimer;for(int i = 0; i < threads.size(); i++){threads[i]->quit();threads[i]->wait();delete threads[i];}
}// --- UI INPUT & CALLBACK FUNCS ---void ElevatorController::handleScreenResized(int w, int h)
{int bufferGap = 10;ui->elevatorScrollArea->resize(w - ui->InputTerminal->width() - 3*bufferGap, h - bufferGap*6);qDebug() << "Reinit scale -- uiWidth: " << w << " uiHeight: " << h;ui->InputTerminal->move(ui->elevatorScrollArea->x() + w - ui->InputTerminal->width() - 2*bufferGap, ui->InputTerminal->y());ui->InputTerminal->resize(ui->InputTerminal->width(), h - bufferGap*5);
}void ElevatorController::updateDisplays()
{int ev = ui->comboElevatorBox->currentText().remove(0, 10).toInt(); // stored from 0QString buttonList = "";const std::set<int>& blist = elevators[ev - 1]->getButtonsPressed();for(const int& a : blist){buttonList += QString::number(a) + " ";}ui->textBrowserButtonsPressed->setPlainText(buttonList);const int flr = ui->comboFloorBox->currentText().remove(0, 7).toInt();ui->passengerOnFloorNumber->display(floors[flr - 1]->peopleOnFloor());ui->passengerNumber->display(elevators[ev - 1]->numPassengers());
}void ElevatorController::buttonElevatorSubmit()
{// get the int values from the combo boxesint ev = ui->comboElevatorBox->currentText().remove(0, 10).toInt();int fb = ui->comboFloorBox->currentText().remove(0, 7).toInt();qDebug() << "BUTTON - elevator submit pressed elev: " << ev << " floor button: " << fb;if(elevators[ev - 1]->getButtonsPressed().count(fb) > 0)emit unpressButton(ev, fb);elseemit pressButton(ev, fb);
}void ElevatorController::buttonPlaceOnFloor()
{qDebug() << "BUTTON buttonPlaceOnFloor.... spawning ppl on floor";const int flr = ui->comboFloorBox->currentText().remove(0, 7).toInt() - 1;floors[flr]->addPeople(ui->spinBoxPlace->value());ui->passengerOnFloorNumber->display(floors[flr]->peopleOnFloor());ui->spinBoxPlace->setValue(0);
}void ElevatorController::buttonMoveToElevator()
{qDebug() << "BUTTON: buttonMoveToElevator.... moving ppl ";const int flr = ui->comboFloorBox->currentText().remove(0, 7).toInt();int evweak = ui->comboElevatorBox->currentText().remove(0, 10).toInt() - 1; // if this is on the same floor its usedElevator* availableEv = nullptr;Elevator* weakEv = nullptr;bool potentialEvPassed = false;if(elevators[evweak]->currentFloor() == flr) // soft lock the current elevatorweakEv = elevators[evweak];for(Elevator* ev : elevators) // unless theres one that makes more sense{if(ev->currentFloor() == flr && ev->currentState() == Elevator::DoorsOpen){availableEv = ev;if(weakEv == ev && weakEv != nullptr){availableEv = weakEv;break;}}}if(!availableEv)return;const int val = ui->spinBoxMove->value(); //usr inputui->spinBoxMove->setValue(0);floors[flr - 1]->removePeople(val);//    emit addElevatorPassengers(availableEv->getId(), flr, val);elevators[availableEv->getId() - 1]->addPassengers(availableEv->getId(), flr, val);// just set the combo box option to the one that people were put into automatically... for visibilityui->comboElevatorBox->setCurrentIndex(availableEv->getId() - 1);// update the floor on people displayupdateDisplays();
}void ElevatorController::buttonLeaveElevator()
{int ev = ui->comboElevatorBox->currentText().remove(0, 10).toInt();qDebug() << "BUTTON: buttonLeaveElevator.... moving ppl EV: " << ev << " FLR: " << elevators[ev - 1]->currentFloor();const int val = ui->spinBoxLeaveElevator->value(); //usr inputui->spinBoxLeaveElevator->setValue(0);emit removeElevatorPassengers(elevators[ev - 1]->getId(), elevators[ev - 1]->currentFloor(), val);floors[elevators[ev - 1]->currentFloor() - 1]->addPeople(val);// just set the combo box option to the one that people were put into automatically... for visibilityui->comboFloorBox->setCurrentIndex(elevators[ev - 1]->currentFloor() - 1);ui->passengerNumber->display(elevators[ev-1]->numPassengers());updateDisplays();const int flr = ui->comboFloorBox->currentText().remove(0, 7).toInt();if(elevators[ev - 1]->currentFloor() != flr)return;// update the floor on people displayui->passengerOnFloorNumber->display(floors[elevators[ev - 1]->currentFloor()]->peopleOnFloor());updateDisplays();controlMoveButtonActivated();
}void ElevatorController::add10ToEachFloor()
{qDebug() << "BUTTON add 10 To Each Floor.... spawning 10 ppl on each floor!";for(Floor* f : floors){f->addPeople(10);}const int flr = ui->comboFloorBox->currentText().remove(0, 7).toInt() - 1;ui->passengerOnFloorNumber->display(floors[flr]->peopleOnFloor());ui->spinBoxPlace->setValue(0);
}void ElevatorController::triggerBuildingEmergency()
{emit buildingEmergency(-1);
}void ElevatorController::buttonElevatorHelp()
{int ev = ui->comboElevatorBox->currentText().remove(0, 10).toInt();emit helpButton(ev);updateDisplays();
}void ElevatorController::resetAllElevatorsEmergency()
{emit resetEmergency(-1);updateDisplays();
}void ElevatorController::controlMoveButtonActivated(Elevator* availableEv)
{// we want to check if there is an elevator on the floor in door open state// & set the control button to active or not based on it//qDebug() << "BUTTON ACTIVATE: Activating/Deactivating the Move Button to allow moving ppl ";const int flr = ui->comboFloorBox->currentText().remove(0, 7).toInt();const int evNum = ui->comboElevatorBox->currentText().remove(0, 10).toInt();for(Elevator* ev : elevators){if(availableEv != nullptr)break;if(ev->currentFloor() == flr && ev->currentState() == Elevator::DoorsOpen || elevators[evNum - 1]->currentState() == Elevator::Overload)availableEv = ev;}if(elevators[evNum - 1]->currentState() == Elevator::DoorsOpen || elevators[evNum - 1]->currentState() == Elevator::Overload || elevators[evNum - 1]->currentState() == Elevator::Emergency)ui->pushLeaveButton->setEnabled(true);else if(ui->pushLeaveButton->isEnabled())ui->pushLeaveButton->setEnabled(false);if(availableEv != nullptr && flr == availableEv->currentFloor())ui->pushMoveButton->setEnabled(true);else if(ui->pushMoveButton->isEnabled())ui->pushMoveButton->setEnabled(false);
}void ElevatorController::elevatorSelected(int index)
{ui->passengerNumber->display(elevators[index]->numPassengers());updateDisplays();controlMoveButtonActivated(elevators[index]);qDebug()  << "COMBO BOX: Elevator selected. Elevator: " << index;
}void ElevatorController::floorSelected(int index)
{// update the segment display for passangersui->passengerOnFloorNumber->display(floors[index]->peopleOnFloor());qDebug()  << "COMBO BOX: Floor selected. Floor: " << index;ui->spinBoxMove->setValue(0); // wipe this since its different # pplcontrolMoveButtonActivated(); // potentially changes move buttons state
}void ElevatorController::moveComboBoxChange(int index)
{if(index > ui->passengerOnFloorNumber->value()){ui->spinBoxMove->setValue(ui->passengerOnFloorNumber->value());}
}void ElevatorController::moveLeaveElevatorBoxChange(int index)
{if(index > ui->passengerNumber->value()){ui->spinBoxLeaveElevator->setValue(ui->passengerNumber->value());}
}// --- UI UPDATE / EV SOCKET FUNCS ---void ElevatorController::elevatorFloorChanged(int floor, int ev, bool up)
{// each elevator emits this when the moved to new floorev -= 1;qDebug() << "EV signal: Elevator floor changed, floor: " << floor << " elevator: " << ev << " up dir: " << up;qDebug() << "(X, Y) : " << floor << ", " << (ev + 1);const int x = floors.size() - floor; // as the floors decrease, x increases (flr increase, x decrease)const int y = ev + 1;QLayoutItem* layoutItem = elevatorGridLayout->itemAtPosition(x, y); // check if we are looking at a valid evif (!layoutItem){qDebug() << "No layout item at this position.";return;}QWidget* widget = layoutItem->widget();if (!widget){qDebug() << "No widget at this position.";return;}const QMetaObject* metaObject = widget->metaObject();QString widgetType = QString::fromUtf8(metaObject->className());if (widgetType == "QLabel"){QLabel* square = qobject_cast<QLabel*>(widget);QLabel* squarePrev;squarePrev = qobject_cast<QLabel*>(elevatorGridLayout->itemAtPosition((x - 1 + floors.size()) % floors.size(), y)->widget());squarePrev->setStyleSheet(QString("background-color: gray;"));squarePrev = qobject_cast<QLabel*>(elevatorGridLayout->itemAtPosition((x + 1)%floors.size(), y)->widget());squarePrev->setStyleSheet(QString("background-color: gray;"));if(elevators[ev]->currentState() == Elevator::Emergency)square->setStyleSheet("background-color: yellow;");elsesquare->setStyleSheet("background-color: red;");}qDebug() << "Widget type: " << widgetType;
}void ElevatorController::doorOpened(int flr, int ev)
{// a door has openedqDebug()  << "EV signal: Door opened! Elevator: " << ev;const int x = floors.size() - flr; // as the floors decrease, x increases (flr increase, x decrease)const int y = ev;if (!elevatorGridLayout->itemAtPosition(x, y)){qDebug()  << "doorOpened(): No Item at position:  (" << x << ", " << y <<  ")";return;}QWidget* wdg = elevatorGridLayout->itemAtPosition(x, y)->widget();if(QString::fromUtf8(wdg->metaObject()->className()) != "QLabel"){qDebug()  << "doorOpened(): Item at position:  (" << x << ", " << y <<  ") " << "is a: " << QString::fromUtf8(wdg->metaObject()->className());return;}QLabel* squarePrev = qobject_cast<QLabel*>(wdg);squarePrev->setStyleSheet(QString("background-color: green;"));controlMoveButtonActivated(elevators[ev - 1]);updateDisplays();
}void ElevatorController::doorClosed(int flr, int ev)
{// a door has closedqDebug()  << "EV signal: Door closed!! Elevator: " << ev;const int x = floors.size() - flr; // as the floors decrease, x increases (flr increase, x decrease)const int y = ev;if (!elevatorGridLayout->itemAtPosition(x, y)){qDebug()  << "doorClosed(): No Item at position:  (" << x << ", " << y <<  ")";return;}QWidget* wdg = elevatorGridLayout->itemAtPosition(x, y)->widget();if(QString::fromUtf8(wdg->metaObject()->className()) != "QLabel"){qDebug()  << "doorClosed(): Item at position:  (" << x << ", " << y <<  ") " << "is a: " << QString::fromUtf8(wdg->metaObject()->className());return;}QLabel* squarePrev = qobject_cast<QLabel*>(wdg);squarePrev->setStyleSheet(QString("background-color: purple;"));
}void ElevatorController::doorBlocked(int flr, int ev)
{// a door has closedqDebug()  << "EV signal: Alert! Door blocked... reopening door... Elevator: " << ev;const int x = floors.size() - flr; // as the floors decrease, x increases (flr increase, x decrease)const int y = ev;if (!elevatorGridLayout->itemAtPosition(x, y)){qDebug()  << "doorBlocked(): No Item at position:  (" << x << ", " << y <<  ")";return;}QWidget* wdg = elevatorGridLayout->itemAtPosition(x, y)->widget();if(QString::fromUtf8(wdg->metaObject()->className()) != "QLabel"){qDebug()  << "doorBlocked(): Item at position:  (" << x << ", " << y <<  ") " << "is a: " << QString::fromUtf8(wdg->metaObject()->className());return;}QLabel* squarePrev = qobject_cast<QLabel*>(wdg);squarePrev->setStyleSheet(QString("background-color: blue;"));
}void ElevatorController::overloaded(int flr, int ev)
{// a door has closedqDebug()  << "EV signal: Elevator overloaded!! Elevator: " << ev;const int x = floors.size() - flr; // as the floors decrease, x increases (flr increase, x decrease)const int y = ev;if (!elevatorGridLayout->itemAtPosition(x, y)){qDebug()  << "doorClosed(): No Item at position:  (" << x << ", " << y <<  ")";return;}QWidget* wdg = elevatorGridLayout->itemAtPosition(x, y)->widget();if(QString::fromUtf8(wdg->metaObject()->className()) != "QLabel"){qDebug()  << "overloaded(): Item at position:  (" << x << ", " << y <<  ") " << "is a: " << QString::fromUtf8(wdg->metaObject()->className());return;}QLabel* squarePrev = qobject_cast<QLabel*>(wdg);squarePrev->setStyleSheet(QString("background-color: orange;"));
}void ElevatorController::emergency(int flr, int ev)
{// a door has closedqDebug()  << "EV signal: Elevator emergency!! Elevator: " << ev;if(flr != SAFE_FLOOR)return;QLayoutItem* layoutItem = elevatorGridLayout->itemAtPosition(floors.size() - SAFE_FLOOR, ev); // check if we are looking at a valid evif (!layoutItem){qDebug() << "No layout item at this position.";return;}QWidget* widget = layoutItem->widget();if (!widget){qDebug() << "No widget at this position.";return;}const QMetaObject* metaObject = widget->metaObject();QString widgetType = QString::fromUtf8(metaObject->className());if (widgetType == "QLabel"){QLabel* square = qobject_cast<QLabel*>(widget);if(elevators[ev - 1]->currentState() == Elevator::Idle)square->setStyleSheet(QString("background-color: red;"));elsesquare->setStyleSheet(QString("background-color: yellow;"));} qDebug() << "Widget type: " << widgetType;
}// --- EV REQUEST FUNCS ---void ElevatorController::buttonPressedUp(int floor)
{// an up button on a floor has been pressedqDebug()  << "Floor signal: Floor up button pressed: " << floor;handleFlrPressed(FloorDirection(floor, true));
}void ElevatorController::buttonPressedDown(int floor)
{// a down button on a floor has been pressedqDebug() << "Floor signal: Floor down button pressed: " << floor;handleFlrPressed(FloorDirection(floor, false));
}void ElevatorController::handleFlrPressed(FloorDirection fd)
{// maybe this had some use in some implementtation? ev->getNumFloorsReserved();Elevator* bestElevator = nullptr;Elevator* idleEv = nullptr; // lower priofor(Elevator* pEv : elevators){if(fd.up && pEv->lastDirMovingUp() && fd.num >= pEv->currentFloor()){bestElevator = pEv;break;}if(!fd.up && !pEv->lastDirMovingUp() && fd.num <= pEv->currentFloor()){bestElevator = pEv;break;}if(pEv->currentState() == Elevator::Idle)idleEv = pEv;}if(bestElevator)emit moveElevatorToFloor(bestElevator->getId(), fd.num);else if(idleEv)emit moveElevatorToFloor(idleEv->getId(), fd.num);elseearliestRequestTree.push(fd);
}void ElevatorController::scanRequestTree()
{// happen on a timer, scan request tree realloc elevators if freeif(AGGRESSIVE_LOGGING && !earliestRequestTree.empty())qDebug() << "scanRequestTree-> Request floor:  " << earliestRequestTree.top().num << " up: " << earliestRequestTree.top().up; // << i++;if (earliestRequestTree.empty()){return;}FloorDirection fd = earliestRequestTree.top();earliestRequestTree.pop();handleFlrPressed(FloorDirection(fd.num, fd.up));
}
xt

三、下载链接

https://download.csdn.net/download/u013083044/88861542

http://www.lryc.cn/news/304767.html

相关文章:

  • 基于springboot+vue的桂林旅游景点导游平台(前后端分离)
  • 设计模式四:适配器模式
  • 【AI应用】SoraWebui——在线文生视频工具
  • 电路设计(27)——交通信号灯的multisim仿真
  • Python Sanic 异步 Web 框架
  • 滚雪球学Java(70):深入理解Java中的PriorityQueue底层实现与源码分析
  • 李宏毅2023机器学习作业1--homework1
  • Mysql的SQL调优-面试
  • Unity 2021.3发布WebGL设置以及nginx的配置
  • 【鸿蒙 HarmonyOS 4.0】数据持久化
  • mysql mgr集群多主部署
  • 【开源】JAVA+Vue.js实现医院门诊预约挂号系统
  • 《图解设计模式》笔记(一)适应设计模式
  • 图文说明Linux云服务器如何更改实例镜像
  • RabbitMQ学习整理————基于RabbitMQ实现RPC
  • Linux-基础知识(黑马学习笔记)
  • SpringBoot项目启动报java.nio.charset.MalformedInputException Input length = 1解决方案
  • 【Unity2019.4.35f1】配置JDK、NDK、SDK、Gradle
  • MySQL中的高级查询
  • leetcode383赎金信
  • 【Unity3D】ASE制作天空盒
  • MyBatisPlus常用注解
  • Putty中运行matlab文件
  • ES6 | (一)ES6 新特性(上) | 尚硅谷Web前端ES6教程
  • 生产环境下,应用模式部署flink任务,通过hdfs提交
  • 【lesson59】线程池问题解答和读者写者问题
  • 【LeetCode每日一题】单调栈316去除重复字母
  • 【Git】Gitbash使用ssh 上传本地项目到github
  • activeMq将mqtt发布订阅转成消息队列
  • Go语言教程