加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
twidget.cpp 11.42 KB
一键复制 编辑 原始数据 按行查看 历史
章宏亮 提交于 2024-05-07 00:25 . 清空仓库后首次提交
#include "twidget.h"
#include "Graph.h"
#include <string>
#include <QRegularExpression>
#include <QTextStream>
#include <QPainter>
#include <QFile>
using namespace std;
Twidget::Twidget(QWidget *parent)
: QWidget(parent)
{
paintMode = 0; //默认绘制欢迎页
route = NULL; //路径是边的数组
edgeNum = 0; //路径边的数目
transNum = 0; //换乘数
length = 0; //总路径长度
string start = ""; //起点站
footMiles = 0;
spotsN = 1;
currentCost = 0;
currentLength = 0;
}
Twidget::~Twidget()
{
delete[] route;
}
void Twidget::paintEvent(QPaintEvent* event)
{
if (paintMode == 0) {
QPainter painter(this);
QPixmap image(":/Icon/image/welcome.png");
QRect r(0, 0, this->width(), this->height());
painter.drawPixmap(r, image);
painter.end();
}
else if (paintMode == 1|| paintMode == 2) {
drawRoute();
}
}
void Twidget::drawRoute() {
QPainter painter(this);
painter.setPen(Qt::NoPen);
painter.setBrush(Qt::white);
painter.drawRect(QRect(0, 0, this->width(), this->height()));
Graph g;
int sign = -1; //控制正负 ,小于0代表线路向左延伸,大于0代表向右延伸
int row = 10; //横排最大数量
int diameter = 60; //直径
int wlength = 30; //同行圆间线长
int linespace = 40; //行间距
int linewidth = 8; //线宽
int R = 0;
int G = 0;
int B = 0;
int x = (this->width() - row * diameter - (row - 1) * wlength) / 2;
int y = -70;
int xR = 0; //路径公里数显示位置的x坐标
int xT = this->width() / 3; //换乘数显示位置的x坐标
int xP = this->width() * 2 / 3; //票价显示位置的x坐标
int xS = this->width() / 2; //游览景点数显示位置的x坐标
int yT = this->height() - 15; //文字显示位置的y坐标
int xTT = 0; //旅游推荐文字显示位置的x坐标
int yTT = this->height() - 35; //旅游推荐文字显示位置的y坐标
if (edgeNum == 0) {
painter.setPen(QPen(Qt::black));
painter.setFont(QFont("楷体", 15, QFont::Bold));
painter.drawText(0,0,QString::fromStdString("起点站与终点站重合"));
return;
}
for (int i = 0; i < edgeNum + 1; i++) {
/*控制正负——延伸方向*/
if (i % row == 0) {
sign = -sign;
y += (diameter + linespace);
}
else {
x += (diameter + wlength) * sign;
}
/*设置圆内的填充颜色*/
if (i == 0) { //起点站设为红色
QBrush brush(QColor(255, 0, 0), Qt::Dense4Pattern);
painter.setBrush(brush);
}
else if (i == edgeNum) { //终点设为绿色
QBrush brush(QColor(0, 255, 0), Qt::Dense4Pattern);
painter.setBrush(brush);
}
else if (route[i].line != route[i - 1].line) { //换乘站设为黄色
QBrush brush(QColor(255, 215, 0), Qt::Dense4Pattern);
painter.setBrush(brush);
}
else {
QBrush brush(QColor(30, 144, 255), Qt::Dense4Pattern);
painter.setBrush(brush);
}
/*读取线路颜色*/
if (i < edgeNum) {
QFile colorL(":/files/files/colorL.txt");
colorL.open(QIODevice::ReadOnly);
QTextStream in(&colorL);
while (true) {
QString array = in.readLine();
array = array.trimmed();
if (array.isNull()) {
break;
}
QStringList parts = array.split(","); //按","分割
if (parts.at(0).toInt() == route[i].line) {
R = parts.at(1).toInt();
G = parts.at(2).toInt();
B = parts.at(3).toInt();
break;
}
}
}
/*设置圆的颜色和画圆*/
painter.setPen(QPen(QColor(0, 0, 128), 2, Qt::SolidLine, Qt::RoundCap));
painter.drawEllipse(x, y, diameter, diameter);
/*画站点间的连线*/
if (i % row == row - 1 && i < edgeNum) { //上拐点,线路向下延伸
painter.setPen(QPen(QColor(R, G, B), linewidth, Qt::SolidLine, Qt::RoundCap));
painter.drawLine(QLine(x + diameter / 2, y + diameter, x + diameter / 2, y + (diameter + linespace)));
}
else if (sign > 0 && i < edgeNum) { //向右延伸
painter.setPen(QPen(QColor(R, G, B), linewidth, Qt::SolidLine, Qt::RoundCap));
painter.drawLine(QLine(x + diameter, y + diameter / 2, x + (diameter + wlength), y + diameter / 2));
}
else if (sign < 0 && i < edgeNum) {
painter.setPen(QPen(QColor(R, G, B), linewidth, Qt::SolidLine, Qt::RoundCap));
painter.drawLine(QLine(x - wlength, y + diameter / 2, x, y + diameter / 2));
}
/*显示站点名称*/
if (i < edgeNum) {
painter.setPen(QPen(Qt::black));
painter.setFont(QFont("宋体", 12, QFont::Bold));
painter.drawText(x, y + 40, QString::fromStdString(g.getStationName(route[i].from)));
}
else if (i == edgeNum && i != 0) {
painter.setPen(QPen(Qt::black));
painter.setFont(QFont("宋体", 12, QFont::Bold));
painter.drawText(x, y + 40, QString::fromStdString(g.getStationName(route[edgeNum - 1].to)));
}
else if (i == 0) {
painter.setPen(QPen(Qt::black));
painter.setFont(QFont("宋体", 12, QFont::Bold));
painter.drawText(x, y + 40, QString::fromStdString(start));
}
}
/*显示路径里程、换乘数、票价*/
string origP = to_string(currentCost);
string cheapP = to_string(currentCost * calSale());
painter.setPen(QPen(Qt::black));
painter.setFont(QFont("楷体", 15, QFont::Bold));
painter.drawText(xR, yT, QString::fromStdString("该出行方案总里程:" + to_string(length) + "米"));
painter.drawText(xT, yT, QString::fromStdString("换乘数:" + to_string(transNum) + "次"));
painter.drawText(xTT, yTT, QString::fromStdString("为您推荐站点:" + g.getStationName(route[edgeNum - 1].to) + " 该站点距 " + spot + " 步行距离为" + to_string(footMiles) + "米"));
painter.drawText(xP, yT, QString::fromStdString("优惠价:" + cheapP.substr(0, cheapP.find(".") + 1 + 1) + "元(原价:" + origP.substr(0, origP.find(".") + 1 + 1) + ")"));
painter.drawText(xS, yT, QString::fromStdString("景点站数:" + to_string(spotsN) + "个"));
painter.end();
}
void Twidget::setAttr(Edge* r, int EdgeN, int TransN, int l,int footmiles,std::string s, std::string sp) {
if (paintMode != 2) {//不在“游览多景点规划”状态
delete[] route;
route = new Edge[EdgeN];
for (int i = 0; i < EdgeN; i++) {
route[i] = r[i];
}
edgeNum = EdgeN;
transNum = TransN;
length = l;
currentLength = l;
footMiles = footmiles;
start = s;
spot = sp;
calcost(length);
}
else if(paintMode==2) //在“游览多景点规划”状态,在原来的边集上追加
{
if (EdgeN == 0) {
spot = sp;
return;
}
//edgeNum += EdgeN;
Edge* tempEdge = new Edge[edgeNum+EdgeN];
for (int i = 0; i < edgeNum + EdgeN; i++) {
if (i < edgeNum) {
tempEdge[i] = route[i];
}
else {
tempEdge[i] = r[i - edgeNum];
}
}
delete[] route;
edgeNum += EdgeN;
route = tempEdge;
transNum += TransN; //换乘数追加
length += l; //路径长度追加
currentLength = l; //当前路径长度更新
footMiles = footmiles;
//start = s; //起点不更新
spot = sp;
spotsN++;
calcost(currentLength);
}
}
void Twidget:: calcost(int len) {
int cost = 0; //价格
int upLimit = 0; //目前最高价格——当价格进入“每增加XX公里,增收XX元”范围内时使用
int lenLimit = 0;//目前最高里程——当价格进入“每增加XX公里,增收XX元”范围内时使用
QFile priceT(":/files/files/ticketPrice.txt");
priceT.open(QIODevice::ReadOnly);
QTextStream readP(&priceT);
QRegularExpression sepatator("-|,");//以-和,分割
for (int j = 0;; j++)
{
QString infoP = readP.readLine();
infoP = infoP.trimmed();
if (infoP.isNull()) {
break;
}
if (j != 0) { //表头不读
if (infoP.at(0).toLatin1() != '/') { //不是按“每增加XX公里,增收XX元”规律递增
QStringList partsP = infoP.split(sepatator);
upLimit = partsP.at(2).toInt(); //记录当前最高价格
lenLimit = partsP.at(1).toInt(); //记录当前最高里程
if (len / 1000 >= partsP.at(0).toInt() && len / 1000 < partsP.at(1).toInt()) {
cost = partsP.at(2).toInt();
break;
}
}
else if (len / 1000 >= lenLimit) {
QStringList partsP2 = infoP.split(",");
QString perKM(partsP2.at(0));
QString add(partsP2.at(1));
perKM.remove('/');
add.remove('+');
int everyKM = perKM.toInt();
int delta = add.toInt();
int spend = ceil(((float)len / 1000 - lenLimit) / everyKM) * delta + upLimit;
cost = spend;
break;
}
}
if (len == 0) {
cost = 0;
break;
}
}
priceT.close();
if (paintMode != 2) {
currentCost = cost;
}
else {
currentCost += cost;
}
}
int Twidget::getPaintMode() const {
return paintMode;
}
int Twidget::getEdgeNum()const {
return edgeNum;
}
Edge* Twidget::getEdge() {
return route;
}
void Twidget::setPaintMode(int i) {
paintMode = i;
}
void Twidget::setSpotNum(int num) {
spotsN = num;
}
void Twidget::spotsPlus() {
spotsN++;
}
float Twidget::calSale() {
if (spotsN <= 1) {
return 1;
}
float discount = 0;
QFile Tticket(":/files/files/sale.txt");
Tticket.open(QIODevice::ReadOnly);
QTextStream readP(&Tticket);
for (int j = 0;; j++)
{
QString infoP = readP.readLine();
infoP = infoP.trimmed();
if (infoP.isNull()) {
break;
}
if (j != 0) { //表头不读
if (infoP.at(0).toLatin1() != '>') { //不是最后一行
QStringList partsP = infoP.split(",");
if (spotsN == partsP.at(0).toInt()) {
QString discountT(partsP.at(1));
discount = discountT.toFloat();
break;
}
}
else if (infoP.at(0).toLatin1() == '>') {
QStringList partsP = infoP.split(",");
QString discountT(partsP.at(1));
discount = discountT.toFloat();
break;
}
}
}
Tticket.close();
return discount;
}
void Twidget::clearEdge() {
delete[] route;
edgeNum = 0;
route = NULL;
update();
}
void Twidget::clearAccuCost() {
currentCost = 0;
}
void Twidget::clearLength() {
length = 0;
}
void Twidget::clearTrans() {
transNum = 0;
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化