Skip to content

Commit 23f148b

Browse files
committed
优化加载速度和预览数量
1 parent 5a80835 commit 23f148b

File tree

2 files changed

+188
-134
lines changed

2 files changed

+188
-134
lines changed

app/view/another_window/prize/import_prize_name.py

Lines changed: 94 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import os
55
import json
66
from typing import Dict, List, Any
7+
from concurrent.futures import ThreadPoolExecutor
78

89
from loguru import logger
910
from PySide6.QtWidgets import *
@@ -23,6 +24,10 @@
2324
class ImportPrizeNameWindow(QWidget):
2425
"""奖品名称导入窗口"""
2526

27+
# 定义信号,用于后台加载文件完成后通知UI线程
28+
fileLoaded = Signal(object, list) # 参数:数据,列名列表
29+
fileLoadError = Signal(str) # 参数:错误信息
30+
2631
def __init__(self, parent=None):
2732
"""初始化奖品名称导入窗口"""
2833
# 调用父类初始化方法
@@ -34,6 +39,8 @@ def __init__(self, parent=None):
3439
self.columns = []
3540
self.column_mapping = {}
3641
self.preview_data = []
42+
# 线程池用于后台加载文件
43+
self.executor = ThreadPoolExecutor(max_workers=2)
3744

3845
# 创建UI
3946
self.__init_ui()
@@ -46,7 +53,7 @@ def __init_ui(self):
4653
# 创建主布局
4754
self.main_layout = QVBoxLayout(self)
4855
self.main_layout.setContentsMargins(20, 20, 20, 20)
49-
self.main_layout.setSpacing(15)
56+
self.main_layout.setSpacing(5)
5057

5158
# 创建标题
5259
self.title_label = TitleLabel(
@@ -210,6 +217,10 @@ def __create_preview_area(self):
210217
self.preview_table = TableWidget()
211218
self.preview_table.setWordWrap(True)
212219
self.preview_table.verticalHeader().setVisible(False)
220+
# 限制预览表格高度
221+
self.preview_table.setMaximumHeight(150)
222+
# 设置固定行数显示
223+
self.preview_table.setRowCount(0)
213224
preview_layout.addWidget(self.preview_table)
214225

215226
# 添加到主布局
@@ -253,6 +264,10 @@ def __connect_signals(self):
253264
# 按钮事件
254265
self.import_btn.clicked.connect(self.__import_data)
255266

267+
# 后台文件加载完成信号
268+
self.fileLoaded.connect(self.__on_file_loaded)
269+
self.fileLoadError.connect(self.__on_file_load_error)
270+
256271
def __update_ui_state(self):
257272
"""更新UI状态"""
258273
has_file = self.file_path is not None
@@ -319,73 +334,18 @@ def __select_file(self):
319334
)
320335

321336
if file_path:
322-
try:
323-
# 加载文件
324-
self.__load_file(file_path)
325-
326-
# 更新文件路径标签
327-
self.file_path_label.setText(os.path.basename(file_path))
328-
329-
# 显示成功消息
330-
config = NotificationConfig(
331-
title=get_content_name_async(
332-
"import_prize_name", "file_loaded_notification_title"
333-
),
334-
content=get_content_name_async(
335-
"import_prize_name", "file_loaded_notification_content"
336-
),
337-
duration=3000,
338-
)
339-
show_notification(NotificationType.SUCCESS, config, parent=self)
340-
341-
except Exception as e:
342-
# 显示错误消息
343-
config = NotificationConfig(
344-
title=get_content_name_async(
345-
"import_prize_name", "load_failed_notification_title"
346-
),
347-
content=get_content_name_async(
348-
"import_prize_name", "load_failed_notification_content"
349-
),
350-
duration=3000,
351-
)
352-
show_notification(NotificationType.ERROR, config, parent=self)
353-
logger.error(f"加载文件失败: {e}")
354-
355-
def __load_file(self, file_path: str):
356-
"""加载文件"""
357-
self.file_path = file_path
358-
359-
# 根据文件扩展名选择加载方法
360-
file_ext = os.path.splitext(file_path)[1].lower()
361-
362-
if file_ext in [".xlsx", ".xls"]:
363-
# 延迟导入 pandas,避免在模块导入时加载大型 C 扩展
364-
try:
365-
import pandas as pd
366-
except Exception as e:
367-
logger.error(f"加载 Excel 需要 pandas 库,但导入失败: {e}")
368-
raise
369-
370-
# 加载Excel文件
371-
self.data = pd.read_excel(file_path)
372-
elif file_ext == ".csv":
373-
# 延迟导入 pandas,避免在模块导入时加载大型 C 扩展
374-
try:
375-
import pandas as pd
376-
except Exception as e:
377-
logger.error(f"加载 CSV 需要 pandas 库,但导入失败: {e}")
378-
raise
337+
# 更新文件路径标签
338+
self.file_path_label.setText(os.path.basename(file_path))
379339

380-
# 加载CSV文件
381-
self.data = pd.read_csv(file_path)
382-
else:
383-
raise ValueError(
384-
get_content_name_async("import_prize_name", "unsupported_format")
385-
)
340+
# 使用线程池在后台加载文件
341+
self.executor.submit(self.__load_file, file_path)
386342

387-
# 获取列名
388-
self.columns = list(self.data.columns)
343+
def __on_file_loaded(self, data, columns):
344+
"""文件加载完成后的处理"""
345+
# 更新UI数据
346+
self.data = data
347+
self.columns = columns
348+
self.file_path = self.file_path_label.text()
389349

390350
# 更新列映射下拉框
391351
self.__update_column_combos()
@@ -399,6 +359,73 @@ def __load_file(self, file_path: str):
399359
# 更新UI状态
400360
self.__update_ui_state()
401361

362+
# 显示成功消息
363+
config = NotificationConfig(
364+
title=get_content_name_async(
365+
"import_prize_name", "file_loaded_notification_title"
366+
),
367+
content=get_content_name_async(
368+
"import_prize_name", "file_loaded_notification_content"
369+
),
370+
duration=3000,
371+
)
372+
show_notification(NotificationType.SUCCESS, config, parent=self)
373+
374+
def __on_file_load_error(self, error_msg):
375+
"""文件加载失败后的处理"""
376+
# 隐藏加载动画
377+
self.__hide_loading_animation()
378+
379+
# 显示错误消息
380+
config = NotificationConfig(
381+
title=get_content_name_async(
382+
"import_prize_name", "load_failed_notification_title"
383+
),
384+
content=get_content_name_async(
385+
"import_prize_name", "load_failed_notification_content"
386+
)
387+
+ f": {error_msg}",
388+
duration=3000,
389+
)
390+
show_notification(NotificationType.ERROR, config, parent=self)
391+
392+
def __load_file(self, file_path: str):
393+
"""加载文件 - 在后台线程中执行"""
394+
try:
395+
# 根据文件扩展名选择加载方法
396+
file_ext = os.path.splitext(file_path)[1].lower()
397+
data = None
398+
399+
if file_ext in [".xlsx", ".xls"]:
400+
# 延迟导入 pandas,避免在模块导入时加载大型 C 扩展
401+
import pandas as pd
402+
403+
# 加载Excel文件,使用更高效的引擎
404+
data = pd.read_excel(
405+
file_path, engine="openpyxl" if file_ext == ".xlsx" else "xlrd"
406+
)
407+
elif file_ext == ".csv":
408+
# 延迟导入 pandas,避免在模块导入时加载大型 C 扩展
409+
import pandas as pd
410+
411+
# 加载CSV文件,使用更高效的参数
412+
data = pd.read_csv(file_path, engine="c", low_memory=False)
413+
else:
414+
raise ValueError(
415+
get_content_name_async("import_prize_name", "unsupported_format")
416+
)
417+
418+
# 获取列名
419+
columns = list(data.columns)
420+
421+
# 通过信号通知UI线程文件加载完成
422+
self.fileLoaded.emit(data, columns)
423+
424+
except Exception as e:
425+
logger.error(f"加载文件失败: {e}")
426+
# 通过信号通知UI线程文件加载失败
427+
self.fileLoadError.emit(str(e))
428+
402429
def __update_column_combos(self):
403430
"""更新列映射下拉框"""
404431
# 清空现有选项
@@ -527,7 +554,7 @@ def __update_preview(self):
527554
)
528555

529556
# 限制预览行数
530-
max_rows = min(10, len(self.data))
557+
max_rows = min(3, len(self.data))
531558
preview_df = self.data[preview_columns].head(max_rows).reset_index(drop=True)
532559

533560
# 更新表格

0 commit comments

Comments
 (0)