QT天气预报

 1.界面设计

在这里插入图片描述

 2.开发

  2.1 重写鼠标右键退出功能

	重写鼠标右键点击事件 + QMenu:
	/*
 QMenu menu;
 QAction *at = actions[0]; // Assumes actions is not empty
 foreach (QAction *a, actions)
     menu.addAction(a);
 menu.exec(pos, at);

*/
void Widget::mousePressEvent(QMouseEvent *event)
{
    if(event->button() == Qt::RightButton){
       menuQuit->exec(QCursor::pos());  //光标点击的当前位置执行
    }
    QWidget::mousePressEvent(event);
}

void Widget::rightMouseClicked()
{
    menuQuit = new QMenu(this);
    QAction *closeAct = new QAction(QIcon(":/res/close.png"), tr("退出"), this);
    menuQuit->addAction(closeAct);

    //[signal] void QMenu::triggered(QAction *action)
    connect(menuQuit,&QMenu::triggered,this,[=](){
        this->close();
    });
}

  2.2 重写鼠标左键移动窗口

	如下图所示:
	鼠标右键点击窗口有鼠标的点击坐标:event->globalPos();
	窗口有窗口的坐标:this->Pos();
	在鼠标点击窗口移动的时候,鼠标的坐标A与窗口坐标B相对的偏移量moffset不会变
	QPoint moffset = event->globalPos() - this->Pos();
	窗口移动到图中黑框的位置时,鼠标的坐标处在一个新的A点上,
	但是A点相较于新窗口点C的偏移量与原来的A点相较于B点的偏移量没有改变
	因此,在已知新坐标点A与固定偏移量的情况下C点可求
	新窗口的坐标点位为:event->globalPos() - moffset 
	然后再对鼠标移动事件进行重写

在这里插入图片描述

void Widget::mousePressEvent(QMouseEvent *event)
{
    if(event->button() == Qt::RightButton){
       menuQuit->exec(QCursor::pos());  //光标点击的当前位置执行
    }

    //鼠标当前位置:event->globalPos()
    //窗口当前位置:this->pos()
    //窗口新位置: event->globalPos()-moffset
    if(event->button() == Qt::LeftButton){
        qDebug() << event->globalPos()<< this->pos();
        moffset = event->globalPos() - this->pos();
    }

    QWidget::mousePressEvent(event);
}

//重写鼠标左键移动事件
void Widget::mouseMoveEvent(QMouseEvent *event)
{
    this->move(event->globalPos()-moffset);
    QWidget::mouseMoveEvent(event);
}

  2.3 QtHttp编程获取天气原始数据

    2.3.1 发送HTTP请求

类:
	QNetworkAccessManager
	QNetworkRequest
    
    QNetworkAccessManager *manager = new QNetworkAccessManager(this);
    QNetworkRequest res(QUrl("http://t.weather.itboy.net/api/weather/city/101010100"));

    2.3.2 读取数据

	QNetworkReply *reply = manager->get(res);
	//网络请求后进行数据读取
    connect(reply,SIGNAL(finished()),this,SLOT(readHttpReply()));

	void Widget::readHttpReply()
	{
    	QByteArray data = reply->readAll();
    	qDebug() << QString::fromUtf8(data);
	}

    2.3.3 处理网络失败请求

	http请求返回200请求成功
void Widget::readHttpReply()
{
    int resCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    qDebug() <<resCode;
    if(reply->error() == QNetworkReply::NoError && resCode == 200){
        //大多数返回utf-8
        QByteArray data = reply->readAll();
        qDebug() << QString::fromUtf8(data);
    }else{
        QMessageBox msgBox;
        msgBox.setWindowTitle("错误");
        msgBox.setText("网络请求失败");
        msgBox.setStandardButtons(QMessageBox::Ok);
        qDebug() << reply->errorString();
        msgBox.exec();
    }
}

  2.4 JSON数据

    2.4.1 QT生成JSON数据

	键值对-- 对象[] = "值";
类:
	QJsonDocument
	QJsonObject
	QJsonArray
方法:
	1. 创建JSON对象:使用 QJsonObject 来构建JSON对象,并使用键值对填充数据。
	2. 创建JSON数组:使用 QJsonArray 来创建一个数组,并添加元素。
	3. 组合JSON结构:将JSON数组添加到JSON对象中。
	4. 生成JSON文档:通过 QJsonDocument 来处理JSON数据,可以选择格式化(缩进)或压缩形式。
	5. 保存到文件:创建 QFile 对象,打开文件,写入JSON数据,并关闭文件。
    QJsonObject rootObj;
    //添加键值对
    rootObj["cityid"] = "1010100";
    rootObj["date"] = "2024-4-6";
    rootObj["weather"] = "雨夹雪";
    rootObj["tmp"] = 3;

    //添加数组
    QJsonArray jsonArr;
    jsonArr.append("data1");
    jsonArr.append("data2");
    jsonArr.append("data3");
    jsonArr.append(100);
    rootObj["testArr"] = jsonArr;

    //添加对象
    QJsonObject jsonObject;
    jsonObject = rootObj;
    rootObj["jsonObject"] = jsonObject;

    //数组中添加对象
    QJsonArray jsObArr;
    jsObArr.append(jsonObject);
    jsObArr.append(jsonObject);
    rootObj["jsObArr"] = jsObArr;

    //生成JSON文件
    QJsonDocument jsonDoc(rootObj);
    //转成数组
    QByteArray jsonArray = jsonDoc.toJson();
    //写入文件
    QFile file("C:/Users/qzh/Desktop/test.json");
    file.open(QIODevice::WriteOnly);
    file.write(jsonArray);
    file.close();

在这里插入图片描述

    2.4.2 QT解析JSON数据

	1.读取JSON数据
	2.生成JSON文件
	3.转成JSON对象
	QFile file("C:/Users/qzh/Desktop/test.json");
    file.open(QIODevice::ReadOnly);
    QByteArray rawData = file.readAll();
    file.close();

    QJsonDocument jsonDoc = QJsonDocument::fromJson(rawData);
    if(!jsonDoc.isNull() && jsonDoc.isObject()){    //不是json对象转成json对象
        QJsonObject jsonRoot = jsonDoc.object();
        QString strW = jsonRoot["weather"].toString();
        QString strCityId = jsonRoot["cityid"].toString();
        qDebug() << strW;
        qDebug() << strCityId;

        //JSON数组处理
        if(jsonRoot.contains("testArr") && jsonRoot["testArr"].isArray()){
            //1.先转成数组
            QJsonArray testArray = jsonRoot["testArr"].toArray();
            for(QJsonValue val : testArray){
                QJsonValue::Type t = val.type();
                switch(t){
                case QJsonValue::Double:
                    qDebug() << QString::number(val.toDouble());
                    break;
                case QJsonValue::String:
                    qDebug() << val.toString();
                    break;
                case QJsonValue::Object:
                    break;

                }
            }

        }
        //处理json对象
        if(jsonRoot.contains("jsonObject") && jsonRoot["jsonObject"].isObject()){
            //转成Json对象
            QJsonObject jsonObject = jsonRoot["jsonObject"].toObject();
            qDebug() << "jsonObject"<<jsonObject["cityid"].toString();
        }

        //处理JSON数组中的对象
        if(jsonRoot.contains("testArr") && jsonRoot["testArr"].isArray()){
            QJsonArray jsObArr = jsonRoot["jsObArr"].toArray();
            for(QJsonValue val : jsObArr){
                if(val.isObject()){
                    QJsonObject obj = val.toObject();
                    qDebug() << obj["weather"].toString();
                    qDebug() << obj["cityid"].toString();
                }
            }
        }
    }

  2.5 获取当前城市天气数据

全局变量
    QNetworkReply *reply;
    QString strUrl;
    QNetworkAccessManager *manager;
	1.创建一个QNetworkAccessManager对象manager
	manager = new QNetworkAccessManager(this);
	2.发送请求
	strUrl = "http://v1.yiketianqi.com/api?unescape=1&version=v61&appid=87767798&appsecret=7Ujk853M";
    QUrl urlTianQi(strUrl);
    QNetworkRequest res(urlTianQi);
    manager->get(res);
    3.QNetworkReply获得相应,并将相关数据存储在replay中
    4.绑定信号与槽,manager响应完成后触发数据处理
    void Widget::readHttpReply(QNetworkReply *reply)
{
    int resCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    if(reply->error() == QNetworkReply::NoError && resCode == 200){
        //大多数返回utf-8
        QByteArray data = reply->readAll();
        parseWeatherJsonData(data);//解析数据并刷新控件
        qDebug() << QString::fromUtf8(data);
    }else{
        QMessageBox msgBox;
        msgBox.setWindowTitle("错误");
        msgBox.setText("网络请求失败");
        msgBox.setStandardButtons(QMessageBox::Ok);
        qDebug() << reply->errorString();
        msgBox.exec();
    }
}

//解析数据并刷新控件
void Widget::parseWeatherJsonData(QByteArray rawData)
{
    QJsonDocument jsonObj = QJsonDocument::fromJson(rawData);
    if(!jsonObj.isNull() && jsonObj.isObject()){
        QJsonObject objRoot = jsonObj.object();
        //解析日期
        QString date = objRoot["date"].toString();
        QString week = objRoot["week"].toString();
        ui->labelCurrentDate->setText(date+"  "+ week);
        //解析城市名称
        QString cityName = objRoot["city"].toString();
        ui->labelCity->setText(cityName);
        //解析当前温度
        QString currentTmp = objRoot["tem"].toString();
        ui->labelWendu->setText(currentTmp+"℃");
        ui->labelWeatherRange->setText(objRoot["tem2"].toString()+"~"+objRoot["tem1"].toString());
        //解析天气类型
        ui->labelWeatherType->setText(objRoot["wea"].toString());

        //感冒指数
        ui->labelGanmao->setText(objRoot["air_tips"].toString());
        //风向
        ui->labelFXtype->setText(objRoot["win"].toString());
        //风力
        ui->labelFXtype_2->setText(objRoot["win_speed"].toString());
        //PM2.5
        ui->labelPMData->setText(objRoot["air_pm25"].toString());
        //湿度
        ui->labelShiduData->setText(objRoot["humidity"].toString());
        //空气质量
        ui->labelAirData->setText(objRoot["air_level"].toString());
    }
}

  2.6 获取不同城市数据信息

	1.当搜查按钮点击后触发信号与槽
	2.读取当前ui->lineEdit控件的内容
	3.解析json格式的城市编码并与当前控件内容进行匹配
	4.刷新控件-
	由于数据的读取绑定的信号是QNetworkAccessManager::finished,
	所当在点击按钮后重对新的url发送请求完成后会触发槽函数进行数据解析
	和刷新相关控件操作
	void Widget::on_pushButton_clicked()
{
    QString cityNameFromUser = ui->lineEditCity->text();
    QString cityCode = getCityCodeFromJson(cityNameFromUser);
    if(cityCode != NULL){
        strUrl += "&cityid=" + cityCode;                 //拼接url
        manager->get(QNetworkRequest(QUrl(strUrl)));    //发送请求
    }else{
        QMessageBox msgBox;
        msgBox.setWindowTitle("错误");
        msgBox.setText("请输入正确城市名");
        msgBox.setStandardButtons(QMessageBox::Ok);
        qDebug() << reply->errorString();
        msgBox.exec();
    }
}

QString getCityCodeFromJson(QString name)
{
    QFile file(":/citycode.json");
    file.open(QIODevice::ReadOnly);
    QByteArray rawData = file.readAll();
    file.close();

    QJsonDocument jsonDoc = QJsonDocument::fromJson(rawData);
    if(jsonDoc.isArray()){
        QJsonArray citys = jsonDoc.array();
        for(QJsonValue val : citys){
            if(val.isObject()){
                QString cityName = val["city_name"].toString();
                if(cityName == name){
                    return val["city_code"].toString();
                }
            }
        }
        return "";
    }
}

  2.7 QMap

    2.7.1 将CityName与CityCode产生联系

	由于每次打开之前都需要打开文件,会很麻烦,所以引入Map容器
	在打开的时候检查Map容器是否为空,为空则打开文件将文件内容存储在Map容器中,后续只需要检查Map容器是否为空即可

QMap<QString,int> myMap; //创建一个存储QString类型的键和int型的值的map容器
QMap<QString,QString> cityMap;  //创建存储一个QString类型的键和QString类型的值的map容器

QString CityCodeUtils::getCityCodeFromName(QString cityName)
{
    if(cityMap.isEmpty()){
        initCityMap();
    }
     QMap<QString, QString>::iterator it =   cityMap.find(cityName);  //查找cityName
     if(it == cityMap.end()){   //未找到
        it =   cityMap.find(cityName+"市");
        if(it == cityMap.end()){   //未找到
           it =   cityMap.find(cityName+"县");
        }
        if(it == cityMap.end()){   //未找到
           it =   cityMap.find(cityName+"区");
        }
        if(it == cityMap.end()){   //未找到
           return "";
        }
     }
     return it.value(); //获得cityCode
}

void CityCodeUtils::initCityMap()
{
    QFile file(":/citycode.json");
    file.open(QIODevice::ReadOnly);
    QByteArray rawData = file.readAll();
    file.close();

    QJsonDocument jsonDoc = QJsonDocument::fromJson(rawData);
    if(jsonDoc.isArray()){
        QJsonArray citys = jsonDoc.array();
        for(QJsonValue val : citys){
            if(val.isObject()){
                QString cityName = val["city_name"].toString();
                QString cityCode = val["city_code"].toString();
                cityMap.insert(cityName,cityCode);  //将cityName和cityCode以键值对的方式插入到map容器中
            }
        }
    }
}

    2.7.1 将天气图标与天气类型产生联系

void Widget::initWeatherIcon()
{
    //根据keys,设置icon的路径
    mTypeMap.insert("暴雪",":/res/type/BaoXue.png");
    mTypeMap.insert("暴雨",":/res/type/BaoYu. png");
    mTypeMap.insert("暴雨到大暴雨",":/res/type/BaoYuDaoDaBaoYu.png");
    mTypeMap.insert("大暴雨",":/res/type/DaBaoYu.png");
    mTypeMap.insert("大暴雨到特大暴雨",":/res/type/DaBaoYuDaoTeDaBaoYu.png");
    mTypeMap.insert("大到暴雪",":/res/type/DaDaoBaoXue.png");
    mTypeMap.insert("大雪",":/res/type/DaXue.png");
    mTypeMap.insert("大雨",":/res/type/DaYu.png");
    mTypeMap.insert("冻雨",":/res/type/DongYu.png");
    mTypeMap.insert("多云",":/res/type/DuoYun.png");
    mTypeMap.insert("浮沉",":/res/type/FuChen.png");
    mTypeMap.insert("雷阵雨",":/res/type/LeiZhenYu.png");
    mTypeMap.insert("雷阵雨伴有冰雹",":/res/type/LeiZhenYuBanYouBingBao.png");
    mTypeMap.insert("霾",":/res/type/Mai.png");
    mTypeMap.insert("强沙尘暴",":/res/type/QiangShaChenBao.png");
    mTypeMap.insert("晴",":/res/type/Qing.png");
    mTypeMap.insert("沙尘暴",":/res/type/ShaChenBao.png");
    mTypeMap.insert("特大暴雨",":/res/type/TeDaBaoYu.png");
    mTypeMap.insert("undefined",":/res/type/undefined.png");
    mTypeMap.insert("雾",":/res/type/Wu.png");
    mTypeMap.insert("小到中雪",":/res/type/XiaoDaoZhongXue.png");
    mTypeMap.insert("小到中雨",":/res/type/XiaoDaoZhongYu.png");
    mTypeMap.insert("小雪",":/res/type/XiaoXue.png");
    mTypeMap.insert("小雨",":/res/type/XiaoYu.png");
    mTypeMap.insert("雪",":/res/type/Xue.png");
    mTypeMap.insert("扬沙",":/res/type/YangSha.png");
    mTypeMap.insert("阴",":/res/type/Yin.png");
    mTypeMap.insert("雨",":/res/type/Yu.png");
    mTypeMap.insert("雨夹雪",":/res/type/YuJiaXue.png");
    mTypeMap.insert("阵雪",":/res/type/ZhenXue.png");
    mTypeMap.insert("阵雨",":/res/type/ZhenYu.png");
    mTypeMap.insert("中到大雪",":/res/type/ZhongDaoDaXue.png");
    mTypeMap.insert("中到大雨",":/res/type/ZhongDaoDaYu.png");
    mTypeMap.insert("中雪",":/res/type/ZhongXue.png");
    mTypeMap.insert("中雨",":/res/type/ZhongYu.png");
}

	ui->labelWeatherIcon->setPixmap(mTypeMap[objRoot["wea"].toString()]);

  2.8 获得最近七天的数据

	strUrl = "http://v1.yiketianqi.com/api?unescape=1&version=v91&appid=87767798&appsecret=7Ujk853M&ext=";
	1.定义一个新的类Day用于存储一天的全部信息
	class Day
{
public:
    Day();
    QString mDate;
    QString mWeek;
    QString mCity;
    QString mTemp;
    QString mWeathType;
    QString mTempLow;
    QString mTempHigh;

    QString mTips;
    QString mFx;
    QString mFl;
    QString mPm25;
    QString mHu;
    QString mAirq;
};

	2.解析新的url获取的json数据-并将数据存储在数组中
	Day days[7];
	
	void Widget::parseWeatherJsonDataNew(QByteArray rawData)
{
    QJsonDocument jsonDoc = QJsonDocument::fromJson(rawData);
    if( !jsonDoc.isNull() && jsonDoc.isObject()){
        QJsonObject jsonRoot = jsonDoc.object();
        days[0].mCity = jsonRoot["city"].toString();
        days[0].mPm25 = jsonRoot["aqi"].toObject()["pm25"].toString();
        if( jsonRoot.contains("data") && jsonRoot["data"].isArray()){
            QJsonArray weaArray = jsonRoot["data"].toArray();
            for(int i = 0; i < weaArray.size(); i++){
                QJsonObject obj = weaArray[i].toObject();
                //qDebug() << obj["date"].toString() << obj["wea"].toString();
                days[i].mDate = obj["date"].toString();
                days[i].mWeek = obj["week"].toString();
                days[i].mWeathType = obj["wea"].toString();
                days[i].mTemp = obj["tem"].toString();
                days[i].mTempLow = obj["tem2"].toString();
                days[i].mTempHigh = obj["tem1"].toString();
                days[i].mFx = obj["win"].toArray()[0].toString();
                days[i].mFl = obj["win_speed"].toString();
                days[i].mAirq = obj["air_level"].toString();
                days[i].mTips = obj["air_tips"].toString();
                days[i].mHu = obj["humidity"].toString();

            }
        }
    }
    updateUI();
}

	3.设置QList泛型并初始化
	QList<QLabel *> mDateList;
    QList<QLabel *> mWeekList;
    QList<QLabel *> mIconList;
    QList<QLabel *> mWeaTypeList;
    QList<QLabel *> mAirqList;
    QList<QLabel *> mFxList;
    QList<QLabel *> mFlList;
    void Widget::initDaysElement()
{
    mWeekList << ui->labelday0 << ui->labelday1
              << ui->labelday2 << ui->labelday3
              << ui->labelday4 << ui->labelday5;
    mDateList << ui->labelDate0 << ui->labelDate1
              << ui->labelDate2 << ui->labelDate3
              << ui->labelDate4 << ui->labelDate5;
    mIconList << ui->labelWeatherIcon0 << ui->labelWeatherIcon1
              << ui->labelWeatherIcon2 << ui->labelWeatherIcon3
              << ui->labelWeatherIcon4 << ui->labelWeatherIcon5;
    mWeaTypeList << ui->lbweatherType0 << ui->lbweatherType1
                 << ui->lbweatherType2 << ui->lbweatherType3
                 << ui->lbweatherType4 << ui->lbweatherType5;
    mAirqList << ui->labelq0 << ui->labelq1
              << ui->labelq2 << ui->labelq3
              << ui->labelq4 << ui->labelq5;
    mFxList << ui->labelFX0 << ui->labelFX1
            << ui->labelFX2 << ui->labelFX3
            << ui->labelFX4 << ui->labelFX5;
    mFlList << ui->labelFL0 << ui->labelFL1
            << ui->labelFL2 << ui->labelFL3
            << ui->labelFL4 << ui->labelFL5;
}
	4.通过泛型设置对应控件
	void Widget::updateUI()
{
    QPixmap pixMap;
    //解析日期
    ui->labelCurrentDate->setText(days[0].mDate+"  "+days[0].mWeek);
    //解析城市名称
    ui->labelCity->setText(days[0].mCity+"市");
    //解析当前温度
    ui->labelWendu->setText(days[0].mTemp+"℃");
    ui->labelWeatherRange->setText(days[0].mTempLow+"~"
            +days[0].mTempHigh);
    //解析天气类型
    ui->labelWeatherType->setText(days[0].mWeathType);
    ui->labelWeatherIcon->setPixmap(mTypeMap[days[0].mWeathType]);
    //感冒指数
    ui->labelGanmao->setText(days[0].mTips);
    //风向
    ui->labelFXtype->setText(days[0].mFx);
    //风力
    ui->labelFXtype_2->setText(days[0].mFl);
    //PM2.5
    ui->labelPMData->setText(days[0].mPm25);
    //湿度
    ui->labelShiduData->setText(days[0].mHu);
    //空气质量
    ui->labelAirData->setText(days[0].mAirq);


    for(int i = 0; i < 6; i++){
        mWeekList[0]->setText("今天");
        mWeekList[1]->setText("明天");
        mWeekList[2]->setText("后天");
        mWeekList[i]->setText(days[i].mWeek);
        QStringList dayList = days[i].mDate.split("-"); //2024-4-7 通过-分割成三部分 0:2024, 1:4, 2:7
        mDateList[i]->setText(dayList[1] + "-" +dayList[2]);

        //缩放图片大小与label大小能匹配
        int index = days[i].mWeathType.indexOf("转");    //找不到 “转” 返回-1
        if(index != -1){
            pixMap = mTypeMap[days[i].mWeathType.left(index)];  //找到了字符转的位置,将左边取出
        }else{
            pixMap = mTypeMap[days[i].mWeathType];
        }
        pixMap = pixMap.scaled(mIconList[i]->size(),Qt::KeepAspectRatio,Qt::SmoothTransformation);
        mIconList[i]->setMaximumHeight(50);
        mIconList[i]->setMinimumWidth(ui->widget0402->width()/6.5);
        mIconList[i]->setPixmap(pixMap);
        mWeaTypeList[i]->setText(days[i].mWeathType);

        QString airQ = days[i].mAirq;

        mAirqList[i]->setText(days[i].mAirq);
        if( airQ == "优"){
            mAirqList[i]->setStyleSheet("background-color:rgb(150,213,32);border-radius: 10px;");
        }else if(airQ == "良"){
            mAirqList[i]->setStyleSheet("background-color:rgb(241,224,103);border-radius: 10px;");
        }else if(airQ == "轻度"){
            mAirqList[i]->setStyleSheet("background-color:rgb(255,199,199);border-radius: 10px;");
        }else if(airQ == "中度"){
            mAirqList[i]->setStyleSheet("background-color:rgb(255,17,17);border-radius: 10px;");
        }else if(airQ == "重度"){
            mAirqList[i]->setStyleSheet("background-color:rgb(153,0,0);border-radius: 10px;");
        }


        mFlList[i]->setText(days[i].mFl);
        index = days[i].mFl.indexOf("转");
        if(index != -1){
            mFlList[i]->setText(days[i].mFl.left(index));
        }else{
            mFlList[i]->setText(days[i].mFl);
        }
        mFxList[i]->setText(days[i].mFx);
    }
}

  2.9 事件过滤器在子控件上画线

	若直接通过重写paintEvent事件,则会被layout遮挡
	因此通过事件过滤对事件过滤在子控件上画线
    ui->widget0404->installEventFilter(this);
    ui->widget0405->installEventFilter(this);

bool Widget::eventFilter(QObject *watched, QEvent *event)
{
    if(watched == ui->widget0404 && event->type() == QEvent::Paint){
        drawTempLineHight();
        return true; //事件被处理返回true
    }
    if(watched == ui->widget0405 && event->type() == QEvent::Paint){
        drawTempLineLow();
        return true; //事件被处理返回true
    }
    return QWidget::eventFilter(watched,event);
}

void Widget::drawTempLineHight()
{
    QPainter painter(ui->widget0404);   //在0404子控件上画画
    painter.setRenderHint(QPainter::Antialiasing,true);
    painter.setBrush(Qt::yellow);
    painter.setPen(Qt::yellow);

    //算出平均温度,以平均值为中线进行偏移
    int ave;
    int sum = 0;
    int offset;
    int middle = ui->widget0404->height()/2;
    for(int i=0 ; i < 6 ;i++){
        sum += days[i].mTempHigh.toInt();
        qDebug() << days[i].mTempHigh;
    }
    ave = sum/6;
    //定义出6个点
    QPoint points[6];
    for(int i = 0; i < 6; i++){
        points[i].setX(mAirqList[i]->x() + mAirqList[i]->width()/2);
        offset = days[i].mTempHigh.toInt() - ave;
        points[i].setY(middle - offset*3);

        painter.drawEllipse(QPoint(points[i]),3,3); //画点
        painter.drawText(points[i].x()-15,points[i].y()-15,days[i].mTempHigh + "℃");
    }
    painter.setBrush(Qt::NoBrush);
    for(int i=0;i<5;i++){
        painter.drawLine(points[i],points[i+1]);    //画线

    }
}

void Widget::drawTempLineLow()
{
    QPainter painter(ui->widget0405);   //在0404子控件上画画
    painter.setRenderHint(QPainter::Antialiasing,true);
    painter.setBrush(Qt::blue);
    painter.setPen(Qt::blue);

    //算出平均温度,以平均值为中线进行偏移
    int ave;
    int sum = 0;
    int offset;
    int middle = ui->widget0405->height()/2;
    for(int i=0 ; i < 6 ;i++){
        sum += days[i].mTempLow.toInt();
        qDebug() << days[i].mTempLow;
    }
    ave = sum/6;
    //定义出6个点
    QPoint points[6];
    for(int i = 0; i < 6; i++){
        points[i].setX(mAirqList[i]->x() + mAirqList[i]->width()/2);
        offset = days[i].mTempLow.toInt() - ave;
        points[i].setY(middle - offset*3);

        painter.drawEllipse(QPoint(points[i]),3,3); //画点
        painter.drawText(points[i].x()-15,points[i].y()-15,days[i].mTempLow + "℃");
    }
    for(int i=0;i<5;i++){
        painter.drawLine(points[i],points[i+1]);    //画线
    }
}

  2.10 LineEdit的returnPressed()

//相当于添加enter快捷键enter按下后进行搜索
void Widget::on_lineEditCity_returnPressed()
{
    on_pushButton_clicked();
}

 3.最终效果

在这里插入图片描述

链接:https://pan.baidu.com/s/1m9eJfvXX7RXK3_ksb7U4hA 
提取码:sw2n 
--来自百度网盘超级会员V5的分享

相关推荐

  1. AJAX——案例_天气预报

    2024-04-08 06:28:01       15 阅读
  2. 天气预报爬虫-多城市-更新版

    2024-04-08 06:28:01       36 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-08 06:28:01       14 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-08 06:28:01       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-08 06:28:01       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-08 06:28:01       18 阅读

热门阅读

  1. node.js常用指令

    2024-04-08 06:28:01       11 阅读
  2. Node.js 常用命令及其详细用法

    2024-04-08 06:28:01       15 阅读
  3. 单片机学习day4

    2024-04-08 06:28:01       13 阅读
  4. c++STL list 简单模拟实现

    2024-04-08 06:28:01       12 阅读
  5. 【STL】链表(list)

    2024-04-08 06:28:01       11 阅读
  6. C#面:在 .NET 中如何取消一个窗体的关闭

    2024-04-08 06:28:01       12 阅读
  7. Vue ElementUI resetForm()表单重置问题

    2024-04-08 06:28:01       12 阅读
  8. 【Vue3】解决 Props 没有默认值而报错的问题

    2024-04-08 06:28:01       14 阅读
  9. Django-用户登录

    2024-04-08 06:28:01       14 阅读