QT-天气预报
1.界面设计 2.开发 2.1 重写鼠标右键退出功能 2.2 重写鼠标左键移动窗口 2.3 QtHttp编程获取天气原始数据 2.3.1 发送HTTP请求 2.3.2 读取数据 2.3.3 处理网络失败请求
2.4 JSON数据 2.4.1 QT生成JSON数据 2.4.2 QT解析JSON数据
2.5 获取当前城市天气数据 2.6 获取不同城市数据信息 2.7 QMap 2.7.1 将CityName与CityCode产生联系 2.7.1 将天气图标与天气类型产生联系
2.8 获得最近七天的数据 2.9 事件过滤器在子控件上画线 2.10 LineEdit的returnPressed()
3.最终效果
1.界面设计
2.开发
2.1 重写鼠标右键退出功能
重写鼠标右键点击事件 + QMenu:
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) ;
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 ( ) ) ;
}
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 ) {
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;
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 ( ) ) {
QJsonObject jsonRoot = jsonDoc. object ( ) ;
QString strW = jsonRoot[ "weather" ] . toString ( ) ;
QString strCityId = jsonRoot[ "cityid" ] . toString ( ) ;
qDebug ( ) << strW;
qDebug ( ) << strCityId;
if ( jsonRoot. contains ( "testArr" ) && jsonRoot[ "testArr" ] . isArray ( ) ) {
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 ;
}
}
}
if ( jsonRoot. contains ( "jsonObject" ) && jsonRoot[ "jsonObject" ] . isObject ( ) ) {
QJsonObject jsonObject = jsonRoot[ "jsonObject" ] . toObject ( ) ;
qDebug ( ) << "jsonObject" << jsonObject[ "cityid" ] . toString ( ) ;
}
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 ) {
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 ( ) ) ;
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;
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;
QMap< QString, QString> cityMap;
QString CityCodeUtils:: getCityCodeFromName ( QString cityName)
{
if ( cityMap. isEmpty ( ) ) {
initCityMap ( ) ;
}
QMap< QString, QString> :: iterator it = cityMap. find ( 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 ( ) ;
}
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) ;
}
}
}
}
2.7.1 将天气图标与天气类型产生联系
void Widget:: initWeatherIcon ( )
{
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 ( ) ;
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) ;
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 ( "-" ) ;
mDateList[ i] -> setText ( dayList[ 1 ] + "-" + dayList[ 2 ] ) ;
int index = days[ i] . mWeathType. indexOf ( "转" ) ;
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;
}
if ( watched == ui-> widget0405 && event-> type ( ) == QEvent:: Paint) {
drawTempLineLow ( ) ;
return true;
}
return QWidget:: eventFilter ( watched, event) ;
}
void Widget:: drawTempLineHight ( )
{
QPainter painter ( ui-> widget0404) ;
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 ;
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) ;
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 ;
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()
void Widget:: on_lineEditCity_returnPressed ( )
{
on_pushButton_clicked ( ) ;
}
3.最终效果
链接:https:
提取码:sw2n
-- 来自百度网盘超级会员V5的分享