|
|
|
|
@ -1,6 +1,7 @@
@@ -1,6 +1,7 @@
|
|
|
|
|
import uiautomation as auto |
|
|
|
|
from utils.config import cfg |
|
|
|
|
|
|
|
|
|
import time |
|
|
|
|
import math |
|
|
|
|
softName = cfg('exe.soft_name', None) |
|
|
|
|
|
|
|
|
|
# 遍历所有控件 找到 |
|
|
|
|
@ -67,7 +68,7 @@ def findAndClick(control, depth=0,index=1):
@@ -67,7 +68,7 @@ def findAndClick(control, depth=0,index=1):
|
|
|
|
|
print(f"✗ 同级元素数量不足,只有 {len(siblings)} 个") |
|
|
|
|
return False |
|
|
|
|
else: |
|
|
|
|
findAndClickFileImportShow(child, depth + 1) |
|
|
|
|
findAndClick(child, depth + 1,index=index) |
|
|
|
|
|
|
|
|
|
# 点击导入文件按钮 |
|
|
|
|
def clickFileIMportShow(): |
|
|
|
|
@ -75,7 +76,7 @@ def clickFileIMportShow():
@@ -75,7 +76,7 @@ def clickFileIMportShow():
|
|
|
|
|
print(f"错误:软件名称未配置") |
|
|
|
|
exit(1) |
|
|
|
|
control = auto.WindowControl(searchDepth=1, Name=softName) |
|
|
|
|
clickRes = findAndClick(control,index=1) |
|
|
|
|
clickRes = findAndClick(control,0,index=1) |
|
|
|
|
return clickRes |
|
|
|
|
|
|
|
|
|
# 点击开始切片按钮 |
|
|
|
|
@ -84,5 +85,286 @@ def clickBegingSlice():
@@ -84,5 +85,286 @@ def clickBegingSlice():
|
|
|
|
|
print(f"错误:软件名称未配置") |
|
|
|
|
exit(1) |
|
|
|
|
control = auto.WindowControl(searchDepth=1, Name=softName) |
|
|
|
|
clickRes = findAndClick(control,index=2) |
|
|
|
|
clickRes = findAndClick(control,0,index=2) |
|
|
|
|
return clickRes |
|
|
|
|
|
|
|
|
|
# 全局变量:存储已找到的.obj文件名 |
|
|
|
|
arrObjName = [] |
|
|
|
|
scroll_direction = "up" |
|
|
|
|
scroll_amount = 360 |
|
|
|
|
|
|
|
|
|
def findObjFiles(control, depth=0): |
|
|
|
|
"""递归查找所有包含.obj的控件,并添加到全局数组中(去重)""" |
|
|
|
|
for child in control.GetChildren(): |
|
|
|
|
if ".obj" in child.Name and child.Name not in arrObjName: |
|
|
|
|
arrObjName.append(child.Name) |
|
|
|
|
print(f"找到文件: {child.Name}") |
|
|
|
|
findObjFiles(child, depth + 1) |
|
|
|
|
|
|
|
|
|
def findListControl(item_control, max_depth=5): |
|
|
|
|
"""向上查找列表控件(ListView等)""" |
|
|
|
|
current = item_control |
|
|
|
|
for _ in range(max_depth): |
|
|
|
|
try: |
|
|
|
|
parent = current.GetParentControl() |
|
|
|
|
if not parent: |
|
|
|
|
break |
|
|
|
|
|
|
|
|
|
# 检查是否是列表控件 |
|
|
|
|
is_list_control = ( |
|
|
|
|
parent.ControlType in [auto.ControlType.ListControl, auto.ControlType.DataGridControl] or |
|
|
|
|
"list" in str(parent.ControlType).lower() or |
|
|
|
|
"50028" in str(parent.AutomationId) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
if is_list_control: |
|
|
|
|
return parent |
|
|
|
|
current = parent |
|
|
|
|
except: |
|
|
|
|
break |
|
|
|
|
return None |
|
|
|
|
|
|
|
|
|
def scrollListView(list_control): |
|
|
|
|
"""滚动列表控件 |
|
|
|
|
Args: |
|
|
|
|
list_control: 列表控件对象 |
|
|
|
|
scroll_direction: "up" 向上滚动, "down" 向下滚动 |
|
|
|
|
Returns: |
|
|
|
|
bool: 是否滚动成功 |
|
|
|
|
""" |
|
|
|
|
try: |
|
|
|
|
import win32api |
|
|
|
|
import win32con |
|
|
|
|
|
|
|
|
|
# 获取列表控件中心位置 |
|
|
|
|
rect = list_control.BoundingRectangle |
|
|
|
|
center_x = int(rect.left + (rect.right - rect.left) / 2) |
|
|
|
|
center_y = int(rect.top + (rect.bottom - rect.top) / 2) |
|
|
|
|
|
|
|
|
|
# 移动鼠标到列表中心 |
|
|
|
|
win32api.SetCursorPos((center_x, center_y)) |
|
|
|
|
time.sleep(0.1) |
|
|
|
|
|
|
|
|
|
# 根据方向决定滚动量(负数向上,正数向下) |
|
|
|
|
# scroll_amount = -360 if scroll_direction == "up" else 360 |
|
|
|
|
# if scroll_direction == "up": |
|
|
|
|
# scroll_amount = -scroll_amount |
|
|
|
|
scroll_count = 3 # 滚动次数 |
|
|
|
|
scroll_interval = 0.1 # 每次滚动间隔 |
|
|
|
|
|
|
|
|
|
# 向上取整 |
|
|
|
|
scroll_count = abs(math.ceil(scroll_amount / 360)) |
|
|
|
|
|
|
|
|
|
# 执行滚动 |
|
|
|
|
for _ in range(scroll_count): |
|
|
|
|
win32api.mouse_event(win32con.MOUSEEVENTF_WHEEL, 0, 0, scroll_amount, 0) |
|
|
|
|
time.sleep(scroll_interval) |
|
|
|
|
|
|
|
|
|
time.sleep(0.2) |
|
|
|
|
direction_text = "向上" if scroll_amount < 0 else "向下" |
|
|
|
|
print(f"✓ 使用鼠标滚轮滚动成功,方向: {direction_text}") |
|
|
|
|
return True |
|
|
|
|
except Exception as e: |
|
|
|
|
print(f"✗ 滚动列表失败: {e}") |
|
|
|
|
return False |
|
|
|
|
|
|
|
|
|
def clickAndScrollFirstObj(control, depth=0): |
|
|
|
|
"""找到第一个.obj文件,点击并滚动列表 |
|
|
|
|
Args: |
|
|
|
|
control: 控件对象 |
|
|
|
|
depth: 递归深度 |
|
|
|
|
Returns: |
|
|
|
|
bool: 是否成功找到并点击 |
|
|
|
|
""" |
|
|
|
|
for child in control.GetChildren(): |
|
|
|
|
if ".obj" in child.Name: |
|
|
|
|
# 获取第一个子控件作为点击目标 |
|
|
|
|
siblings = control.GetChildren() |
|
|
|
|
if not siblings: |
|
|
|
|
continue |
|
|
|
|
|
|
|
|
|
target = siblings[0] |
|
|
|
|
|
|
|
|
|
# 尝试点击 |
|
|
|
|
try: |
|
|
|
|
target.Click() |
|
|
|
|
print("✓ 使用 Click() 方法点击成功") |
|
|
|
|
# 等待点击生效 |
|
|
|
|
time.sleep(0.2) |
|
|
|
|
# 查找列表控件并滚动 |
|
|
|
|
list_control = findListControl(child) |
|
|
|
|
if list_control: |
|
|
|
|
print(f"找到列表控件: {list_control.ControlType} - {list_control.AutomationId}") |
|
|
|
|
print("开始滚动列表...") |
|
|
|
|
scrollListView(list_control) |
|
|
|
|
else: |
|
|
|
|
print("未找到列表控件,跳过滚动") |
|
|
|
|
|
|
|
|
|
return True |
|
|
|
|
except Exception as e: |
|
|
|
|
print(f"✗ Click() 失败: {e}") |
|
|
|
|
return True |
|
|
|
|
|
|
|
|
|
# 递归查找 |
|
|
|
|
if clickAndScrollFirstObj(child, depth + 1): |
|
|
|
|
return True |
|
|
|
|
|
|
|
|
|
return False |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 获取所有窗口信息 |
|
|
|
|
def getAllWindowsInfo(): |
|
|
|
|
windows_info = [] |
|
|
|
|
try: |
|
|
|
|
import win32gui |
|
|
|
|
def enum_windows_callback(hwnd, windows): |
|
|
|
|
try: |
|
|
|
|
if win32gui.IsWindowVisible(hwnd): |
|
|
|
|
window_title = win32gui.GetWindowText(hwnd) |
|
|
|
|
class_name = win32gui.GetClassName(hwnd) |
|
|
|
|
|
|
|
|
|
# 获取最顶层窗口 |
|
|
|
|
top_hwnd = win32gui.GetForegroundWindow() |
|
|
|
|
is_top = (hwnd == top_hwnd) |
|
|
|
|
|
|
|
|
|
windows.append({ |
|
|
|
|
'hwnd': hwnd, |
|
|
|
|
'title': window_title, |
|
|
|
|
'class_name': class_name, |
|
|
|
|
'is_visible': True, |
|
|
|
|
'is_top': is_top |
|
|
|
|
}) |
|
|
|
|
except: |
|
|
|
|
pass |
|
|
|
|
return True |
|
|
|
|
|
|
|
|
|
win32gui.EnumWindows(enum_windows_callback, windows_info) |
|
|
|
|
|
|
|
|
|
# 按是否最顶层排序(最顶层在前) |
|
|
|
|
windows_info.sort(key=lambda x: (not x['is_top'], x['title'])) |
|
|
|
|
|
|
|
|
|
return windows_info |
|
|
|
|
|
|
|
|
|
except ImportError: |
|
|
|
|
print("错误: win32gui 未安装,无法获取窗口信息") |
|
|
|
|
return [] |
|
|
|
|
except Exception as e: |
|
|
|
|
print(f"获取窗口信息时发生异常: {e}") |
|
|
|
|
import traceback |
|
|
|
|
traceback.print_exc() |
|
|
|
|
return [] |
|
|
|
|
|
|
|
|
|
# 检测是否存在标题为"生成代码信息"的弹框,并获取其文本信息 |
|
|
|
|
def checkIsSliceingText(): |
|
|
|
|
try: |
|
|
|
|
import win32gui |
|
|
|
|
# 获取所有窗口信息 |
|
|
|
|
all_windows = getAllWindowsInfo() |
|
|
|
|
# 打印所有窗口信息 |
|
|
|
|
print(f"当前所有可见窗口(共 {len(all_windows)} 个):") |
|
|
|
|
for win_info in all_windows: |
|
|
|
|
if "SlicingInfoDialog" in win_info['title']: |
|
|
|
|
#获取控件对象,获取到时间信息,并返回 |
|
|
|
|
control = auto.WindowControl(searchDepth=1, hwnd=win_info['hwnd']) |
|
|
|
|
a = getWindowText(control) |
|
|
|
|
return a[0]['text'] |
|
|
|
|
return True |
|
|
|
|
except ImportError: |
|
|
|
|
print("错误: win32gui 未安装,无法查找窗口") |
|
|
|
|
return False |
|
|
|
|
except Exception as e: |
|
|
|
|
print(f"检查弹框时发生异常: {e}") |
|
|
|
|
import traceback |
|
|
|
|
traceback.print_exc() |
|
|
|
|
return False |
|
|
|
|
|
|
|
|
|
# 获取窗口内所有文本信息 |
|
|
|
|
def getWindowText(control, depth=0, texts=None): |
|
|
|
|
"""递归获取控件及其子控件的所有文本信息 |
|
|
|
|
Args: |
|
|
|
|
control: 控件对象 |
|
|
|
|
depth: 递归深度 |
|
|
|
|
texts: 文本列表 |
|
|
|
|
Returns: |
|
|
|
|
list: 所有文本信息的列表 |
|
|
|
|
""" |
|
|
|
|
if texts is None: |
|
|
|
|
texts = [] |
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
# 获取控件名称 |
|
|
|
|
if hasattr(control, 'Name') and control.Name: |
|
|
|
|
if getattr(control, 'AutomationId', '') == "labelDuration": |
|
|
|
|
texts.append({ |
|
|
|
|
'depth': depth, |
|
|
|
|
'type': str(control.ControlType), |
|
|
|
|
'name': control.Name, |
|
|
|
|
'automation_id': getattr(control, 'AutomationId', ''), |
|
|
|
|
'text': control.Name |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 递归获取子控件文本 |
|
|
|
|
try: |
|
|
|
|
for child in control.GetChildren(): |
|
|
|
|
getWindowText(child, depth + 1, texts) |
|
|
|
|
except: |
|
|
|
|
pass |
|
|
|
|
|
|
|
|
|
except Exception as e: |
|
|
|
|
pass |
|
|
|
|
|
|
|
|
|
return texts |
|
|
|
|
|
|
|
|
|
def checkImportFileIsSuccess(modelCounts = 0,find_interval=2, scroll_interval=1): |
|
|
|
|
|
|
|
|
|
if modelCounts == 0: |
|
|
|
|
print(f"错误:模型数量未配置") |
|
|
|
|
return False |
|
|
|
|
if softName is None: |
|
|
|
|
print("错误:软件名称未配置") |
|
|
|
|
return |
|
|
|
|
|
|
|
|
|
control = auto.WindowControl(searchDepth=1, Name=softName) |
|
|
|
|
if not control.Exists(0, 0): |
|
|
|
|
print(f"错误:未找到窗口 {softName}") |
|
|
|
|
return |
|
|
|
|
|
|
|
|
|
global arrObjName |
|
|
|
|
global scroll_direction |
|
|
|
|
global scroll_amount |
|
|
|
|
arrObjName = [] |
|
|
|
|
scroll_direction = "up" |
|
|
|
|
scroll_amount = 120*50*3 |
|
|
|
|
# 每次滚动 移动到最顶部 |
|
|
|
|
clickAndScrollFirstObj(control, 0) |
|
|
|
|
time.sleep(10) |
|
|
|
|
rection = "up" |
|
|
|
|
scroll_amount = -120*10 |
|
|
|
|
|
|
|
|
|
temptoTalCounts = 0 |
|
|
|
|
compareCounts = 0 |
|
|
|
|
#死循环 |
|
|
|
|
while True: |
|
|
|
|
if len(arrObjName) >= modelCounts: |
|
|
|
|
break |
|
|
|
|
else: |
|
|
|
|
findObjFiles(control, 0) |
|
|
|
|
time.sleep(find_interval) |
|
|
|
|
clickAndScrollFirstObj(control, 0) |
|
|
|
|
time.sleep(scroll_interval) |
|
|
|
|
#判断 arrObjName 长度,连续3次没有变化,则退出循环 |
|
|
|
|
if temptoTalCounts < len(arrObjName): |
|
|
|
|
temptoTalCounts = len(arrObjName) |
|
|
|
|
else: |
|
|
|
|
compareCounts += 1 |
|
|
|
|
if compareCounts >= 3: |
|
|
|
|
break |
|
|
|
|
print(f"当前已找到文件数量: {len(arrObjName)}") |
|
|
|
|
|
|
|
|
|
if len(arrObjName) == modelCounts: |
|
|
|
|
print(f"文件导入完成") |
|
|
|
|
return True |
|
|
|
|
|
|
|
|
|
print(f"文件导入未完成") |
|
|
|
|
return False |