diff --git a/car.cpp b/car.cpp index 990cf39..4a33d00 100644 --- a/car.cpp +++ b/car.cpp @@ -257,6 +257,8 @@ void Car::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidg if(item->type()==Car::Type) { Car *car = qgraphicsitem_cast(item); + if (car->getStatus() == Car::parking) + continue; if(qAbs(car->getDir()-270)<20&&qAbs(this->getDir()-270)<20&&car->getmPos().x()getmPos().x()) { posAni->stop(); @@ -287,8 +289,15 @@ int Car::type() const } void Car::leaveProbability(int p) { - if (rand() % 100 + 1 < p) - emit out(this, -1); + if (m_status == parking) { + if (rand() % 100 + 1 < p) + emit out(this, -1); + } + else if (m_status == waiting) + if (rand() % 100 + 1 < 10) { + m_status = parking; + emit back(this); + } } @@ -308,6 +317,16 @@ void Car::requestSpace() emit queueHead(this); } +void Car::go() +{ + if (m_status == parking) + emit out(this, -1); + else if (m_status == waiting) { + m_status = parking; + emit back(this); + } +} + int Car::getTargetFloor() const { return targetFloor; diff --git a/car.h b/car.h index d180ec1..b884e0b 100644 --- a/car.h +++ b/car.h @@ -78,6 +78,7 @@ public: void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event); void requestSpace(void); + void go(void); private: Status m_status; diff --git a/carlist.cpp b/carlist.cpp index 3504031..8fd74a3 100644 --- a/carlist.cpp +++ b/carlist.cpp @@ -12,6 +12,7 @@ CarList::CarList(QWidget *parent) : setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint); setWindowTitle("车辆列表"); setGeometry(parent->x() + parent->width(), y() + parent->height() / 2, 400, 450); + connect(ui->tableView, &QTableView::clicked, this, &CarList::mouseEvent); hide(); } @@ -24,6 +25,7 @@ void CarList::setAdapter(Adapter *adapter) ui->tableView->setModel(adapter); ui->tableView->resizeColumnsToContents(); ui->tableView->resizeRowsToContents(); + m_carList = adapter->getCarList(); } CarList *CarList::newInstance(QWidget *parent) @@ -44,9 +46,16 @@ void CarList::closeEvent(QCloseEvent *e) e->accept(); } +void CarList::mouseEvent(const QModelIndex &index) +{ + qDebug() << index.row() << " " << index.column(); + if (index.column() == 5) + m_carList->at(index.row())->go(); +} + Adapter::Adapter(QObject *parent, QList *list): QAbstractTableModel(parent), m_list(list) { - header << "车牌" << "车型" << "停放位置" << "驶入时间" << "已产生费用"; + header << "车牌" << "车型" << "停放位置" << "驶入时间" << "已产生费用" << "操作"; timer = new QTimer(this); QObject::connect(timer, &QTimer::timeout, this, &Adapter::update); timer->start(1000); // 每秒更新 @@ -55,7 +64,7 @@ Adapter::Adapter(QObject *parent, QList *list): QAbstractTableModel(parent int Adapter::columnCount(const QModelIndex &parent) const { Q_UNUSED(parent); - return 5; + return 6; } int Adapter::rowCount(const QModelIndex &parent) const @@ -77,6 +86,7 @@ QVariant Adapter::data(const QModelIndex &index, int role) const else return m_list->at(index.row())->getStartTime().toString("hh:mm"); case 4: return m_list->at(index.row())->getFee(); + case 5: return "离开"; default: return QVariant(); } } @@ -90,6 +100,11 @@ QVariant Adapter::headerData(int section, Qt::Orientation orientation, int role) return QVariant(); } +QList *Adapter::getCarList() +{ + return m_list; +} + void Adapter::update() { beginResetModel(); diff --git a/carlist.h b/carlist.h index 5135a2d..dedd445 100644 --- a/carlist.h +++ b/carlist.h @@ -20,13 +20,12 @@ public: int rowCount(const QModelIndex &parent = QModelIndex()) const; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; QVariant headerData(int section, Qt::Orientation orientation, int role) const; + QList* getCarList(); void update(); private: QStringList header; QList* m_list; QTimer *timer; - - }; class CarList : public QDialog @@ -39,13 +38,14 @@ public: static CarList* newInstance(QWidget* parent); static CarList* getInstance(); void closeEvent(QCloseEvent *e); + void mouseEvent(const QModelIndex& index); signals: void onCloseButtonClicked(void); private: static CarList* m_instance; explicit CarList(QWidget *parent = 0); - QList* m_adapter; + QList* m_carList; Ui::CarList *ui; }; diff --git a/monitor.cpp b/monitor.cpp index 2df52ee..71d0ce9 100644 --- a/monitor.cpp +++ b/monitor.cpp @@ -33,11 +33,12 @@ Monitor::Monitor(MainWindow *parent) : QObject::connect(ui->drawPath, &QPushButton::clicked, [=](){ pk->drawPath(ui->placeNum1->text().toInt(), ui->placeNum2->text().toInt()); }); - + QObject::connect(ui->showMode, &QCheckBox::toggled, pk, &ParkingLotManager::showMode); + ui->sequence->hide(); QObject::connect(ui->addCar, &QPushButton::clicked, [this, pk]() { QString p = this->ui->plateNumBox->text(); if(checkPlate(p) == false) { - QMessageBox::warning(this, "警告","车牌不合规则"); + QMessageBox::warning(this, "警告", "车牌不合规则"); } else if (pk->checkSame(p)) { QMessageBox::warning(this, "警告", "车牌重复"); } else { @@ -45,9 +46,27 @@ Monitor::Monitor(MainWindow *parent) : } }); QObject::connect(ui->random, &QPushButton::clicked, pk, &ParkingLotManager::addCarR); - + QObject::connect(ui->sequence, &QCheckBox::clicked, pk, &ParkingLotManager::setSequence); + QObject::connect(ui->confirm_max, &QPushButton::clicked, [this, pk]() { + pk->setMax(ui->max_number->value()); + }); pk->showParkingLot(); ui->view->setScene(scene); + ui->max_number->setValue(208); + + QObject::connect(ui->searchButton, &QPushButton::clicked, [this, pk]() { + QPair p = pk->search(this->ui->searchBox->text()); + if (p.first == "-1" && p.second == -1) + QMessageBox::information(this, "搜索结果", QString("未找到%1") + .arg(this->ui->searchBox->text())); + else if (p.first == "0" && p.second == 0) + QMessageBox::information(this, "搜索结果", + QString("%1正在等候中").arg(this->ui->searchBox->text())); + else + QMessageBox::information(this, "搜索结果", + QString("%1在%2%3号").arg(this->ui->searchBox->text()) + .arg(p.first).arg(p.second)); + }); } void Monitor::showEvent(QShowEvent *event) diff --git a/monitor.ui b/monitor.ui index 27102f8..d278820 100644 --- a/monitor.ui +++ b/monitor.ui @@ -67,7 +67,7 @@ - + QLayout::SetDefaultConstraint @@ -160,6 +160,78 @@ + + + + 按顺序停车 + + + true + + + + + + + + + 最大车位数量 + + + + + + + 1 + + + 208 + + + 208 + + + + + + + 确认 + + + + + + + + + + + 搜索车牌 + + + + + + + + 80 + 16777215 + + + + 搜索 + + + + + + + + + 演示模式 + + + diff --git a/parkingLotManager.cpp b/parkingLotManager.cpp index c9ae450..ed45dd2 100644 --- a/parkingLotManager.cpp +++ b/parkingLotManager.cpp @@ -54,13 +54,12 @@ ParkingLotManager::ParkingLotManager(QObject* objectParent, QGraphicsScene* scen QObject::connect(this, &ParkingLotManager::showMarginSignal, widget, &ParkingLotWidget::showMarginSlot); QObject::connect(widget, &ParkingLotWidget::banParkingSpace, [i, this](bool b, int n){banSpace(b, i, n);}); } - generatePool(false); + generatePool(true); Adapter *adapter = new Adapter(objectParent, &m_all_cars); // 注册model CarList::getInstance()->setAdapter(adapter); - QTimer *timer = new QTimer(this); + timer = new QTimer(this); connect(timer, &QTimer::timeout, this, &ParkingLotManager::periodWork); - timer->start(1000); // 轮询 } void ParkingLotManager::showParkingLot(uint pos) @@ -71,11 +70,13 @@ void ParkingLotManager::showParkingLot(uint pos) } for (uint i = 0; i < m_num_of_layer; i++) m_widgets.at(i)->hide(); + qDebug()<<(QString("LINE:%1").arg(__LINE__)); m_widgets.at(pos)->show(); for (QGraphicsPixmapItem* p: m_graph_pixmap) if (m_scene->items().contains(p)) m_scene->removeItem(p); if (m_showGraph) { + qDebug()<<(QString("LINE:%1").arg(__LINE__)); m_scene->addItem(m_graph_pixmap.at(m_current_floor)); } for (auto c: m_all_cars) { @@ -172,6 +173,29 @@ QString ParkingLotManager::getParkingLotName(int pos) return m_widgets.at(pos)->getName(); } +QPair ParkingLotManager::search(const QString& plate) +{ + for (auto c: m_all_cars) { + if (c->getPlateNumber() == plate) { + if (c->getStatus() == Car::Status::parking || + c->getStatus() == Car::Status::moving) + return qMakePair(m_widgets.at(c->getTargetFloor())->getName(), + c->getNum()); + else if (c->getStatus() == Car::Status::waiting) + return qMakePair(QString("0"), 0); + } + } + return qMakePair(QString("-1"), -1); +} + +void ParkingLotManager::showMode(bool enable) +{ + if (enable) + timer->start(1000); + else + timer->stop(); +} + void ParkingLotManager::requestOut(Car *car, int exit) { if (exit == -1) @@ -182,7 +206,8 @@ void ParkingLotManager::requestOut(Car *car, int exit) else p = m_graph[car->getCurrentFloor()]-> findPath(NODE_TYPE::space, car->getNum(), NODE_TYPE::stair, exit); - m_pool.append(qMakePair(car->getCurrentFloor(), car->getNum() - 1)); + if (m_pool.size() < m_max) + m_pool.append(qMakePair(car->getCurrentFloor(), car->getNum() - 1)); m_widgets[car->getCurrentFloor()]-> getSpaceList()[car->getNum() - 1]->setSituation(ParkingSpaceWidget::free); car->setNum(-exit); // 负数代表出口 @@ -227,6 +252,8 @@ void ParkingLotManager::requestIn(Car* car) if (!m_pool.empty()) { uint l = m_pool.first().first; int n = m_pool.first().second + 1; + if (m_widgets[l]->getSpaceList().at(n - 1)->getSituation() != FREE) + return; // l = 0; m_pool.removeAt(0); Log::i(QString("分配第%1层%2号车位,剩余%3个空车位").arg(l).arg(n).arg(m_pool.size())); @@ -247,6 +274,7 @@ void ParkingLotManager::requestIn(Car* car) car->setStatus(Car::parking); m_num_of_cars[l] += 1; m_widgets[l]->getSpaceList()[n - 1]->setSituation(ParkingSpaceWidget::occupied); + qDebug()<<(QString("LINE:%1 %2").arg(__LINE__).arg(m_current_floor)); emit setLoad(QString::number(m_capacity.at(m_current_floor) - m_num_of_cars[m_current_floor])); } else { Log::i("请求失败,车位已满"); @@ -256,23 +284,13 @@ void ParkingLotManager::requestIn(Car* car) void ParkingLotManager::leave(Car* car) { int l = car->getCurrentFloor(); - int n = car->getNum(); - Log::i(QString("有车离开,当前共有%1个空车位").arg(m_pool.size())); - - for (uint i = 0 ; i < m_num_of_entry; i++) { - if (m_waitting[lastInEntry].size() == 0) - lastInEntry = (lastInEntry + 1) % m_num_of_entry ; - else { - Car *c = m_waitting[lastInEntry][0]; - c->requestSpace(); - } - } - + callIn(); car->hide(); m_all_cars.removeOne(car); delete car; m_num_of_cars[l] -= 1; + qDebug()<<(QString("LINE:%1").arg(__LINE__)); emit setLoad(QString::number(m_capacity.at(m_current_floor) - m_num_of_cars[m_current_floor])); } @@ -281,6 +299,8 @@ void ParkingLotManager::addCarR() Log::i("生成车"); int entry = (rand() % m_num_of_entry); + if (m_waitting[entry].size() > 10) + return; Car *car = new Car(this); car->setEntryNum(entry + 1); @@ -302,6 +322,8 @@ void ParkingLotManager::addCar(QString plate, int color, int entry) Log::i("生成车"); if (entry == -1) entry = (rand() % m_num_of_entry) + 1; + if (m_waitting[entry - 1].size() > 10) + return; Car *car = new Car(this, nullptr, 0, static_cast(color)); car->setPlateNumber(plate); car->setEntryNum(entry); @@ -339,21 +361,19 @@ void ParkingLotManager::banSpace(bool banned, int l , int n) } else { m_pool.append(qMakePair(l, n - 1)); Log::i(QString("启用第%1层%2号车位,剩余%3个空车位").arg(l).arg(n).arg(m_pool.size())); - for (uint i = 0 ; i < m_num_of_entry; i++) { - if (m_waitting[lastInEntry].size() == 0) - lastInEntry = (lastInEntry + 1) % m_num_of_entry ; - else { - Car *c = m_waitting[lastInEntry][0]; - c->requestSpace(); - } - } + callIn(); } } -void ParkingLotManager::generatePool(bool sequence) +void ParkingLotManager::generatePool(bool sequence, int max) { + m_pool.clear(); + if (max == -1) + max = 65536; for (int l = m_num_of_layer - 1; l >= 0; l--) { for (int n = 0; n < m_capacity[l]; n++) { + if (max-- == 0) + return; if (GET_SITUATION(l, n) == FREE) { m_pool.append(qMakePair(l, n)); } @@ -370,7 +390,39 @@ void ParkingLotManager::periodWork() if (rand() % 100 + 1 < generateProbability) addCarR(); for (auto c: m_all_cars) { - if (c->getStatus() == Car::parking) - c->leaveProbability(2); + c->leaveProbability(2); } } + +void ParkingLotManager::callIn() +{ + for (uint i = 0 ; i < m_num_of_entry; i++) { + if (m_waitting[lastInEntry].size() == 0) + lastInEntry = (lastInEntry + 1) % m_num_of_entry ; + else { + Log::i(QString("从%1召唤车").arg(lastInEntry)); + Car *c = m_waitting[lastInEntry][0]; + c->requestSpace(); + } + } +} + +void ParkingLotManager::setMax(int max) +{ + int n = m_max; + m_max = max; + Log::i(QString("设置最大容量%1").arg(max)); + generatePool(m_sequence, max); + if (max - n == 1) + callIn(); + else if (max - n >= 2) { + callIn(); + callIn(); + } +} + +void ParkingLotManager::setSequence(bool sequence) +{ + m_sequence = sequence; + generatePool(m_sequence, m_max); +} diff --git a/parkingLotManager.h b/parkingLotManager.h index e579af3..d1dfc8d 100644 --- a/parkingLotManager.h +++ b/parkingLotManager.h @@ -34,8 +34,9 @@ public: void drawPath(Path* p); bool checkSame(const QString& plate); - QString getParkingLotName(int pos); + QPair search(const QString& plate); + void showMode(bool enable); public slots: void requestIn(Car* car); @@ -49,6 +50,8 @@ public slots: void showMargin(bool enable); void showGraph(bool enable); void banSpace(bool banned, int layer, int number); + void setMax(int max); + void setSequence(bool sequence); private: QGraphicsScene* m_scene; @@ -68,10 +71,14 @@ private: uint m_current_floor = 1; // 当前楼层,默认为1楼(按照从下往上递增,值与实际楼层无关) bool m_showGraph = false; // 是否显示图 - void generatePool(bool sequence); + void generatePool(bool sequence, int max = -1); void periodWork(void); + void callIn(void); int lastInEntry = 0; + int m_max = -1; + bool m_sequence = true; + QTimer *timer; signals: