0.2.1 #44

Merged
p9o3yklam merged 6 commits from main into shixinglin 4 months ago

@ -1,115 +0,0 @@
# WeatherAPI 集成总结
## 集成状态
**成功完成** - WeatherAPI类已成功集成到word_main_window.py文件中
## 集成功能概览
### 1. 核心集成组件
- **WeatherAPI实例**: 在WordStyleMainWindow类中创建了WeatherAPI实例
- **WeatherFetchThread线程**: 使用WeatherAPI获取实时天气数据
- **状态栏显示**: 在状态栏中显示当前天气信息
### 2. 新增功能
#### 2.1 天气数据获取
- **自动获取**: WeatherFetchThread线程自动获取北京天气数据
- **数据格式化**: 将原始天气数据格式化为用户友好的格式
- **错误处理**: 包含完整的异常处理机制
#### 2.2 用户界面功能
- **状态栏显示**: 在状态栏右侧显示当前温度、天气描述、湿度和风力
- **菜单集成**: 在"视图"菜单中添加"天气信息"子菜单
- **快捷键支持**: F5快捷键刷新天气信息
#### 2.3 详细天气信息
- **对话框显示**: 点击"显示详细天气"打开详细天气信息对话框
- **实时刷新**: 对话框内可手动刷新天气数据
- **预报信息**: 显示未来3天的天气预报
### 3. 技术实现细节
#### 3.1 类结构修改
```python
class WordStyleMainWindow(QMainWindow):
def __init__(self):
# ... 其他初始化代码
self.weather_api = WeatherAPI() # 新增WeatherAPI实例
# ...
```
#### 3.2 线程实现
```python
class WeatherFetchThread(QThread):
def __init__(self):
super().__init__()
self.weather_api = WeatherAPI() # 使用WeatherAPI替代NetworkService
def run(self):
# 使用WeatherAPI获取天气数据
weather_data = self.weather_api.get_weather_data("北京")
# 格式化并发送信号
```
#### 3.3 菜单集成
```python
def create_menu_bar(self):
# 在视图菜单中添加天气信息子菜单
weather_submenu = view_menu.addMenu('天气信息')
# 刷新天气菜单项
refresh_weather_action = QAction('刷新天气', self)
refresh_weather_action.setShortcut('F5')
refresh_weather_action.triggered.connect(self.refresh_weather)
# 显示详细天气菜单项
show_weather_action = QAction('显示详细天气', self)
show_weather_action.triggered.connect(self.show_detailed_weather)
```
## 测试验证
### 测试结果
- ✅ 导入测试: WeatherAPI类导入成功
- ✅ 方法存在性测试: 所有相关类和方法存在
- ✅ 功能完整性测试: WeatherAPI功能完整可用
### 测试覆盖率
- WeatherAPI实例创建和初始化
- 天气数据获取和格式化
- 用户界面集成
- 错误处理机制
## 使用说明
### 基本使用
1. 启动应用程序
2. 天气信息自动显示在状态栏右侧
3. 使用F5快捷键或菜单刷新天气
4. 点击"显示详细天气"查看详细信息
### 功能特点
- **实时更新**: 天气数据自动更新
- **用户友好**: 简洁的界面和操作
- **错误处理**: 网络异常时显示友好提示
- **扩展性**: 支持未来添加更多城市
## 技术优势
1. **模块化设计**: WeatherAPI独立封装便于维护
2. **线程安全**: 使用QThread避免界面卡顿
3. **信号机制**: 使用pyqtSignal进行线程间通信
4. **错误恢复**: 完善的异常处理机制
## 未来扩展建议
1. **多城市支持**: 添加城市选择功能
2. **天气预警**: 集成天气预警信息
3. **主题适配**: 根据天气调整界面主题
4. **数据缓存**: 添加天气数据缓存机制
---
**集成完成时间**: 2024年
**测试状态**: 全部通过
**代码质量**: 优秀

@ -231,7 +231,7 @@ class MainWindow(QMainWindow):
view_menu.addAction(self.quote_action)
# 显示天气信息动作
self.weather_action = QAction('显示天气信息', self)
self.weather_action = QAction('显示天气', self)
self.weather_action.setCheckable(True)
self.weather_action.setChecked(True)
self.weather_action.triggered.connect(self.toggleWeatherDisplay)

@ -13,6 +13,9 @@ from datetime import datetime
class WordRibbonTab(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.weather_group = None # 天气组件组
self.weather_visible = False # 天气组件显示状态
self.ribbon_layout = None # 功能区布局
self.setup_ui()
def setup_ui(self):
@ -24,6 +27,11 @@ class WordRibbonTab(QWidget):
class WordRibbon(QFrame):
def __init__(self, parent=None):
super().__init__(parent)
self.weather_visible = False # 天气组件显示状态
self.weather_group = None # 天气组件组
self.quote_visible = False # 每日一言组件显示状态
self.quote_group = None # 每日一言组件组
self.ribbon_layout = None # 功能区布局
self.setup_ui()
def setup_ui(self):
@ -45,35 +53,16 @@ class WordRibbon(QFrame):
}
""")
ribbon_layout = QHBoxLayout()
ribbon_layout.setContentsMargins(10, 5, 10, 5)
ribbon_layout.setSpacing(15)
self.ribbon_layout = QHBoxLayout() # 保存为实例变量
self.ribbon_layout.setContentsMargins(10, 5, 10, 5)
self.ribbon_layout.setSpacing(15)
# 开始标签的内容(最常用的功能)
self.setup_home_tab(ribbon_layout)
self.setup_home_tab(self.ribbon_layout)
# 添加天气工具组
weather_group = self.create_ribbon_group("天气")
weather_layout = QVBoxLayout()
# 城市选择
self.city_combo = QComboBox()
self.city_combo.setFixedWidth(100)
self.city_combo.addItems(['自动定位', '北京', '上海', '广州', '深圳', '杭州', '南京', '武汉', '成都', '西安'])
self.city_combo.setCurrentText('自动定位')
self.city_combo.currentTextChanged.connect(self.on_city_changed)
# 刷新按钮
self.refresh_weather_btn = QPushButton("刷新天气")
self.refresh_weather_btn.clicked.connect(self.on_refresh_weather)
self.refresh_weather_btn.setFixedSize(80, 25)
# 天气工具组将在需要时动态添加
weather_layout.addWidget(self.city_combo)
weather_layout.addWidget(self.refresh_weather_btn)
weather_group.setLayout(weather_layout)
ribbon_layout.addWidget(weather_group)
self.ribbon_area.setLayout(ribbon_layout)
self.ribbon_area.setLayout(self.ribbon_layout)
main_layout.addWidget(self.ribbon_area)
self.setLayout(main_layout)
@ -179,6 +168,109 @@ class WordRibbon(QFrame):
"""下划线按钮点击处理"""
pass
def create_weather_group(self):
"""创建天气组件组"""
if self.weather_group is not None:
return self.weather_group
weather_group = self.create_ribbon_group("天气")
weather_layout = QVBoxLayout()
# 城市选择 - 添加所有省会城市
self.city_combo = QComboBox()
self.city_combo.setFixedWidth(120) # 增加宽度以显示完整城市名
self.city_combo.addItems([
'自动定位',
'北京', '上海', '广州', '深圳', '杭州', '南京', '武汉', '成都', '西安', # 一线城市
'天津', '重庆', '苏州', '青岛', '大连', '宁波', '厦门', '无锡', '佛山', # 新一线城市
'石家庄', '太原', '呼和浩特', '沈阳', '长春', '哈尔滨', # 东北华北
'合肥', '福州', '南昌', '济南', '郑州', '长沙', '南宁', '海口', # 华东华中华南
'贵阳', '昆明', '拉萨', '兰州', '西宁', '银川', '乌鲁木齐' # 西南西北
])
self.city_combo.setCurrentText('自动定位')
self.city_combo.currentTextChanged.connect(self.on_city_changed)
# 刷新按钮
self.refresh_weather_btn = QPushButton("刷新天气")
self.refresh_weather_btn.clicked.connect(self.on_refresh_weather)
self.refresh_weather_btn.setFixedSize(80, 25)
weather_layout.addWidget(self.city_combo)
weather_layout.addWidget(self.refresh_weather_btn)
weather_group.setLayout(weather_layout)
self.weather_group = weather_group
return weather_group
def show_weather_group(self):
"""显示天气组件"""
if not self.weather_visible and self.weather_group is None:
weather_group = self.create_weather_group()
# 在编辑组之后添加天气组
if self.ribbon_layout:
# 找到编辑组的位置,在其后插入天气组
insert_index = self.ribbon_layout.count() - 1 # 在stretch之前插入
self.ribbon_layout.insertWidget(insert_index, weather_group)
self.weather_visible = True
def hide_weather_group(self):
"""隐藏天气组件"""
if self.weather_visible and self.weather_group is not None:
self.weather_group.setParent(None)
self.weather_group = None
self.weather_visible = False
def create_quote_group(self):
"""创建每日一言组件组"""
if self.quote_group is not None:
return self.quote_group
quote_group = self.create_ribbon_group("每日一言")
quote_layout = QVBoxLayout()
# 每日一言显示标签
self.quote_label = QLabel("暂无")
self.quote_label.setStyleSheet("QLabel { color: #666666; font-style: italic; font-size: 10px; }")
self.quote_label.setWordWrap(True)
self.quote_label.setFixedWidth(150)
# 刷新按钮
self.refresh_quote_btn = QPushButton("刷新箴言")
self.refresh_quote_btn.clicked.connect(self.on_refresh_quote)
self.refresh_quote_btn.setFixedSize(80, 25)
quote_layout.addWidget(self.quote_label)
quote_layout.addWidget(self.refresh_quote_btn)
quote_group.setLayout(quote_layout)
self.quote_group = quote_group
# 组件创建完成后自动获取每日一言
self.load_daily_quote()
return quote_group
def show_quote_group(self):
"""显示每日一言组件"""
if not self.quote_visible and self.quote_group is None:
quote_group = self.create_quote_group()
# 在天气组之后添加每日一言组
if self.ribbon_layout:
# 找到合适的位置插入每日言组
insert_index = self.ribbon_layout.count() - 1 # 在stretch之前插入
# 如果天气组件存在,在其后插入;否则在编辑组后插入
if self.weather_group is not None and self.weather_visible:
insert_index = self.ribbon_layout.indexOf(self.weather_group) + 1
self.ribbon_layout.insertWidget(insert_index, quote_group)
self.quote_visible = True
def hide_quote_group(self):
"""隐藏每日一言组件"""
if self.quote_visible and self.quote_group is not None:
self.quote_group.setParent(None)
self.quote_group = None
self.quote_visible = False
def create_ribbon_group(self, title):
"""创建功能区组"""
group = QGroupBox(title)
@ -208,6 +300,53 @@ class WordRibbon(QFrame):
"""城市选择变化处理"""
pass
def load_daily_quote(self):
"""加载每日一言"""
try:
# 创建每日一言API实例
quote_api = daily_sentence_API("https://api.nxvav.cn/api/yiyan")
# 获取每日一言数据
quote_data = quote_api.get_sentence('json')
if quote_data and isinstance(quote_data, dict):
# 从返回的数据中提取每日一言文本
quote_text = quote_data.get('yiyan', '暂无每日一言')
self.update_quote_display(quote_text)
else:
# 如果API返回空或格式不正确显示默认文本
self.update_quote_display("暂无每日一言")
except Exception as e:
print(f"加载每日一言失败: {e}")
self.update_quote_display("暂无每日一言")
def on_refresh_quote(self):
"""刷新每日一言按钮点击处理"""
try:
# 创建每日一言API实例
quote_api = daily_sentence_API("https://api.nxvav.cn/api/yiyan")
# 获取每日一言数据
quote_data = quote_api.get_sentence('json')
if quote_data and isinstance(quote_data, dict):
# 从返回的数据中提取每日一言文本
quote_text = quote_data.get('yiyan', '暂无每日一言')
self.update_quote_display(quote_text)
else:
# 如果API返回空或格式不正确显示默认文本
self.update_quote_display("获取每日一言失败")
except Exception as e:
print(f"获取每日一言失败: {e}")
self.update_quote_display("获取每日一言失败")
def update_quote_display(self, quote_text):
"""更新每日一言显示"""
if hasattr(self, 'quote_label') and self.quote_label:
self.quote_label.setText(f"{quote_text}")
def create_ribbon_button(self, text, shortcut, icon_name):
"""创建功能区按钮"""
btn = QToolButton()
@ -575,6 +714,24 @@ class WeatherAPI:
results[city] = weather_data
return results
def get_isp_info(self):
"""获取ISP信息"""
try:
url = "http://ip-api.com/json/"
response = requests.get(url, timeout=5)
response.raise_for_status()
data = response.json()
if data.get('status') == 'success':
isp = data.get('isp', '')
org = data.get('org', '')
as_info = data.get('as', '')
return f"{isp} {org} {as_info}".strip()
return None
except Exception as e:
print(f"获取ISP信息失败: {e}")
return None
def get_location_by_ip(self):
"""通过IP地址获取用户位置"""
try:
@ -675,12 +832,159 @@ class WeatherAPI:
city = self.get_location_by_ip()
if city:
print(f"通过IP定位成功: {city}")
# 检查是否是教育网或特殊网络环境
isp_info = self.get_isp_info()
if isp_info and ('教育网' in isp_info or 'CERNET' in isp_info or 'University' in isp_info):
print(f"检测到教育网环境: {isp_info}")
print("教育网IP定位可能不准确建议手动选择城市")
# 教育网环境下如果定位到北京可能是IP分配问题
if city.lower() in ['beijing', '北京', 'haidian', '海淀']:
print("提示:教育网环境下北京定位可能是网络出口导致的")
return {'city': city, 'note': '教育网环境,定位可能不准确', 'isp': isp_info}
# 智能处理 - 如果是区级单位,映射到市级城市
district_to_city_map = {
# 北京各区
'海淀': '北京',
'haidian': '北京',
'朝阳': '北京',
'chaoyang': '北京',
'东城': '北京',
'dongcheng': '北京',
'西城': '北京',
'xicheng': '北京',
'丰台': '北京',
'fengtai': '北京',
'石景山': '北京',
'shijingshan': '北京',
'通州': '北京',
'tongzhou': '北京',
'昌平': '北京',
'changping': '北京',
'大兴': '北京',
'daxing': '北京',
'怀柔': '北京',
'huairou': '北京',
'平谷': '北京',
'pinggu': '北京',
'门头沟': '北京',
'mentougou': '北京',
'密云': '北京',
'miyun': '北京',
'延庆': '北京',
'yanqing': '北京',
'房山': '北京',
'fangshan': '北京',
'顺义': '北京',
'shunyi': '北京',
# 天津各区
'和平': '天津',
'heping': '天津',
'河东': '天津',
'hedong': '天津',
'河西': '天津',
'hexi': '天津',
'南开': '天津',
'nankai': '天津',
'河北': '天津',
'hebei': '天津',
'红桥': '天津',
'hongqiao': '天津',
'滨海新区': '天津',
'binhaixinqu': '天津',
'东丽': '天津',
'dongli': '天津',
'西青': '天津',
'xiqing': '天津',
'津南': '天津',
'jinnan': '天津',
'北辰': '天津',
'beichen': '天津',
'武清': '天津',
'wuqing': '天津',
'宝坻': '天津',
'baodi': '天津',
'宁河': '天津',
'ninghe': '天津',
'静海': '天津',
'jinghai': '天津',
'蓟州': '天津',
'jizhou': '天津',
# 上海各区
'黄浦': '上海',
'huangpu': '上海',
'徐汇': '上海',
'xuhui': '上海',
'长宁': '上海',
'changning': '上海',
'静安': '上海',
'jingan': '上海',
'普陀': '上海',
'putuo': '上海',
'虹口': '上海',
'hongkou': '上海',
'杨浦': '上海',
'yangpu': '上海',
'闵行': '上海',
'minhang': '上海',
'宝山': '上海',
'baoshan': '上海',
'嘉定': '上海',
'jiading': '上海',
'浦东': '上海',
'pudong': '上海',
'金山': '上海',
'jinshan': '上海',
'松江': '上海',
'songjiang': '上海',
'青浦': '上海',
'qingpu': '上海',
'奉贤': '上海',
'fengxian': '上海',
'崇明': '上海',
'chongming': '上海',
# 广州各区
'天河': '广州',
'tianhe': '广州',
'越秀': '广州',
'yuexiu': '广州',
'海珠': '广州',
'haizhu': '广州',
'荔湾': '广州',
'liwan': '广州',
'白云': '广州',
'baiyun': '广州',
'黄埔': '广州',
'huangpu': '广州',
'番禺': '广州',
'panyu': '广州',
'花都': '广州',
'huadu': '广州',
'南沙': '广州',
'nansha': '广州',
'从化': '广州',
'conghua': '广州',
'增城': '广州',
'zengcheng': '广州'
}
# 检查是否是区级单位,如果是则映射到市级城市
city_lower = city.lower()
if city_lower in district_to_city_map:
mapped_city = district_to_city_map[city_lower]
print(f"智能映射: {city} -> {mapped_city}")
city = mapped_city
return {'city': city}
# 如果IP定位失败尝试其他方法
# 可以尝试使用浏览器的地理位置API但这需要前端支持
print("自动定位失败,使用默认城市")
print("自动定位失败,建议手动选择城市")
return None
except Exception as e:
@ -692,6 +996,138 @@ class WeatherAPI:
try:
# 处理英文城市名映射
original_city_name = city_name
# 智能城市映射 - 将区级单位映射到市级城市
district_to_city_map = {
# 北京各区
'海淀': '北京',
'朝阳': '北京',
'东城': '北京',
'西城': '北京',
'丰台': '北京',
'石景山': '北京',
'通州': '北京',
'昌平': '北京',
'大兴': '北京',
'怀柔': '北京',
'平谷': '北京',
'门头沟': '北京',
'密云': '北京',
'延庆': '北京',
'房山': '北京',
'顺义': '北京',
'haidian': '北京',
'chaoyang': '北京',
'dongcheng': '北京',
'xicheng': '北京',
'fengtai': '北京',
'shijingshan': '北京',
'tongzhou': '北京',
'changping': '北京',
'daxing': '北京',
'huairou': '北京',
'pinggu': '北京',
'mentougou': '北京',
'miyun': '北京',
'yanqing': '北京',
'fangshan': '北京',
'shunyi': '北京',
# 天津各区(统一映射到天津)
'和平': '天津',
'heping': '天津',
'河东': '天津',
'hedong': '天津',
'河西': '天津',
'hexi': '天津',
'南开': '天津',
'nankai': '天津',
'河北': '天津',
'红桥': '天津',
'hongqiao': '天津',
'滨海新区': '天津',
'binhaixinqu': '天津',
'东丽': '天津',
'dongli': '天津',
'西青': '天津',
'xiqing': '天津',
'津南': '天津',
'jinnan': '天津',
'北辰': '天津',
'beichen': '天津',
'武清': '天津',
'wuqing': '天津',
'宝坻': '天津',
'baodi': '天津',
'宁河': '天津',
'ninghe': '天津',
'静海': '天津',
'jinghai': '天津',
'蓟州': '天津',
'jizhou': '天津',
'黄浦': '上海',
'徐汇': '上海',
'长宁': '上海',
'静安': '上海',
'普陀': '上海',
'虹口': '上海',
'杨浦': '上海',
'闵行': '上海',
'宝山': '上海',
'嘉定': '上海',
'浦东': '上海',
'金山': '上海',
'松江': '上海',
'青浦': '上海',
'奉贤': '上海',
'崇明': '上海',
'huangpu': '上海',
'xuhui': '上海',
'changning': '上海',
'jingan': '上海',
'putuo': '上海',
'hongkou': '上海',
'yangpu': '上海',
'minhang': '上海',
'baoshan': '上海',
'jiading': '上海',
'pudong': '上海',
'jinshan': '上海',
'songjiang': '上海',
'qingpu': '上海',
'fengxian': '上海',
'chongming': '上海',
'天河': '广州',
'越秀': '广州',
'海珠': '广州',
'荔湾': '广州',
'白云': '广州',
'黄埔': '广州',
'番禺': '广州',
'花都': '广州',
'南沙': '广州',
'从化': '广州',
'增城': '广州',
'tianhe': '广州',
'yuexiu': '广州',
'haizhu': '广州',
'liwan': '广州',
'baiyun': '广州',
'huangpu': '广州',
'panyu': '广州',
'huadu': '广州',
'nansha': '广州',
'conghua': '广州',
'zengcheng': '广州'
}
# 检查是否是区级单位,如果是则映射到市级城市
city_lower = city_name.lower()
if city_lower in district_to_city_map:
mapped_city = district_to_city_map[city_lower]
print(f"智能映射: {city_name} -> {mapped_city}")
city_name = mapped_city
if city_name in self.city_id_map:
# 如果是英文城市名,先映射到中文
mapped_name = self.city_id_map.get(city_name)
@ -758,4 +1194,46 @@ class WeatherAPI:
if weather_data:
results[city] = weather_data
return results
class daily_sentence_API:
def __init__(self, api_url):
self.api_url = api_url or "https://api.nxvav.cn/api/yiyan"
def get_sentence(self, format_type='json'):
"""
获取每日一言数据
参数:
format_type (str): 指定返回格式可选值: 'json', 'js', 'js1', 'text'默认为 'json'
返回:
如果 format_type 'json'返回解析后的字典包含 id, yiyan, createTime, nick
如果 format_type 'js', 'js1', 'text'返回字符串形式的响应内容
如果请求失败或格式不支持返回 None
"""
# 定义查询参数字典,根据 format_type 添加对应参数
params = {}
if format_type == 'json':
params['json'] = 'true'
elif format_type == 'js':
params['js'] = 'true'
elif format_type == 'js1':
params['js1'] = 'true'
elif format_type == 'text':
params['text'] = 'true'
else:
print(f"错误:不支持的格式类型 '{format_type}',使用默认 'json'")
params['json'] = 'true' # 默认为 JSON
try:
# 发送 GET 请求
response = requests.get(self.api_url, params=params)
response.raise_for_status() # 如果请求失败(如 4xx 或 5xx抛出异常
# 根据格式类型处理响应
if format_type == 'json':
return response.json() # 解析为字典
else:
return response.text # 返回文本内容
except requests.exceptions.RequestException as e:
print(f"请求失败: {e}")
return None

@ -143,7 +143,20 @@ class WordStyleMainWindow(QMainWindow):
if current_city == '自动定位':
# 使用自动定位
print("使用自动定位")
weather_data = self.weather_api.get_weather_data()
location_info = self.weather_api.get_current_location()
if location_info:
if 'note' in location_info:
# 检测到特殊网络环境
print(f"网络环境提示: {location_info['note']}")
if '教育网' in location_info['note'] and location_info['city'].lower() in ['beijing', '北京', 'haidian', '海淀']:
print("建议:教育网环境下北京定位可能不准确,可手动选择天津")
# 可以选择提示用户手动选择,或者使用上次的定位
# 使用定位到的城市获取天气
actual_city = location_info.get('city', '北京')
weather_data = self.weather_api.get_weather_data(actual_city)
else:
# 定位失败,使用默认城市
weather_data = self.weather_api.get_weather_data()
else:
# 使用选中的城市
print(f"使用选中的城市: {current_city}")
@ -324,8 +337,24 @@ class WordStyleMainWindow(QMainWindow):
view_menu.addSeparator()
# 天气功能
weather_menu = view_menu.addMenu('天气信息')
# 附加工具功能
weather_menu = view_menu.addMenu('附加工具')
# 显示天气工具组
self.show_weather_tools_action = QAction('显示天气工具', self)
self.show_weather_tools_action.setCheckable(True)
self.show_weather_tools_action.setChecked(False) # 默认不显示
self.show_weather_tools_action.triggered.connect(self.toggle_weather_tools)
weather_menu.addAction(self.show_weather_tools_action)
# 显示每日一言工具组
self.show_quote_tools_action = QAction('显示每日一言工具', self)
self.show_quote_tools_action.setCheckable(True)
self.show_quote_tools_action.setChecked(False) # 默认不显示
self.show_quote_tools_action.triggered.connect(self.toggle_quote_tools)
weather_menu.addAction(self.show_quote_tools_action)
weather_menu.addSeparator()
# 刷新天气
refresh_weather_action = QAction('刷新天气', self)
@ -583,7 +612,7 @@ class WordStyleMainWindow(QMainWindow):
print(f"接收到天气数据: {weather_data}")
if 'error' in weather_data:
print(f"天气显示错误: {weather_data['error']}")
self.status_bar.showMessage(f"天气信息获取失败: {weather_data['error']}", 3000)
self.status_bar.showMessage(f"天气数据获取失败: {weather_data['error']}", 3000)
else:
city = weather_data.get('city', '未知城市')
temp = weather_data.get('temperature', 'N/A')
@ -625,9 +654,9 @@ class WordStyleMainWindow(QMainWindow):
'forecast': weather_data['forecast']
}
self.update_weather_display(formatted_data)
self.status_bar.showMessage("天气信息已刷新", 2000)
self.status_bar.showMessage("天气数据已刷新", 2000)
else:
self.status_bar.showMessage("天气信息刷新失败请检查API密钥", 3000)
self.status_bar.showMessage("天气数据刷新失败请检查API密钥", 3000)
except Exception as e:
self.status_bar.showMessage(f"天气刷新失败: {str(e)}", 3000)
@ -637,14 +666,14 @@ class WordStyleMainWindow(QMainWindow):
# 检查是否有天气数据
if not hasattr(self, 'current_weather_data') or not self.current_weather_data:
QMessageBox.information(self, "天气信息", "暂无天气数据,请先刷新天气信息")
QMessageBox.information(self, "附加工具", "暂无天气数据,请先刷新天气信息")
return
weather_data = self.current_weather_data
# 创建对话框
dialog = QDialog(self)
dialog.setWindowTitle("详细天气信息")
dialog.setWindowTitle("详细天气")
dialog.setMinimumWidth(400)
layout = QVBoxLayout()
@ -706,6 +735,68 @@ class WordStyleMainWindow(QMainWindow):
self.refresh_weather()
dialog.close()
def toggle_weather_tools(self, checked):
"""切换天气工具组显示"""
if checked:
# 显示天气工具组
if hasattr(self, 'ribbon'):
self.ribbon.show_weather_group()
self.status_bar.showMessage("天气工具已显示", 2000)
else:
# 隐藏天气工具组
if hasattr(self, 'ribbon'):
self.ribbon.hide_weather_group()
self.status_bar.showMessage("天气工具已隐藏", 2000)
def toggle_quote_tools(self, checked):
"""切换每日一言工具组显示"""
if checked:
# 显示每日一言工具组
if hasattr(self, 'ribbon'):
self.ribbon.show_quote_group()
self.status_bar.showMessage("每日一言工具已显示", 2000)
# 如果当前没有显示内容,刷新一次
if hasattr(self.ribbon, 'quote_label') and self.ribbon.quote_label.text() == "每日一言: 暂无":
self.refresh_daily_quote()
else:
# 隐藏每日一言工具组
if hasattr(self, 'ribbon'):
self.ribbon.hide_quote_group()
self.status_bar.showMessage("每日一言工具已隐藏", 2000)
def refresh_daily_quote(self):
"""刷新每日一言 - 使用WordRibbon中的API"""
if hasattr(self, 'ribbon'):
# 直接调用WordRibbon中的刷新方法
self.ribbon.on_refresh_quote()
def on_quote_fetched(self, quote_data):
"""处理名言获取成功"""
if 'error' not in quote_data:
content = quote_data.get('content', '获取名言失败')
author = quote_data.get('author', '未知')
quote_text = f"{content}{author}"
# 更新Ribbon中的每日一言显示
if hasattr(self, 'ribbon') and hasattr(self.ribbon, 'quote_label'):
self.ribbon.quote_label.setText(f"{quote_text}")
# 更新状态栏
self.status_bar.showMessage(f"每日名言: {quote_text}", 10000)
else:
# 处理错误情况
error_msg = quote_data.get('error', '获取名言失败')
if hasattr(self, 'ribbon') and hasattr(self.ribbon, 'quote_label'):
self.ribbon.quote_label.setText(f"获取失败")
self.status_bar.showMessage(f"每日名言获取失败: {error_msg}", 5000)
def on_quote_error(self, error_data):
"""处理名言获取错误"""
error_msg = error_data.get('error', '获取名言失败') if isinstance(error_data, dict) else str(error_data)
if hasattr(self, 'ribbon') and hasattr(self.ribbon, 'quote_label'):
self.ribbon.quote_label.setText(f"获取失败")
self.status_bar.showMessage(f"每日名言获取失败: {error_msg}", 5000)
def update_quote_display(self, quote_data):
"""更新名言显示"""
if 'error' not in quote_data:

Loading…
Cancel
Save