gui
第一版完整版
This commit is contained in:
344
gui_app.py
344
gui_app.py
@@ -12,7 +12,7 @@ from PyQt5.QtWidgets import (
|
||||
QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
|
||||
QLabel, QFileDialog, QTableWidgetItem, QMessageBox,
|
||||
QDateTimeEdit, QGridLayout, QStackedWidget, QButtonGroup,
|
||||
QStyle, QComboBox, QFrame, QShortcut, QMenu,
|
||||
QStyle, QComboBox, QFrame, QShortcut, QMenu, QAbstractButton,
|
||||
QAbstractItemView, QTableView, QStyledItemDelegate,
|
||||
QStyleOptionProgressBar, QStyleOptionButton, QHeaderView,
|
||||
QTabWidget, QSplitter, QSizePolicy
|
||||
@@ -638,6 +638,9 @@ class ConfigTableModel(QAbstractTableModel):
|
||||
key = mapping.get(col, "")
|
||||
if role == Qt.DisplayRole:
|
||||
return str(config.get(key, "")) if key else ""
|
||||
elif role == Qt.TextAlignmentRole:
|
||||
# 所有单元格居中对齐
|
||||
return Qt.AlignCenter
|
||||
elif role == Qt.ToolTipRole:
|
||||
# 为达人链接和文件路径列提供 tooltip 显示完整内容
|
||||
if col in (5, 8) and key:
|
||||
@@ -691,9 +694,8 @@ class ConfigTableModel(QAbstractTableModel):
|
||||
class TableActionDelegate(QStyledItemDelegate):
|
||||
"""Model/View 操作列 + 进度列 delegate"""
|
||||
|
||||
def __init__(self, parent, on_edit, on_delete):
|
||||
def __init__(self, parent, on_delete):
|
||||
super().__init__(parent)
|
||||
self.on_edit = on_edit
|
||||
self.on_delete = on_delete
|
||||
|
||||
def paint(self, painter, option, index):
|
||||
@@ -716,16 +718,10 @@ class TableActionDelegate(QStyledItemDelegate):
|
||||
return
|
||||
if index.column() == 10:
|
||||
rect = option.rect
|
||||
btn_w = (rect.width() - 12) // 2
|
||||
edit_rect = rect.adjusted(6, 4, -rect.width() + btn_w + 6, -4)
|
||||
delete_rect = rect.adjusted(6 + btn_w + 6, 4, -6, -4)
|
||||
edit_btn = QStyleOptionButton()
|
||||
edit_btn.rect = edit_rect
|
||||
edit_btn.text = "编辑"
|
||||
delete_rect = rect.adjusted(6, 4, -6, -4)
|
||||
delete_btn = QStyleOptionButton()
|
||||
delete_btn.rect = delete_rect
|
||||
delete_btn.text = "删除"
|
||||
QApplication.style().drawControl(QStyle.CE_PushButton, edit_btn, painter)
|
||||
QApplication.style().drawControl(QStyle.CE_PushButton, delete_btn, painter)
|
||||
return
|
||||
super().paint(painter, option, index)
|
||||
@@ -735,12 +731,7 @@ class TableActionDelegate(QStyledItemDelegate):
|
||||
return super().editorEvent(event, model, option, index)
|
||||
if event.type() == event.MouseButtonRelease:
|
||||
rect = option.rect
|
||||
btn_w = (rect.width() - 12) // 2
|
||||
edit_rect = rect.adjusted(6, 4, -rect.width() + btn_w + 6, -4)
|
||||
delete_rect = rect.adjusted(6 + btn_w + 6, 4, -6, -4)
|
||||
if edit_rect.contains(event.pos()):
|
||||
self.on_edit(index)
|
||||
return True
|
||||
delete_rect = rect.adjusted(6, 4, -6, -4)
|
||||
if delete_rect.contains(event.pos()):
|
||||
self.on_delete(index)
|
||||
return True
|
||||
@@ -964,11 +955,11 @@ class MainWindow(QMainWindow):
|
||||
import_row = QHBoxLayout()
|
||||
import_row.addWidget(QLabel("Excel文件:"))
|
||||
self.excel_path_input = LineEdit()
|
||||
self.excel_path_input.setReadOnly(True)
|
||||
self.excel_path_input.setPlaceholderText("点击导入按钮选择Excel配置文件")
|
||||
import_row.addWidget(self.excel_path_input)
|
||||
self.excel_browse_btn = PushButton("浏览")
|
||||
self.excel_browse_btn.clicked.connect(self.browse_excel)
|
||||
import_row.addWidget(self.excel_browse_btn)
|
||||
self.import_btn = PrimaryPushButton("导入")
|
||||
self.import_btn = PrimaryPushButton("导入配置")
|
||||
self.import_btn.setToolTip("选择Excel文件并导入配置")
|
||||
self.import_btn.clicked.connect(self.import_excel)
|
||||
import_row.addWidget(self.import_btn)
|
||||
self.download_template_btn = PushButton("下载模板")
|
||||
@@ -1047,6 +1038,13 @@ class MainWindow(QMainWindow):
|
||||
table_title = QLabel("配置列表(从Excel导入后显示,可直接在表格中编辑)")
|
||||
table_title.setFont(QFont("Microsoft YaHei", 11, QFont.Bold))
|
||||
table_layout.addWidget(table_title)
|
||||
self.table_edit_hint = QLabel("编辑模式:当前行已高亮,其它行已锁定。修改后点击“确认”保存,点击“退出”还原。")
|
||||
self.table_edit_hint.setVisible(False)
|
||||
self.table_edit_hint.setStyleSheet(
|
||||
"background-color: #fff7ed; color: #9a3412; "
|
||||
"border: 1px solid #fed7aa; border-radius: 6px; padding: 6px 8px;"
|
||||
)
|
||||
table_layout.addWidget(self.table_edit_hint)
|
||||
|
||||
search_row = QHBoxLayout()
|
||||
self.table_search_input = LineEdit()
|
||||
@@ -1143,8 +1141,8 @@ class MainWindow(QMainWindow):
|
||||
self.config_table.horizontalHeader().setSortIndicatorShown(True)
|
||||
self.config_table.verticalHeader().setVisible(False)
|
||||
self.config_table.verticalHeader().setDefaultSectionSize(42)
|
||||
# 设置表格编辑触发方式:双击进入编辑(单击只选择行)
|
||||
self.config_table.setEditTriggers(TableWidget.DoubleClicked)
|
||||
# 禁用直接编辑,只能通过编辑按钮进入编辑模式
|
||||
self.config_table.setEditTriggers(TableWidget.NoEditTriggers)
|
||||
self.config_table.setSelectionBehavior(QAbstractItemView.SelectRows)
|
||||
self.config_table.setSelectionMode(QAbstractItemView.ExtendedSelection)
|
||||
self.config_table.setContextMenuPolicy(Qt.CustomContextMenu)
|
||||
@@ -1385,6 +1383,54 @@ class MainWindow(QMainWindow):
|
||||
if current_item:
|
||||
self.config_table.closePersistentEditor(current_item)
|
||||
self.config_table.setCurrentItem(None)
|
||||
# 恢复为只读模式
|
||||
self.config_table.setEditTriggers(TableWidget.NoEditTriggers)
|
||||
self._cleanup_edit_mode_state()
|
||||
|
||||
def _set_row_highlight(self, row, enabled):
|
||||
"""高亮/取消高亮某一行"""
|
||||
highlight_color = QColor(255, 247, 216)
|
||||
for col in range(9):
|
||||
item = self.config_table.item(row, col)
|
||||
if not item:
|
||||
continue
|
||||
if enabled:
|
||||
item.setBackground(highlight_color)
|
||||
else:
|
||||
item.setData(Qt.BackgroundRole, None)
|
||||
|
||||
def _set_other_rows_locked(self, edit_row, locked):
|
||||
"""锁定/解锁编辑行以外的行"""
|
||||
for r in range(self.config_table.rowCount()):
|
||||
if r == edit_row:
|
||||
# 编辑行保持可用
|
||||
continue
|
||||
# 操作列按钮禁用/启用
|
||||
action_widget = self.config_table.cellWidget(r, 10)
|
||||
if action_widget:
|
||||
action_widget.setEnabled(not locked)
|
||||
# 数据列禁用/启用
|
||||
for col in range(9):
|
||||
item = self.config_table.item(r, col)
|
||||
if not item:
|
||||
continue
|
||||
if locked:
|
||||
item.setFlags(item.flags() & ~Qt.ItemIsEnabled)
|
||||
else:
|
||||
item.setFlags((item.flags() | Qt.ItemIsEnabled) & ~Qt.ItemIsEditable)
|
||||
|
||||
def _cleanup_edit_mode_state(self):
|
||||
"""清理编辑态UI状态"""
|
||||
edit_row = getattr(self, '_editing_row', None)
|
||||
if edit_row is None:
|
||||
return
|
||||
self._set_row_highlight(edit_row, False)
|
||||
self._set_other_rows_locked(edit_row, False)
|
||||
self._editing_row = None
|
||||
if getattr(self, "table_edit_hint", None):
|
||||
self.table_edit_hint.setVisible(False)
|
||||
if hasattr(self, '_edit_selection_mode_backup'):
|
||||
self.config_table.setSelectionMode(self._edit_selection_mode_backup)
|
||||
|
||||
def on_table_item_changed(self, item):
|
||||
"""表格内容变更回调"""
|
||||
@@ -1420,6 +1466,14 @@ class MainWindow(QMainWindow):
|
||||
# 确保标志被重置
|
||||
self.is_updating_table = False
|
||||
|
||||
def _create_centered_item(self, text):
|
||||
"""创建居中对齐的表格单元格"""
|
||||
item = QTableWidgetItem(str(text))
|
||||
item.setTextAlignment(Qt.AlignCenter)
|
||||
# 默认不可编辑,必须通过编辑按钮进入编辑模式
|
||||
item.setFlags(item.flags() & ~Qt.ItemIsEditable)
|
||||
return item
|
||||
|
||||
def _set_status_item(self, row, text):
|
||||
"""设置状态列图标与文本"""
|
||||
try:
|
||||
@@ -1427,6 +1481,8 @@ class MainWindow(QMainWindow):
|
||||
self.config_table.itemChanged.disconnect(self.on_table_item_changed)
|
||||
try:
|
||||
item = QTableWidgetItem(text)
|
||||
item.setTextAlignment(Qt.AlignCenter) # 居中对齐
|
||||
item.setFlags(item.flags() & ~Qt.ItemIsEditable)
|
||||
if "完成" in text or "成功" in text:
|
||||
item.setIcon(self.style().standardIcon(QStyle.SP_DialogApplyButton))
|
||||
elif "失败" in text or "错误" in text:
|
||||
@@ -1466,28 +1522,142 @@ class MainWindow(QMainWindow):
|
||||
self.config_table.setCellWidget(row, 9, progress)
|
||||
|
||||
def _set_action_buttons(self, row, config_index):
|
||||
"""设置操作列按钮"""
|
||||
"""设置操作列按钮(编辑和删除)"""
|
||||
wrapper = QWidget()
|
||||
layout = QHBoxLayout(wrapper)
|
||||
layout.setContentsMargins(4, 0, 4, 0)
|
||||
layout.setSpacing(4)
|
||||
edit_btn = PushButton("编辑")
|
||||
edit_btn.setFixedWidth(50)
|
||||
delete_btn = PushButton("删除")
|
||||
delete_btn.setFixedWidth(50)
|
||||
# 使用默认参数捕获当前值,避免闭包问题
|
||||
edit_btn.clicked.connect(lambda checked, r=row: self._enter_edit_mode(r))
|
||||
edit_btn.clicked.connect(lambda checked, r=row, idx=config_index: self._enter_edit_mode(r, idx))
|
||||
delete_btn.clicked.connect(lambda checked, idx=config_index: self.delete_row_by_index(idx))
|
||||
layout.addWidget(edit_btn)
|
||||
layout.addWidget(delete_btn)
|
||||
self.config_table.setCellWidget(row, 10, wrapper)
|
||||
|
||||
def _enter_edit_mode(self, row):
|
||||
"""进入指定行的编辑模式"""
|
||||
def _set_edit_mode_buttons(self, row, config_index):
|
||||
"""设置编辑模式按钮(确认和退出)"""
|
||||
wrapper = QWidget()
|
||||
layout = QHBoxLayout(wrapper)
|
||||
layout.setContentsMargins(4, 0, 4, 0)
|
||||
layout.setSpacing(4)
|
||||
confirm_btn = PushButton("确认")
|
||||
confirm_btn.setFixedWidth(50)
|
||||
cancel_btn = PushButton("退出")
|
||||
cancel_btn.setFixedWidth(50)
|
||||
# 使用默认参数捕获当前值
|
||||
confirm_btn.clicked.connect(lambda checked, r=row, idx=config_index: self._confirm_edit(r, idx))
|
||||
cancel_btn.clicked.connect(lambda checked, r=row, idx=config_index: self._cancel_edit(r, idx))
|
||||
layout.addWidget(confirm_btn)
|
||||
layout.addWidget(cancel_btn)
|
||||
self.config_table.setCellWidget(row, 10, wrapper)
|
||||
|
||||
def _enter_edit_mode(self, row, config_index):
|
||||
"""进入编辑模式"""
|
||||
if row < 0 or row >= self.config_table.rowCount():
|
||||
return
|
||||
# 选中第一个可编辑的单元格(多多ID列)
|
||||
item = self.config_table.item(row, 0)
|
||||
if item:
|
||||
self.config_table.setCurrentItem(item)
|
||||
self.config_table.editItem(item)
|
||||
# 允许当前行进入编辑时的交互触发
|
||||
if not hasattr(self, '_edit_triggers_backup'):
|
||||
self._edit_triggers_backup = self.config_table.editTriggers()
|
||||
self.config_table.setEditTriggers(QAbstractItemView.DoubleClicked | QAbstractItemView.SelectedClicked)
|
||||
if not hasattr(self, '_edit_selection_mode_backup'):
|
||||
self._edit_selection_mode_backup = self.config_table.selectionMode()
|
||||
self.config_table.setSelectionMode(QAbstractItemView.SingleSelection)
|
||||
self._editing_row = row
|
||||
# 保存原始数据用于还原
|
||||
if not hasattr(self, '_edit_backup'):
|
||||
self._edit_backup = {}
|
||||
original_data = {}
|
||||
for col in range(9): # 前9列是数据列
|
||||
item = self.config_table.item(row, col)
|
||||
original_data[col] = item.text() if item else ""
|
||||
self._edit_backup[row] = original_data
|
||||
|
||||
# 启用该行的编辑
|
||||
for col in range(9):
|
||||
item = self.config_table.item(row, col)
|
||||
if item:
|
||||
item.setFlags(item.flags() | Qt.ItemIsEditable)
|
||||
# 高亮编辑行并锁定其他行
|
||||
self._set_row_highlight(row, True)
|
||||
self._set_other_rows_locked(row, True)
|
||||
|
||||
# 切换到编辑模式按钮
|
||||
self._set_edit_mode_buttons(row, config_index)
|
||||
|
||||
# 自动聚焦第一个可编辑单元格
|
||||
first_item = None
|
||||
for col in range(9):
|
||||
item = self.config_table.item(row, col)
|
||||
if item and (item.flags() & Qt.ItemIsEditable):
|
||||
first_item = item
|
||||
self.config_table.setCurrentCell(row, col)
|
||||
break
|
||||
if first_item:
|
||||
self.config_table.setFocus(Qt.TabFocusReason)
|
||||
self.config_table.scrollToItem(first_item, QAbstractItemView.PositionAtCenter)
|
||||
self.config_table.editItem(first_item)
|
||||
if self.table_edit_hint:
|
||||
self.table_edit_hint.setVisible(True)
|
||||
self._show_infobar("info", "编辑模式", f"正在编辑第 {row + 1} 行,修改后点击确认保存或退出还原")
|
||||
|
||||
def _confirm_edit(self, row, config_index):
|
||||
"""确认编辑并保存"""
|
||||
if row < 0 or row >= self.config_table.rowCount():
|
||||
return
|
||||
|
||||
# 同步表格数据到configs
|
||||
self._sync_config_from_row(row)
|
||||
|
||||
# 禁用该行的编辑
|
||||
for col in range(9):
|
||||
item = self.config_table.item(row, col)
|
||||
if item:
|
||||
item.setFlags(item.flags() & ~Qt.ItemIsEditable)
|
||||
|
||||
# 清除备份
|
||||
if hasattr(self, '_edit_backup') and row in self._edit_backup:
|
||||
del self._edit_backup[row]
|
||||
|
||||
# 恢复操作按钮
|
||||
self._set_action_buttons(row, config_index)
|
||||
self._show_infobar("success", "保存成功", f"第 {row + 1} 行数据已保存")
|
||||
# 退出编辑模式后恢复为只读
|
||||
self.config_table.setEditTriggers(TableWidget.NoEditTriggers)
|
||||
self._cleanup_edit_mode_state()
|
||||
|
||||
def _cancel_edit(self, row, config_index):
|
||||
"""取消编辑并还原数据"""
|
||||
if row < 0 or row >= self.config_table.rowCount():
|
||||
return
|
||||
|
||||
# 还原原始数据
|
||||
if hasattr(self, '_edit_backup') and row in self._edit_backup:
|
||||
original_data = self._edit_backup[row]
|
||||
# 临时断开信号防止触发同步
|
||||
try:
|
||||
self.config_table.itemChanged.disconnect(self.on_table_item_changed)
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
for col, value in original_data.items():
|
||||
item = self.config_table.item(row, col)
|
||||
if item:
|
||||
item.setText(value)
|
||||
item.setFlags(item.flags() & ~Qt.ItemIsEditable)
|
||||
finally:
|
||||
self.config_table.itemChanged.connect(self.on_table_item_changed)
|
||||
del self._edit_backup[row]
|
||||
|
||||
# 恢复操作按钮
|
||||
self._set_action_buttons(row, config_index)
|
||||
self._show_infobar("info", "已退出", f"第 {row + 1} 行数据已还原")
|
||||
# 退出编辑模式后恢复为只读
|
||||
self.config_table.setEditTriggers(TableWidget.NoEditTriggers)
|
||||
self._cleanup_edit_mode_state()
|
||||
|
||||
def delete_row_by_index(self, row):
|
||||
"""删除指定行"""
|
||||
@@ -2061,8 +2231,9 @@ class MainWindow(QMainWindow):
|
||||
"""按多多ID应用定时发布+间隔时间规则
|
||||
|
||||
规则说明:
|
||||
第一种情况:第一条数据有定时时间,有间隔时间5分钟,然后第二条数据的定时时间就是在第一条的上面加5分钟,第三条在第二条定时时间上加5分钟
|
||||
第二种情况:第一条数据没有定时时间,第二条数据有定时时间还有间隔时间5分钟,那么第三条数据在第二条定时时间上加5分钟
|
||||
1. 如果某条有定时时间,就按照定时时间发布,并记录为基准时间
|
||||
2. 如果某条没有定时时间,也没有间隔时间,就是立即发布(不设置定时)
|
||||
3. 如果某条没有定时时间,但有间隔时间,就是在上一条发布时间的基础上加上间隔时间发布
|
||||
|
||||
注意:按多多ID分组,同一个多多ID的所有数据按行顺序处理
|
||||
"""
|
||||
@@ -2073,56 +2244,42 @@ class MainWindow(QMainWindow):
|
||||
user_id = config.get("多多id", "")
|
||||
if not user_id:
|
||||
continue
|
||||
# 只按多多ID分组,不按序号分组
|
||||
grouped[user_id].append(item)
|
||||
|
||||
updated_count = 0
|
||||
for user_id, items in grouped.items():
|
||||
items.sort(key=lambda x: x["row_idx"])
|
||||
base_time = None
|
||||
interval_seconds = 0
|
||||
base_time = None # 上一条的发布时间(基准时间)
|
||||
|
||||
for entry in items:
|
||||
config = entry["config"]
|
||||
row_idx = entry["row_idx"]
|
||||
schedule_text = (config.get("定时发布") or "").strip()
|
||||
interval_value = config.get("间隔时间", 0)
|
||||
|
||||
# 解析间隔时间
|
||||
# 解析间隔时间(分钟转秒)
|
||||
current_interval = self._parse_interval_seconds(interval_value)
|
||||
|
||||
# 解析定时时间
|
||||
parsed_time = self._parse_schedule_time(schedule_text) if schedule_text else None
|
||||
|
||||
# 情况1:当前条目有定时时间和间隔时间
|
||||
# 例如:第1条有定时时间09:00和间隔时间5分钟,或第2条有定时时间09:10和间隔时间5分钟
|
||||
if parsed_time and current_interval > 0:
|
||||
# 设置基准时间和间隔时间,用于后续数据自动计算
|
||||
# 情况1:当前条目有定时时间 -> 使用该定时时间,并记录为基准时间
|
||||
if parsed_time:
|
||||
base_time = parsed_time
|
||||
interval_seconds = current_interval
|
||||
# 不更新当前条目的定时时间(保持用户设置的原值)
|
||||
# 但更新 base_time 和 interval_seconds 用于后续计算
|
||||
# 不修改当前条目的定时时间,保持用户设置的原值
|
||||
|
||||
# 情况2:当前条目有定时时间但没有间隔时间
|
||||
# 例如:用户只设置了定时时间,没有设置间隔时间
|
||||
elif parsed_time and current_interval == 0:
|
||||
# 只更新基准时间,清空间隔时间(后续不会自动计算)
|
||||
base_time = parsed_time
|
||||
interval_seconds = 0
|
||||
# 情况2:当前条目没有定时时间,但有间隔时间
|
||||
elif not parsed_time and current_interval > 0:
|
||||
if base_time:
|
||||
# 有基准时间 -> 新时间 = 基准时间 + 间隔时间
|
||||
base_time = base_time + timedelta(seconds=current_interval)
|
||||
new_text = self._format_schedule_time(base_time)
|
||||
config["定时发布"] = new_text
|
||||
self._update_table_cell(row_idx, 3, new_text, highlight=True)
|
||||
updated_count += 1
|
||||
# 如果没有基准时间,则保持空(立即发布)
|
||||
|
||||
# 情况3:当前条目没有定时时间,但存在基准时间和间隔时间
|
||||
# 例如:第1条有定时时间09:00和间隔时间5分钟,第2条没有定时时间 -> 第2条自动计算为09:05
|
||||
# 或者:第2条有定时时间09:10和间隔时间5分钟,第3条没有定时时间 -> 第3条自动计算为09:15
|
||||
elif not parsed_time and base_time and interval_seconds > 0:
|
||||
# 计算新的定时时间 = 基准时间 + 间隔时间
|
||||
base_time = base_time + timedelta(seconds=interval_seconds)
|
||||
new_text = self._format_schedule_time(base_time)
|
||||
config["定时发布"] = new_text
|
||||
self._update_table_cell(row_idx, 3, new_text, highlight=True)
|
||||
updated_count += 1
|
||||
# 注意:base_time 已经更新为新的计算值,用于下一条数据的计算
|
||||
|
||||
# 情况4:当前条目没有定时时间,也没有基准时间或间隔时间
|
||||
# 例如:第1条没有定时时间和间隔时间,第2条也没有 -> 不做任何处理
|
||||
# 情况3:当前条目没有定时时间,也没有间隔时间 -> 立即发布(保持空)
|
||||
# 不做任何处理,保持原样
|
||||
|
||||
return updated_count
|
||||
@@ -2191,6 +2348,8 @@ class MainWindow(QMainWindow):
|
||||
self.config_table.itemChanged.disconnect(self.on_table_item_changed)
|
||||
try:
|
||||
item = QTableWidgetItem(str(value))
|
||||
item.setTextAlignment(Qt.AlignCenter) # 居中对齐
|
||||
item.setFlags(item.flags() & ~Qt.ItemIsEditable)
|
||||
if highlight:
|
||||
item.setBackground(QColor("#E6F4FF"))
|
||||
self.config_table.setItem(row, col, item)
|
||||
@@ -2225,6 +2384,8 @@ class MainWindow(QMainWindow):
|
||||
try:
|
||||
# 第7列是"情况"列
|
||||
status_item = QTableWidgetItem(status)
|
||||
status_item.setTextAlignment(Qt.AlignCenter) # 居中对齐
|
||||
status_item.setFlags(status_item.flags() & ~Qt.ItemIsEditable)
|
||||
|
||||
# 根据状态设置不同的颜色
|
||||
if status == "已完成":
|
||||
@@ -2654,10 +2815,7 @@ class MainWindow(QMainWindow):
|
||||
for col, width in widths.items():
|
||||
if col < self.config_table.columnCount():
|
||||
self.config_table.setColumnWidth(col, width)
|
||||
# 设置达人链接列和文件路径列不自动调整宽度
|
||||
header = self.config_table.horizontalHeader()
|
||||
header.setSectionResizeMode(5, QHeaderView.Fixed) # 达人链接列固定宽度
|
||||
header.setSectionResizeMode(8, QHeaderView.Fixed) # 文件路径列固定宽度
|
||||
# 所有列都可以手动调整宽度(Interactive模式)
|
||||
|
||||
def _apply_table_view_column_widths(self):
|
||||
"""应用 Model/View 列宽"""
|
||||
@@ -2677,11 +2835,7 @@ class MainWindow(QMainWindow):
|
||||
for col, width in widths.items():
|
||||
if self.table_view.model() and col < self.table_view.model().columnCount():
|
||||
self.table_view.setColumnWidth(col, width)
|
||||
# 设置达人链接列和文件路径列固定宽度
|
||||
header = self.table_view.horizontalHeader()
|
||||
if header:
|
||||
header.setSectionResizeMode(5, QHeaderView.Fixed) # 达人链接列固定宽度
|
||||
header.setSectionResizeMode(8, QHeaderView.Fixed) # 文件路径列固定宽度
|
||||
# 所有列都可以手动调整宽度(Interactive模式)
|
||||
|
||||
def _refresh_log_match_selector(self, items):
|
||||
"""更新日志匹配下拉"""
|
||||
@@ -2731,14 +2885,6 @@ class MainWindow(QMainWindow):
|
||||
else:
|
||||
InfoBar.error(title=title, content=content, parent=self, position=InfoBarPosition.TOP_RIGHT)
|
||||
|
||||
def browse_excel(self):
|
||||
"""浏览Excel文件"""
|
||||
file_path, _ = QFileDialog.getOpenFileName(
|
||||
self, "选择Excel文件", "", "Excel文件 (*.xlsx *.xls)"
|
||||
)
|
||||
if file_path:
|
||||
self.excel_path_input.setText(file_path)
|
||||
|
||||
def browse_folder(self):
|
||||
"""浏览文件夹"""
|
||||
folder_path = QFileDialog.getExistingDirectory(self, "选择文件夹")
|
||||
@@ -2783,7 +2929,7 @@ class MainWindow(QMainWindow):
|
||||
self.log_text.append(" - 序号: 文件序号,用于匹配文件夹中的文件(如:1-视频名称.mp4)")
|
||||
self.log_text.append(" - 话题: 发布时的话题标签")
|
||||
self.log_text.append(" - 定时发布: 定时发布时间(格式:yyyy-MM-dd HH:mm)")
|
||||
self.log_text.append(" - 间隔时间: 同一ID下各条目的发布间隔(分钟)")
|
||||
self.log_text.append(" - 间隔时间: 在上一条基础上延迟的分钟数(无定时时间时生效)")
|
||||
self.log_text.append(" - 达人链接: 达人主页链接")
|
||||
self.log_text.append(" - 执行人: 负责人")
|
||||
self.log_text.append(" - 情况: 执行状态(待执行/执行中/已完成/失败)")
|
||||
@@ -2793,15 +2939,17 @@ class MainWindow(QMainWindow):
|
||||
logger.error(f"保存模板失败: {e}")
|
||||
|
||||
def import_excel(self):
|
||||
"""导入Excel配置文件"""
|
||||
excel_path = self.excel_path_input.text().strip()
|
||||
if not excel_path:
|
||||
self._show_infobar("warning", "警告", "请先选择Excel文件")
|
||||
return
|
||||
"""导入Excel配置文件(直接弹出文件选择对话框)"""
|
||||
# 弹出文件选择对话框
|
||||
excel_path, _ = QFileDialog.getOpenFileName(
|
||||
self, "选择Excel配置文件", "", "Excel文件 (*.xlsx *.xls)"
|
||||
)
|
||||
|
||||
if not os.path.exists(excel_path):
|
||||
self._show_infobar("warning", "警告", f"Excel文件不存在: {excel_path}")
|
||||
return
|
||||
if not excel_path:
|
||||
return # 用户取消选择
|
||||
|
||||
# 显示选择的文件路径
|
||||
self.excel_path_input.setText(excel_path)
|
||||
|
||||
try:
|
||||
# 读取Excel文件,添加更多异常处理
|
||||
@@ -2917,21 +3065,21 @@ class MainWindow(QMainWindow):
|
||||
self.config_table.setRowCount(len(self.page_row_indices))
|
||||
for table_row, config_index in enumerate(self.page_row_indices):
|
||||
config = self.configs[config_index]
|
||||
self.config_table.setItem(table_row, 0, QTableWidgetItem(str(config.get('多多id', ''))))
|
||||
self.config_table.setItem(table_row, 1, QTableWidgetItem(str(config.get('序号', ''))))
|
||||
self.config_table.setItem(table_row, 2, QTableWidgetItem(str(config.get('话题', ''))))
|
||||
self.config_table.setItem(table_row, 3, QTableWidgetItem(str(config.get('定时发布', ''))))
|
||||
self.config_table.setItem(table_row, 4, QTableWidgetItem(str(config.get('间隔时间', 0))))
|
||||
self.config_table.setItem(table_row, 0, self._create_centered_item(str(config.get('多多id', ''))))
|
||||
self.config_table.setItem(table_row, 1, self._create_centered_item(str(config.get('序号', ''))))
|
||||
self.config_table.setItem(table_row, 2, self._create_centered_item(str(config.get('话题', ''))))
|
||||
self.config_table.setItem(table_row, 3, self._create_centered_item(str(config.get('定时发布', ''))))
|
||||
self.config_table.setItem(table_row, 4, self._create_centered_item(str(config.get('间隔时间', 0))))
|
||||
# 达人链接列:设置 tooltip 显示完整内容
|
||||
url_text = str(config.get('达人链接', ''))
|
||||
url_item = QTableWidgetItem(url_text)
|
||||
url_item = self._create_centered_item(url_text)
|
||||
url_item.setToolTip(url_text) # 悬停显示完整链接
|
||||
self.config_table.setItem(table_row, 5, url_item)
|
||||
self.config_table.setItem(table_row, 6, QTableWidgetItem(str(config.get('执行人', ''))))
|
||||
self.config_table.setItem(table_row, 6, self._create_centered_item(str(config.get('执行人', ''))))
|
||||
self._set_status_item(table_row, str(config.get('情况', '待执行')))
|
||||
# 文件路径列(第8列,索引为8),如果配置中没有则显示空,设置 tooltip
|
||||
file_path = str(config.get('文件路径', ''))
|
||||
file_path_item = QTableWidgetItem(file_path)
|
||||
file_path_item = self._create_centered_item(file_path)
|
||||
file_path_item.setToolTip(file_path) # 悬停显示完整路径
|
||||
self.config_table.setItem(table_row, 8, file_path_item)
|
||||
self._set_progress_item(table_row, str(config.get('情况', '待执行')))
|
||||
|
||||
Reference in New Issue
Block a user