From 998cffecafb514b53bf008d9ee365c43352a35b2 Mon Sep 17 00:00:00 2001 From: wmj Date: Thu, 14 Dec 2017 16:34:27 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=A9=E7=94=A8widget=E9=87=8D=E6=9E=84parki?= =?UTF-8?q?nglot?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ParkingLotWidget.cpp | 111 +++++++++++++++++++++++++++++++++++++++++++ ParkingLotWidget.h | 23 +++++++++ ParkingSpaceInfo.cpp | 88 ++++++++++++++++++++++++++++++++++ ParkingSpaceInfo.h | 17 +++++++ Road.cpp | 44 +++++++++++++++++ Road.h | 15 ++++++ 6 files changed, 298 insertions(+) create mode 100644 ParkingLotWidget.cpp create mode 100644 ParkingLotWidget.h create mode 100644 ParkingSpaceInfo.cpp create mode 100644 ParkingSpaceInfo.h create mode 100644 Road.cpp create mode 100644 Road.h diff --git a/ParkingLotWidget.cpp b/ParkingLotWidget.cpp new file mode 100644 index 0000000..d7d8260 --- /dev/null +++ b/ParkingLotWidget.cpp @@ -0,0 +1,111 @@ +#include "ParkingLotWidget.h" + +#include +#include +#include +#include +#include "Road.h" +#include "ParkingSpaceInfo.h" +#include + +ParkingLotWidget::ParkingLotWidget(QWidget *parent, const QString& xml) : QWidget(parent) +{ + resize(1000, 1000); + parse_xml(xml); + if (rootLayoutDirection == horizontal) + setLayout(hBoxLayout); + else + setLayout(vBoxLayout); + +} + + +void ParkingLotWidget::paintEvent(QPaintEvent * event) +{ + +} + +ParkingLotWidget::~ParkingLotWidget() +{ +} + +void ParkingLotWidget::parse_xml(const QString & xml) +{ + QFile file(xml); + if (!file.open(QFile::ReadOnly | QFile::Text)) { + QMessageBox::critical(this, QObject::tr("Error"), + QObject::tr("Cannot read file %1").arg(xml)); + } + + QString errorStr; + int errorLine; + int errorColumn; + QDomDocument doc; + if (!doc.setContent(&file, false, &errorStr, &errorLine, &errorColumn)) { + QMessageBox::critical(this, QObject::tr("Error"), + QObject::tr("Parse error at line %1, column %2: %3") + .arg(errorLine).arg(errorColumn).arg(errorStr)); + } + QDomElement element = doc.documentElement().firstChild().toElement(); + QString name = element.tagName(); + if (element.tagName() == "vLayout") + { + rootLayoutDirection = vertical; + vBoxLayout = parseVbox(element); + } else if (element.tagName() == "hLayout") + { + rootLayoutDirection = horizontal; + hBoxLayout = parseHbox(element); + } else + { + qDebug() << this -> objectName() << "布局文件错误"; + } +} + +inline QHBoxLayout * ParkingLotWidget::parseHbox(const QDomElement & element) +{ + return static_cast(parseLayout(element)); +} + +inline QVBoxLayout * ParkingLotWidget::parseVbox(const QDomElement & element) +{ + return static_cast(parseLayout(element));; +} + +QBoxLayout * ParkingLotWidget::parseLayout(const QDomElement & element) +{ + QBoxLayout* layout; + if (element.tagName() == "hLayout") + layout = new QHBoxLayout; + else + layout = new QVBoxLayout; + + QDomElement child = element.firstChild().toElement(); + while (!child.isNull()) + { + QString name = child.tagName(); + if (name == "road") + { + const int l = child.attribute("length").toInt(); + if (child.attribute("direction") == "vertical") + layout->addWidget(new Road(this, l, Road::vertical)); + else + layout->addWidget(new Road(this, l, Road::horizontal)); + } + else if (name == "room") + { + const auto n = child.attribute("number", "1").toInt(); + layout->addLayout(ParkingSpaceInfo::makeParkingSapceGroup( + this, child.attribute("direction"), n, child.attribute("expendDirection"))); + } + else if ((name.at(0) == 'v' || name.at(0) == 'h' )&& name.contains("Layout")) + layout->addLayout(parseHbox(child)); + else + qDebug() << this->objectName() << "错误的xml标签"; + child = child.nextSiblingElement(); + } + layout->setMargin(0); + layout->setSpacing(0); + layout->setContentsMargins(0, 0, 0, 0); + return layout; +} diff --git a/ParkingLotWidget.h b/ParkingLotWidget.h new file mode 100644 index 0000000..a3b74d5 --- /dev/null +++ b/ParkingLotWidget.h @@ -0,0 +1,23 @@ +#pragma once +#include +#include +#include +#include +#include +class ParkingLotWidget: public QWidget +{ + Q_OBJECT +public: + explicit ParkingLotWidget(QWidget* parent, const QString& xml); + void paintEvent(QPaintEvent* event) override; + ~ParkingLotWidget(); +private: + void parse_xml(const QString& xml); + inline QHBoxLayout* parseHbox(const QDomElement& element); + inline QVBoxLayout* parseVbox(const QDomElement& element); + enum {horizontal, vertical} rootLayoutDirection; + QBoxLayout *parseLayout(const QDomElement& element); + QHBoxLayout *hBoxLayout = nullptr; + QVBoxLayout *vBoxLayout = nullptr; +}; + diff --git a/ParkingSpaceInfo.cpp b/ParkingSpaceInfo.cpp new file mode 100644 index 0000000..292d4a5 --- /dev/null +++ b/ParkingSpaceInfo.cpp @@ -0,0 +1,88 @@ +#include "ParkingSpaceInfo.h" +#include +#include + +ParkingSpaceInfo::ParkingSpaceInfo(QWidget* parent, const direction dir) : QWidget(parent) +{ + this->dir = dir; + switch (dir) + { + case N: + case S: + resize(40, 60); + setMinimumSize(40, 60); + setMaximumSize(40, 60); + break; + case E: + case W: + resize(60, 40); + setMinimumSize(60, 40); + setMaximumSize(60, 40); + break; + } +} +ParkingSpaceInfo::ParkingSpaceInfo(QWidget* parent, const QString &dir) +{ + direction d = {}; + const char c = dir.at(0).unicode(); + switch (c) + { + case 'N':d = N; break; + case 'E':d = E; break; + case 'W':d = W; break; + case 'S':d = S; break; + default: qDebug() << this->objectName() << "错误的方向"; + } + this->ParkingSpaceInfo::ParkingSpaceInfo(parent, d); +} + +QBoxLayout *ParkingSpaceInfo::makeParkingSapceGroup(QWidget* parent, const QString& dir, int n, const QString & expend) +{ + QBoxLayout *layout; + if (expend == "down") + layout = new QVBoxLayout(); + else + layout = new QHBoxLayout(); + for (int i = 0; i < n; i++) + { + ParkingSpaceInfo *pk = new ParkingSpaceInfo(parent, dir); + layout->addWidget(pk); + } + layout->setMargin(0); + layout->setSpacing(0); + layout->setContentsMargins(0, 0, 0, 0); + return layout; +} + +void ParkingSpaceInfo::paintEvent(QPaintEvent * event) +{ + QPainter painter(this); + painter.setPen(Qt::blue); + // painter.drawRect(0, 0, this->width(), this->height()); + painter.setPen(Qt::red); + painter.setBrush(Qt::white); + painter.translate(30, 20); + switch (dir) { + case E: + break; + case S: + painter.rotate(270); + break; + case W: + painter.rotate(180); + break; + case N: + painter.rotate(90); + break; + } + painter.translate(-30, -20); + painter.drawRect(0, 0, 60, 5); + painter.drawRect(0, 5, 10, 35); + painter.drawRect(10, 35, 50, 5); + painter.end(); +} + + +ParkingSpaceInfo::~ParkingSpaceInfo() +{ +} diff --git a/ParkingSpaceInfo.h b/ParkingSpaceInfo.h new file mode 100644 index 0000000..e0b8c4e --- /dev/null +++ b/ParkingSpaceInfo.h @@ -0,0 +1,17 @@ +#pragma once +#include +#include +class ParkingSpaceInfo: public QWidget +{ + Q_OBJECT +public: + enum direction{N, S, E, W}; + ParkingSpaceInfo(QWidget* parent, direction dir); + ParkingSpaceInfo(QWidget* parent, const QString &dir); + static QBoxLayout* makeParkingSapceGroup(QWidget* parent, const QString& dir, int n, const QString &expend); + void paintEvent(QPaintEvent* event) override; + ~ParkingSpaceInfo(); +private: + direction dir; +}; + diff --git a/Road.cpp b/Road.cpp new file mode 100644 index 0000000..75f6db8 --- /dev/null +++ b/Road.cpp @@ -0,0 +1,44 @@ +#include "Road.h" +#include + +Road::Road(QWidget* parent, const int length, const direction dir) + :QWidget(parent), length(length), dir(dir) +{ + switch(dir) + { + case horizontal: + resize(length, 50); + setMinimumSize(length, 50); + setMaximumSize(length, 50); + break; + case vertical: + resize(50, length); + setMinimumSize(50, length); + setMaximumSize(50, length); + break; + } +} + +void Road::paintEvent(QPaintEvent * event) +{ + QPainter painter(this); + painter.setBrush(Qt::white); + painter.setPen(Qt::white); + auto x = 0, y = 0; + if (dir == horizontal) { + while (x < length) { + painter.drawRect(x + 5, 20, 40, 10); + x += 50; + } + } + else { + while (y < length) { + painter.drawRect(20, y + 5, 10, 40); + y += 50; + } + } +} + +Road::~Road() +{ +} diff --git a/Road.h b/Road.h new file mode 100644 index 0000000..d0a2abb --- /dev/null +++ b/Road.h @@ -0,0 +1,15 @@ +#pragma once +#include +class Road: public QWidget +{ + Q_OBJECT +public: + enum direction{ horizontal, vertical}; + Road(QWidget* parent, const int length, direction dir); + void paintEvent(QPaintEvent* event) override; + ~Road(); +private: + const int length; + direction dir; +}; +