代码拉取完成,页面将自动刷新
# -*- coding: utf-8 -*-
import configparser
import functools
import os.path
import subprocess
import sys
from datetime import datetime
import re
import shutil
import webbrowser
from lanrentools.扫描是否有ACE import checkACEPresence
from wayfinding import *
from PyQt5.Qt import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from ui.formitemjiaoben import Ui_formitemjiaoben
from ui.guanjitishi import ShutdownConfirmationDialog
from ui.main import Ui_mainWindow
from ui.formitem import Ui_formitem
from ui.formitemfuben import Ui_formitemfuben
from ui.formshow import Ui_DockWidget
from ui.yunfilelist import Ui_form_yunfilelist
from ui.formitemyun import Ui_formitemyun
from ui.formitemxuanjue import Ui_formitemxuanjue
from ui.formitemlianzhao import Ui_formitemlianzhao
from PyQt5.QtWidgets import QMessageBox
from lanrentools.stitchimages import *
from yunpan import YunPan
from jianchaupdate import get_var_data, get_updatetxt
def extract_number(folder_name):
numbers = re.findall(r'\d+', folder_name)
return int(numbers[0]) if numbers else float('inf')
def is_intersecting(region1, region2):
# region1 和 region2 是由 (x1, y1, x2, y2) 定义的元组,表示左下角 (x1, y1) 和右上角 (x2, y2) 的坐标
# 提取区域1的坐标
x1_r1, y1_r1, x2_r1, y2_r1 = region1
# 提取区域2的坐标
x1_r2, y1_r2, x2_r2, y2_r2 = region2
# 检查是否相交
if x1_r1 > x2_r2 or x1_r2 > x2_r1: # 横向无交集
return False
if y1_r1 > y2_r2 or y1_r2 > y2_r1: # 纵向无交集
return False
# 如果通过上述检查,则相交
return True
class MySignal(QObject):
mySignal = pyqtSignal(int, str) # 定义自定义信号,并指定信号参数类型
mysig_shutdown = pyqtSignal()
mysig_mouse_through = pyqtSignal(bool)
mysig_tishi = pyqtSignal(str)
mysig_show_xunlu = pyqtSignal()
mysig_show_yolov = pyqtSignal()
mysig_dingwei=pyqtSignal(int)
mysig_next_pack=pyqtSignal(str)
class WrappedTextToolButton(QToolButton):
def __init__(self, text, parent=None):
super().__init__(parent)
self.setText(text)
def sizeHint(self):
size_hint = super().sizeHint()
font_metrics = self.fontMetrics()
width = max(font_metrics.width(self.text()), 100) # 最小宽度为 100 像素
height = font_metrics.heightForWidth(width)
size_hint.setWidth(width)
size_hint.setHeight(height)
return size_hint
class FrameItem(QFrame, Ui_formitem):
def __init__(self, parent=None):
super(QFrame, self).__init__(parent)
self.setupUi(self)
self.set_ui()
self.is_zd=False
w = int(item_width * ratio)
h = int(item_height_min * ratio)
self.setMinimumSize(w + int(1 * ratio), h)
self.setMaximumSize(w, h)
# self.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowCloseButtonHint | Qt.WindowStaysOnTopHint)
def set_ui(self):
pass
def mousePressEvent(self, event):
if not self.is_zd:
self.is_zd=not self.is_zd
w = int(item_width * ratio)
h = int(item_height * ratio)
self.setMinimumSize(w + int(1* ratio), h)
self.setMaximumSize(w, h)
self.bt_map.setVisible(True)
self.bt_lujing.setVisible(True)
self.bt_chuansong.setVisible(True)
self.bt_moban.setVisible(True)
self.bt_moban_maodian.setVisible(True)
self.bt_start.setVisible(True)
self.cb_wakuang.setVisible(True)
self.cb_daditu.setVisible(True)
self.cb_daguai.setVisible(True)
self.bt_del.setVisible(True)
else:
self.is_zd = not self.is_zd
w = int(item_width * ratio)
h = int(item_height_min * ratio)
self.setMinimumSize(w + int(1* ratio), h)
self.setMaximumSize(w, h)
self.bt_map.setVisible(False)
self.bt_lujing.setVisible(False)
self.bt_chuansong.setVisible(False)
self.bt_moban.setVisible(False)
self.bt_moban_maodian.setVisible(False)
self.bt_start.setVisible(False)
self.cb_wakuang.setVisible(False)
self.cb_daditu.setVisible(False)
self.cb_daguai.setVisible(False)
self.bt_del.setVisible(False)
class FrameItemFuBen(QFrame, Ui_formitemfuben):
def __init__(self, parent=None):
super(QFrame, self).__init__(parent)
self.setupUi(self)
self.set_ui()
self.is_zd=False
w = int(item_width * ratio)
h = int(item_height_min * ratio)
self.setMinimumSize(w + int(1 * ratio), h)
self.setMaximumSize(w, h)
# self.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowCloseButtonHint | Qt.WindowStaysOnTopHint)
def set_ui(self):
pass
def mousePressEvent(self, event):
if not self.is_zd:
self.is_zd=not self.is_zd
# 在这里添加鼠标进入时的逻辑
w = int(item_width * ratio)
h = int(item_height * ratio)
self.setMinimumSize(w + int(1* ratio), h)
self.setMaximumSize(w, h)
self.bt_chuansong.setVisible(True)
self.bt_moban.setVisible(True)
self.bt_moban_maodian.setVisible(True)
self.bt_start.setVisible(True)
self.bt_del.setVisible(True)
self.cbb_level.setVisible(True)
self.cb_lingjiang.setVisible(True)
self.led_cishu.setVisible(True)
self.label.setVisible(True)
else:
self.is_zd = not self.is_zd
w = int(item_width * ratio)
h = int(item_height_min * ratio)
self.setMinimumSize(w + int(1 * ratio), h)
self.setMaximumSize(w, h)
self.bt_chuansong.setVisible(False)
self.bt_moban.setVisible(False)
self.bt_moban_maodian.setVisible(False)
self.bt_start.setVisible(False)
self.bt_del.setVisible(False)
self.cbb_level.setVisible(False)
self.cb_lingjiang.setVisible(False)
self.led_cishu.setVisible(False)
self.label.setVisible(False)
class FrameItemJiaoBen(QFrame, Ui_formitemjiaoben):
def __init__(self, parent=None):
super(QFrame, self).__init__(parent)
self.setupUi(self)
self.set_ui()
self.is_zd=False
w = int(item_width * ratio)
h = int(item_height_min * ratio)
self.setMinimumSize(w + int(1 * ratio), h)
self.setMaximumSize(w, h)
# self.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowCloseButtonHint | Qt.WindowStaysOnTopHint)
def set_ui(self):
pass
def mousePressEvent(self, event):
if not self.is_zd:
self.is_zd=not self.is_zd
# 在这里添加鼠标进入时的逻辑
w = int(item_width* ratio)
h = int(item_height* ratio)
self.setMinimumSize(w + int(1* ratio), h)
self.setMaximumSize(w, h)
self.bt_start.setVisible(True)
self.bt_jiaoben.setVisible(True)
self.bt_chuansong.setVisible(True)
self.bt_moban_maodian.setVisible(True)
self.bt_moban.setVisible(True)
self.bt_start.setVisible(True)
self.bt_del.setVisible(True)
self.cb_auto_f.setVisible(True)
else:
self.is_zd = not self.is_zd
w = int(item_width * ratio)
h = int(item_height_min * ratio)
self.setMinimumSize(w + int(1* ratio), h)
self.setMaximumSize(w, h)
self.bt_start.setVisible(False)
self.bt_jiaoben.setVisible(False)
self.bt_chuansong.setVisible(False)
self.bt_moban_maodian.setVisible(False)
self.bt_moban.setVisible(False)
self.bt_start.setVisible(False)
self.bt_del.setVisible(False)
self.cb_auto_f.setVisible(False)
class FrameItemXuanJue(QFrame, Ui_formitemxuanjue):
def __init__(self, parent=None):
super(QFrame, self).__init__(parent)
self.setupUi(self)
self.set_ui()
self.is_zd=False
w = int(item_width * ratio)
h = int(item_height_min * ratio)
self.setMinimumSize(w + int(1 * ratio), h)
self.setMaximumSize(w, h)
# self.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowCloseButtonHint | Qt.WindowStaysOnTopHint)
#过滤滚轮事件 防止误触
self.cbb_1.installEventFilter(self)
self.cbb_2.installEventFilter(self)
self.cbb_3.installEventFilter(self)
def eventFilter(self,obj, event):
if isinstance(obj, QComboBox) and event.type() == QEvent.Wheel and not obj.view().isVisible():
return True # 拦截鼠标滚轮事件
return False
def set_ui(self):
pass
def mousePressEvent(self, event):
if not self.is_zd:
self.is_zd=not self.is_zd
# 在这里添加鼠标进入时的逻辑
w = int(item_width * ratio)
h = int(item_height * ratio)
self.setMinimumSize(w + int(1* ratio), h)
self.setMaximumSize(w, h)
self.bt_start.setVisible(True)
self.cbb_1.setVisible(True)
self.cbb_2.setVisible(True)
self.cbb_3.setVisible(True)
self.lb_zhanchang.setVisible(True)
self.led_main.setVisible(True)
self.bt_del.setVisible(True)
else:
self.is_zd = not self.is_zd
w = int(item_width * ratio)
h = int(item_height_min * ratio)
self.setMinimumSize(w + int(1* ratio), h)
self.setMaximumSize(w, h)
self.bt_start.setVisible(False)
self.cbb_1.setVisible(False)
self.cbb_2.setVisible(False)
self.cbb_3.setVisible(False)
self.lb_zhanchang.setVisible(False)
self.led_main.setVisible(False)
self.bt_del.setVisible(False)
class FrameItemLianZhao(QFrame, Ui_formitemlianzhao):
def __init__(self, parent=None):
super(QFrame, self).__init__(parent)
self.setupUi(self)
self.set_ui()
self.is_zd=False
w = int(item_width * ratio)
h = int(item_height_min * ratio)
self.setMinimumSize(w + int(1 * ratio), h)
self.setMaximumSize(w, h)
# self.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowCloseButtonHint | Qt.WindowStaysOnTopHint)
#过滤滚轮事件 防止误触
self.cbb_lianzhao.installEventFilter(self)
def eventFilter(self,obj, event):
if isinstance(obj, QComboBox) and event.type() == QEvent.Wheel and not obj.view().isVisible():
return True # 拦截鼠标滚轮事件
return False
def set_ui(self):
pass
def mousePressEvent(self, event):
if not self.is_zd:
self.is_zd=not self.is_zd
# 在这里添加鼠标进入时的逻辑
w = int(item_width * ratio)
h = int(item_height * ratio)
self.setMinimumSize(w + int(1* ratio), h)
self.setMaximumSize(w, h)
self.bt_start.setVisible(True)
self.cbb_lianzhao.setVisible(True)
self.bt_del.setVisible(True)
else:
self.is_zd = not self.is_zd
w = int(item_width * ratio)
h = int(item_height_min * ratio)
self.setMinimumSize(w + int(1* ratio), h)
self.setMaximumSize(w, h)
self.bt_start.setVisible(False)
self.cbb_lianzhao.setVisible(False)
self.bt_del.setVisible(False)
class FormShow(QDockWidget, Ui_DockWidget):
def __init__(self, parent=None):
super(QDockWidget, self).__init__(parent)
self.parent=parent
self.setupUi(self)
self.set_ui()
#self.timer = QTimer()
self.setWindowTitle("检测预览")
self.lb_yolov.setScaledContents(True)
self.lb_yolov.setAlignment(Qt.AlignCenter)
self.lb_xunlu.setAlignment(Qt.AlignCenter)
self.move(0, 0)
self.setWindowFlags(Qt.WindowStaysOnTopHint)
self.window_height=int(270* ratio)
self.window_width=int(480* ratio)
self.setMinimumSize(self.window_width, self.window_height * 2)
self.bt_jia.clicked.connect(self.clicked_jia)
self.bt_jian.clicked.connect(self.clicked_jian)
def set_ui(self):
pass
def clicked_jia(self):
if self.window_height+108* ratio>1080* ratio:
return
self.window_height += int(108* ratio)
self.window_width += int(190* ratio)
self.lb_xunlu.setFixedHeight(self.window_height)
if self.width() >= self.lb_yolov.width() + self.lb_xunlu.width():
self.lb_yolov.move(self.lb_xunlu.width(), 0)
else:
self.lb_yolov.move(0, self.lb_xunlu.height())
self.lb_yolov.setFixedHeight(self.window_height)
self.lb_yolov.setFixedWidth(self.window_width)
def clicked_jian(self):
if self.window_height-108* ratio < 270* ratio:
return
self.window_height -= int(108* ratio)
self.window_width -= int(190* ratio)
self.lb_xunlu.setFixedHeight(self.window_height)
if self.width() >= self.lb_yolov.width() + self.lb_xunlu.width():
self.lb_yolov.move(self.lb_xunlu.width(), 0)
else:
self.lb_yolov.move(0, self.lb_xunlu.height())
self.lb_yolov.setFixedHeight(self.window_height)
self.lb_yolov.setFixedWidth(self.window_width)
def closeEvent(self, event):
state.开关_是否展预测结果 = False
self.parent.action_isShow.setChecked(state.开关_是否展预测结果)
def resizeEvent(self, event):
if self.width() >= self.lb_yolov.width() + self.lb_xunlu.width():
self.lb_yolov.move(self.lb_xunlu.width(), 0)
else:
self.lb_yolov.move(0, self.lb_xunlu.height())
class FormItemYun(QFrame, Ui_formitemyun):
def __init__(self, parent=None):
super(QFrame, self).__init__(parent)
self.setupUi(self)
self.set_ui()
# self.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowCloseButtonHint | Qt.WindowStaysOnTopHint)
def set_ui(self):
pass
class FormYunFileList(QFrame, Ui_form_yunfilelist,YunPan):
def __init__(self):
super().__init__()
YunPan.__init__(self)
self.set_ui()
self.setupUi(self)
self.setWindowIcon(QIcon("datas/logo.png"))
self.setWindowTitle('懒人群友云端资源 感谢零度可乐提供云端支持') # 标题
self.setWindowFlags(Qt.WindowStaysOnTopHint)
self.resize(int(910*ratio), int(700*ratio))
self.g_box = QGridLayout()
self.container_widget = QWidget() # 创建一个中间部件 为了可以让g_布局超过窗口大小
self.container_widget.setLayout(self.g_box) # 将网格布局设置给中间部件
self.g_box.setAlignment(Qt.AlignTop | Qt.AlignLeft) # 布局 左上对齐
self.g_box.setContentsMargins(0, 0, 0, 0) # 边距
self.g_box.setAlignment(Qt.AlignTop)
self.sa_main.setWidget(self.container_widget) # 将中间部件设置为QScrollArea的子部件
# 获取纵向滚动条控件
vertical_scrollbar = self.findChild(QScrollArea)
self.v_scrollbar = vertical_scrollbar.verticalScrollBar()
self.row = 0
self.column = -1
# 所有数据
self.datas = []
self.login(username="lanren",password="lanrenai2024")
# 创建一个计时器,用于延迟布局
self.timer = QTimer(self)
self.timer.setSingleShot(True) # 设置为单次触发
self.timer.timeout.connect(self.update_layout)
self.connect_set()
self.ing=True
# 创建一个计时器,用于延迟布局
self.timer1 = QTimer(self)
self.timer1.timeout.connect(self.update_init)
self.timer1.start(200)
self.lb_ing=QLabel("加载中请稍等...",self)
self.lb_ing.setStyleSheet("""
font: 75 50pt "微软雅黑";
color: rgb(255, 0, 0);
""")
self.lb_ing.resize(500,100)
def update_init(self):
if not self.ing:
self.updatefilelist()
self.lb_ing.close()
self.timer1.stop()
def set_ui(self):
self.setStyleSheet("""
QScrollBar::handle:horizontal {
background-color: #A50F2C; /* 设置滑块颜色 */
}
QScrollBar::handle:horizontal:hover{
background-color: #FF1744; /* 设置滑块颜色 */
}
QPushButton:hover{
background-color: #DFC472; /* 设置颜色 */
}
QPlainTextEdit{padding: 0px;margin: 0px;}
QPushButton{padding: 0px;margin: 1px;}
""" + "font-family: {}; font-size: {}pt;".format(font.family(), font.pointSize()))
def resizeEvent(self, event):
super().resizeEvent(event)
# 每当用户调整窗口大小时,启动计时器
self.timer.start(300) # 500毫秒后触发timeout信号
def connect_set(self):
self.tabWidget.currentChanged.connect(self.currentChanged_tabWidget)
def currentChanged_tabWidget(self,index):
self.updatefilelist(keys=self.tabWidget.tabText(index))
def update_layout(self):
try:
# 获取主窗口的宽度
width = self.width()
# 计算每行可以容纳的组件数量
num_per_row = (width ) // (280 * ratio) # 假设每个组件的宽度为200
if num_per_row < 1:
num_per_row = 1
# 清空当前布局
for i in reversed(range(self.g_box.count())):
self.g_box.itemAt(i).widget().setParent(None)
# 重新添加组件到网格布局
for i, data in enumerate(self.datas):
self.row = int(i // num_per_row)
self.column =int( i % num_per_row)
self.g_box.addWidget(data["f_item"], self.row, self.column)
except:
pass
def update(self):
self.ing=True
self.file_all=[]
self.file_all = self.get_file_all(isclose=True,dir_="鸣潮AI")
self.file_all = list(map(lambda x: {"name": x['name'], "sign": x['sign'], "dir": x['dir'],
"url": x['raw_url'], "modified": x['modified']}, self.file_all))
self.file_all = sorted(self.file_all, key=lambda x: datetime.strptime(x['modified'].split("+")[0].split(".")[0], "%Y-%m-%dT%H:%M:%S"),
reverse=True)
self.ing = False
def updatefilelist(self,keys=""):
try:
if keys=="全部":
keys=""
self.datas = []
self.row = 0
self.column = -1
# 清空当前布局
for i in reversed(range(self.g_box.count())):
self.g_box.itemAt(i).widget().setParent(None)
for item in self.file_all:
if keys in item[ "dir"].split("/")[-3] or keys=="":
self.add_yun_file(data=item)
except:
pass
def add_yun_file(self,data={}):
'''
添加云文件显示
:return:
'''
# 根据导入的文件
# 获取主窗口的宽度
# 获取主窗口的宽度
width = self.width()
# 计算每行可以容纳的组件数量
num_per_row = (width ) // (280* ratio) # 假设每个组件的宽度为200
if num_per_row < 1:
num_per_row = 1
self.column += 1
if self.column == num_per_row:
self.column = 0
self.row += 1
f_item = FormItemYun()
w = int(300* ratio)
h = int(180* ratio)
f_item.setMinimumSize(int((w + 13)* ratio), h)
f_item.setMinimumSize(w, h)
f_item.setMaximumSize(w, h)
f_item.setObjectName("frame_cont")
f_item.raise_()
f_item.setStyleSheet("""
#frame_cont:hover {
border: 1px solid red;
}
#frame_cont {
background-color: rgba(0, 0, 0, 0);
}
""")
f_item.bt_down.clicked.connect(lambda: webbrowser.open(data["url"]))
f_item.led_name.setText(data["name"])
f_item.led_author.setText(data["dir"].split("/")[-2][:-6])
f_item.led_time.setText(data["modified"].split(".")[0].replace("T", " "))
data["f_item"] = f_item
self.datas.append(data)
self.g_box.addWidget(f_item, self.row, self.column)
class MainWindow(QMainWindow, Ui_mainWindow):
def __init__(self):
super().__init__()
self.set_ui()
self.setupUi(self)
self.setWindowIcon(QIcon("datas/logo.png"))
self.setWindowTitle(f"懒人鸣潮AI{state.版本号} F8暂停 F9停止 F10标记")
self.resize(state.WINDOW_WIDTH, state.WINDOW_HEIGHT)
self.move(state.WINDOW_LEFT, state.WINDOW_TOP)
self.g_box = QGridLayout()
self.container_widget = QWidget() # 创建一个中间部件 为了可以让g_布局超过窗口大小
self.container_widget.setLayout(self.g_box) # 将网格布局设置给中间部件
self.g_box.setAlignment(Qt.AlignTop | Qt.AlignLeft) # 布局 左上对齐
self.g_box.setContentsMargins(0, 0, 0, 0) # 边距
self.g_box.setAlignment(Qt.AlignTop)
self.sa_main.setWidget(self.container_widget) # 将中间部件设置为QScrollArea的子部件
# 获取纵向滚动条控件
vertical_scrollbar = self.findChild(QScrollArea)
self.v_scrollbar = vertical_scrollbar.verticalScrollBar()
self.setWindowFlags(Qt.WindowStaysOnTopHint)
self.row = 0
self.column = -1
self.run_times = 1
self.column_step=310
# 所有数据
self.datas = []
# 创建一个计时器,用于延迟布局
self.timer = QTimer(self)
self.timer.setSingleShot(True) # 设置为单次触发
self.timer.timeout.connect(self.update_layout)
self.connect_set()
# 加载任务包列表
self.load_task_packs()
self.show_tool_item(state.PATH_TASK,)
self.timer_luzhi = QTimer(self)
self.timer_luzhi.timeout.connect(self.timeout_luzhi)
self.timer_luzhi_chuansong = QTimer(self)
self.timer_luzhi_chuansong.timeout.connect(self.timeout_luzhi_chuansong)
self.timer_luzhi_lianzhao = QTimer(self)
self.timer_luzhi_lianzhao.timeout.connect(self.timeout_luzhi_lianzhao)
self.timer_huifang = QTimer(self)
self.timer_huifang.timeout.connect(self.timeout_huifang)
# 获取主窗口的状态栏对象
self.statusbar = self.statusBar()
# 设置状态栏文本
self.statusbar.showMessage('本工具仅在QQ群789467094中免费分享!欢迎使用懒人鸣潮AI!')
#禁止截图
#set_window_display_affinity(int(self.winId()))
# self.toolBar.setMovable(True)
# self.toolBar.setFloatable(True)
# self.toolBar.setAllowedAreas(Qt.AllToolBarAreas)
def load_task_packs(self):
self.toolBar.clear()
packs=state.PACKS_TASK.split("#@@#")
try:
if len(packs)>=1:
for pack in packs:
if pack!="":
self.add_tool_item(pack)
else:
self.add_tool_item(state.PACKS_TASK)
except:
pass
def update_tasks(self):
try:
self.datas = []
self.row = 0
self.column = -1
# 清空当前布局
for i in reversed(range(self.g_box.count())):
self.g_box.itemAt(i).widget().setParent(None)
# 遍历文件夹下有哪些目录
#判断这个路径是否存在
if not os.path.exists(state.PATH_TASK):
state.PATH_TASK="./datas/Task/"
# 创建 ConfigParser 对象
config_main = configparser.ConfigParser()
# 加载 INI 文件
config_main.read(os.path.join(state.PATH_TASK, "细节参数.ini"))
self.run_times = int(config_main.get('seting', 'run_times', fallback='1'))
self.action_run_times.setText(f"设置:当前任务包 执行次数:{self.run_times}")
# 获取文件夹列表
folders = [item for item in os.listdir(state.PATH_TASK) if os.path.isdir(os.path.join(state.PATH_TASK, item))]
# 将文件夹名称中的数字提取出来,并按照数字大小排序
sorted_folders = sorted(folders, key=lambda x: extract_number(x))
for item in sorted_folders:
item_path = os.path.join(state.PATH_TASK, item)
if os.path.isdir(item_path):
# 创建 ConfigParser 对象
config = configparser.ConfigParser()
# 加载 INI 文件
config.read(os.path.join(item_path, "jiaoben.ini"))
if config.get('seting', 'type', fallback='1') == "2":
# 副本任务
self.add_taskfuben(item_path, config)
elif config.get('seting', 'type', fallback='1') == "3":
# 脚本任务
self.add_taskjiaoben(item_path, config)
elif config.get('seting', 'type', fallback='1') == "4":
# 脚本任务
self.add_xuanjue(item_path, config)
elif config.get('seting', 'type', fallback='1') == "5":
# 脚本任务
self.add_xuanlianzhao(item_path, config)
else:
# 锄地任务
self.add_task(item_path, config)
except Exception:
logger.info(f"请选择任务文件夹,目前没有这个文件夹{state.PATH_TASK}" )
def resizeEvent(self, event):
super().resizeEvent(event)
self.data=[]
# 每当用户调整窗口大小时,启动计时器
self.timer.start(300) # 500毫秒后触发timeout信号
def timeout_luzhi(self):
if state.录制_脚本文本 != "":
tangbaowss.send_msg( "是否禁止录制#@@#真")
state.状态_是否禁止录制 = True
dir_ = os.path.join(state.PATH_TASK, self.datas[state.录制_当前任务索引]["name"])
if not os.path.exists(dir_):
os.makedirs(dir_)
# 并且将jiaoben.ini文件也填入数据然后生成
path = dir_ + "/脚本.txt"
with open(path, "w", encoding="gbk", newline='') as f:
f.write(state.录制_脚本文本)
self.datas[state.录制_当前任务索引]["jiaoben"] = "脚本.txt"
self.datas[state.录制_当前任务索引]["f_item"].bt_jiaoben.setProperty("OK_jiaoben", True)
logger.info(f"导入脚本成功:{path}")
self.sg.mysig_tishi.emit(f"导入脚本成功:{path}")
self.datas[state.录制_当前任务索引]["f_item"].bt_jiaoben.setStyleSheet("""
#bt_jiaoben[OK_jiaoben="true"] {
color: rgb(237,182,43);
border-color: rgb(237,182,43);
}
""")
state.录制_脚本文本 = ""
self.save_ini(dir_, self.datas[state.录制_当前任务索引])
self.timer_luzhi.stop()
def timeout_luzhi_chuansong(self):
if state.录制_脚本文本 != "":
tangbaowss.send_msg( "是否禁止录制#@@#真")
state.状态_是否禁止录制 = True
dir_ = os.path.join(state.PATH_TASK, self.datas[state.录制_当前任务索引]["name"])
if not os.path.exists(dir_):
os.makedirs(dir_)
# 并且将jiaoben.ini文件也填入数据然后生成
path = dir_ + "/传送脚本.txt"
with open(path, "w", encoding="gbk", newline='') as f:
f.write(state.录制_脚本文本)
self.datas[state.录制_当前任务索引]["chuansong"] = "传送脚本.txt"
self.datas[state.录制_当前任务索引]["f_item"].bt_chuansong.setProperty("OK_chuansong", True)
logger.info(f"导入脚本成功:{path}")
self.sg.mysig_tishi.emit(f"导入脚本成功:{path}")
self.datas[state.录制_当前任务索引]["f_item"].bt_chuansong.setStyleSheet("""
#bt_chuansong[OK_chuansong="true"] {
color: rgb(237,182,43);
border-color: rgb(237,182,43);
}
""")
state.录制_脚本文本 = ""
self.save_ini(dir_, self.datas[state.录制_当前任务索引])
self.timer_luzhi_chuansong.stop()
def timeout_luzhi_lianzhao(self):
if state.录制_脚本文本 != "":
tangbaowss.send_msg( "是否禁止录制#@@#真")
state.状态_是否禁止录制 = True
dir_ = os.path.abspath(state.PATH_JIAOBEN)
if not os.path.exists(dir_):
os.makedirs(dir_)
# 并且将jiaoben.ini文件也填入数据然后生成
path = os.path.join(dir_, state.LIANZHAO)
with open(path, "w", encoding="gbk", newline='') as f:
f.write(state.录制_脚本文本)
state.录制_脚本文本 = ""
logger.info("录制并选择连招脚本成功!")
self.sg.mysig_tishi.emit("录制并选择连招脚本成功!")
self.save_ini_seting()
self.timer_luzhi_lianzhao.stop()
def timeout_huifang(self):
if state.状态_循环开关 == False:
state.状态_需重新传送 = False
tangbaowss.send_msg( "是否回放#@@#假")
logger.info("回放结束1")
self.sg.mysig_tishi.emit("回放结束1")
self.timer_huifang.stop()
return
if state.状态_是否回放中 == False:
logger.info("回放结束2")
self.sg.mysig_tishi.emit("回放结束2")
self.timer_huifang.stop()
def update_layout(self):
try:
# 获取主窗口的宽度
width =self.centralWidget().width()
# 计算每行可以容纳的组件数量
num_per_row = (width ) // (self.column_step * ratio) # 假设每个组件的宽度为200
if num_per_row < 1:
num_per_row = 1
# 清空当前布局
for i in reversed(range(self.g_box.count())):
self.g_box.itemAt(i).widget().setParent(None)
# 重新添加组件到网格布局
for i, data in enumerate(self.datas):
self.row = int(i // num_per_row)
self.column = int(i % num_per_row)
self.g_box.addWidget(data["f_item"], self.row, self.column)
except:
pass
def connect_set(self):
'''
绑定信号
:return:
'''
self.sg = MySignal()
state. QT_信号=self.sg
self.sg.mysig_shutdown.connect(self.show_shutdown_dig)
self.sg.mysig_mouse_through.connect(self.set_mouse_through)
self.sg.mysig_tishi.connect(self.set_tishi)
self.sg.mysig_next_pack.connect(self.next_pack)
self.sg.mysig_show_xunlu.connect(self.show_xunlu)
self.sg.mysig_show_yolov.connect(self.show_yolov)
self.sg.mysig_dingwei.connect(self.dingwei)
self.menu = self.menuBar()
# 创建一个顶级菜单
self.menu_file = self.menu.addMenu("文件")
# 创建一个动作
self.action_addtask = QAction("新增-AI锄地任务-大世界寻路打怪", self)
self.action_addtask.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_1))
self.action_addtask.triggered.connect(self.hotkey_addtask)
self.menu_file.addAction(self.action_addtask)
# 创建一个动作
self.action_addtaskfuben = QAction("新增-AI副本任务-任意副本", self)
self.action_addtaskfuben.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_2))
self.action_addtaskfuben.triggered.connect(self.hotkey_addtaskfuben)
self.menu_file.addAction(self.action_addtaskfuben)
# 创建一个动作
self.action_addtaskjiaoben = QAction("新增-脚本回放任务-适合 采花/挖矿/等等", self)
self.action_addtaskjiaoben.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_3))
self.action_addtaskjiaoben.triggered.connect(self.hotkey_addtaskjiaoben)
self.menu_file.addAction(self.action_addtaskjiaoben)
# 创建一个动作
self.action_qiejue = QAction("新增-切换角色任务", self)
self.action_qiejue.triggered.connect(self.hotkey_qiejue)
self.menu_file.addAction(self.action_qiejue)
# 创建一个动作
self.action_qiehuanlianzhao = QAction("新增-切换连招任务", self)
self.action_qiehuanlianzhao.triggered.connect(self.hotkey_qiehuanlianzhao)
self.menu_file.addAction(self.action_qiehuanlianzhao)
# 创建一个动作
self.action_importtask = QAction("导入单个任务", self)
self.action_importtask.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_4))
self.action_importtask.triggered.connect(self.hotkey_importtask)
self.menu_file.addAction(self.action_importtask)
self.action_opentaskdir = QAction("打开任务文件夹", self)
self.action_opentaskdir.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_5))
self.action_opentaskdir.triggered.connect(self.hotkey_opentaskdir)
self.menu_file.addAction(self.action_opentaskdir)
self.action_selecttaskdir = QAction("导入任务包", self)
self.action_selecttaskdir.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_6))
self.action_selecttaskdir.triggered.connect(self.hotkey_selecttaskdir)
self.menu_file.addAction(self.action_selecttaskdir)
self.action_setlianzhao = QAction("选择连招脚本", self)
self.action_setlianzhao.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_7))
self.action_setlianzhao.triggered.connect(self.hotkey_setlianzhao)
self.menu_file.addAction(self.action_setlianzhao)
self.action_addlianzhao = QAction("录制/编辑连招", self)
self.action_addlianzhao.triggered.connect(self.hotkey_addlianzhao)
self.menu_file.addAction(self.action_addlianzhao)
# 创建一个顶级菜单
self.menu_ck = self.menu.addMenu("选择")
# 创建一个动作
self.action_all_ck = QAction("全部选中", self)
self.action_all_ck.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_8))
self.action_all_ck.triggered.connect(self.hotkey_all_ck)
self.menu_ck.addAction(self.action_all_ck)
self.action_all_not_ck = QAction("全部不选", self)
self.action_all_not_ck.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_9))
self.action_all_not_ck.triggered.connect(self.hotkey_all_not_ck)
self.menu_ck.addAction(self.action_all_not_ck)
self.action_all_fan_ck = QAction("全部反选", self)
self.action_all_fan_ck.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_0))
self.action_all_fan_ck.triggered.connect(self.hotkey_all_fan_ck)
self.menu_ck.addAction(self.action_all_fan_ck)
self.action_keys_ack = QAction("选中包含某个关键词的", self)
self.action_keys_ack.triggered.connect(self.hotkey_keys_ack)
self.menu_ck.addAction(self.action_keys_ack)
self.action_num_ck = QAction("选中包含某个区间数字的", self)
self.action_num_ck.triggered.connect(self.hotkey_num_ck)
self.menu_ck.addAction(self.action_num_ck)
self.action_find = QAction("查找并定位到包含某个关键字的任务", self)
self.action_find.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_F))
self.action_find.triggered.connect(self.hotkey_find)
self.menu_ck.addAction(self.action_find)
# 创建一个顶级菜单
self.menu_run = self.menu.addMenu("操作")
# 创建一个动作
self.action_runall = QAction("启动选中任务", self)
self.action_runall.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_F1))
self.action_runall.triggered.connect(self.hotkey_runall)
self.menu_run.addAction(self.action_runall)
self.action_deltask = QAction("删除选中任务", self)
self.action_deltask.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_F2))
self.action_deltask.triggered.connect(self.hotkey_deltask)
self.menu_run.addAction(self.action_deltask)
self.action_refresh = QAction("保存任务并刷新顺序", self)
self.action_refresh.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_S))
self.action_refresh.triggered.connect(functools.partial(self.save,None))
self.menu_run.addAction(self.action_refresh)
# 创建一个动作
self.action_kuang = QAction("选中任务-是否勾选-矿", self)
self.action_kuang.setCheckable(True)
self.action_kuang.setChecked(False)
self.action_kuang.triggered.connect(self.hotkey_kuang)
self.action_kuang.setChecked(True)
self.menu_run.addAction(self.action_kuang)
# 创建一个动作
self.action_hua = QAction("选中任务-是否勾选-大地图", self)
self.action_hua.setCheckable(True)
self.action_hua.setChecked(False)
self.action_hua.triggered.connect(self.hotkey_hua)
self.action_hua.setChecked(True)
self.menu_run.addAction(self.action_hua)
# 创建一个动作
self.action_guai = QAction("选中任务-是否勾选-怪", self)
self.action_guai.setCheckable(True)
self.action_guai.setChecked(False)
self.action_guai.triggered.connect(self.hotkey_guai)
self.action_guai.setChecked(True)
self.menu_run.addAction(self.action_guai)
# 创建一个动作
self.action_run_times = QAction(f"设置:当前任务包 执行次数:{self.run_times}", self)
self.action_run_times.triggered.connect(self.hotkey_run_times)
self.menu_run.addAction(self.action_run_times)
# 创建一个顶级菜单
self.menu_view = self.menu.addMenu("视图")
# 创建一个动作
self.action_isShow = QAction("显示检测结果窗口", self)
self.action_isShow.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_F11))
self.action_isShow.triggered.connect(self.hotkey_isShow)
self.action_isShow.setCheckable(True)
self.action_isShow.setChecked(True)
self.menu_view.addAction(self.action_isShow)
self.hotkey_isShow()
# 创建一个顶级菜单
self.menu_yun= self.menu.addMenu("云端")
# 创建一个动作
self.action_yunduanlist= QAction("懒人群友云端资源", self)
self.action_yunduanlist.triggered.connect(self.hotkey_yunduanlist)
self.menu_yun.addAction(self.action_yunduanlist)
# 创建一个动作
self.action_yunduanup1 = QAction("分享-副本打怪任务", self)
self.action_yunduanup1.triggered.connect( lambda: webbrowser.open("https://nas.qizhiqiang.com:5001/sharing/WclV3JS7Q"))
self.menu_yun.addAction(self.action_yunduanup1)
self.action_yunduanup2 = QAction("分享-打怪锄地任务", self)
self.action_yunduanup2.triggered.connect(
lambda: webbrowser.open("https://nas.qizhiqiang.com:5001/sharing/bpYBwYjjc"))
self.menu_yun.addAction(self.action_yunduanup2)
self.action_yunduanup3 = QAction("分享-回放脚本任务", self)
self.action_yunduanup3.triggered.connect(
lambda: webbrowser.open("https://nas.qizhiqiang.com:5001/sharing/kBRWfAuxt"))
self.menu_yun.addAction(self.action_yunduanup3)
self.action_yunduanup4 = QAction("分享-收集材料任务", self)
self.action_yunduanup4.triggered.connect(
lambda: webbrowser.open("https://nas.qizhiqiang.com:5001/sharing/lHDHkv00G"))
self.menu_yun.addAction(self.action_yunduanup4)
self.action_yunduanup5 = QAction("分享-连招脚本任务", self)
self.action_yunduanup5.triggered.connect(
lambda: webbrowser.open("https://nas.qizhiqiang.com:5001/sharing/x4rmFtLsV"))
self.menu_yun.addAction(self.action_yunduanup5)
self.action_yunduanup6 = QAction("分享-其它资源分享", self)
self.action_yunduanup6.triggered.connect(
lambda: webbrowser.open("https://nas.qizhiqiang.com:5001/sharing/4SOeHNy6I"))
self.menu_yun.addAction(self.action_yunduanup6)
# 创建一个顶级菜单
self.menu_tools = self.menu.addMenu("工具")
# 创建一个动作
self.action_stitchimg = QAction("合成全景大图", self)
self.action_stitchimg.triggered.connect(self.hotkey_stitchimg)
self.menu_tools.addAction(self.action_stitchimg)
# 创建一个顶级菜单
self.menu_setting = self.menu.addMenu("设置")
# 创建一个动作
self.action_runstartwith = QAction("启动改为从这开始", self)
self.action_runstartwith.setCheckable(True)
self.action_runstartwith.setChecked(False)
self.menu_setting.addAction(self.action_runstartwith)
# 创建一个动作
self.action_nextpack = QAction("是否自动继续下一个任务包", self)
self.action_nextpack.setCheckable(True)
self.action_nextpack.setChecked(False)
self.action_nextpack.triggered.connect(self.hotkey_nextpack)
if state.ON_NEXTPACK == 0:
self.action_nextpack.setChecked(False)
else:
self.action_nextpack.setChecked(True)
self.menu_setting.addAction(self.action_nextpack)
# 创建一个动作
self.action_jixing = QAction("是否任务完成后领取电台奖励", self)
self.action_jixing.triggered.connect(self.hotkey_jixing)
self.action_jixing.setCheckable(True)
if state.ON_JIXING == 0:
self.action_jixing.setChecked(False)
else:
self.action_jixing.setChecked(True)
self.menu_setting.addAction(self.action_jixing)
# 创建一个动作
self.action_shutdown = QAction("是否任务完成后关机", self)
self.action_shutdown.triggered.connect(self.hotkey_shutdown)
self.action_shutdown.setCheckable(True)
if state.ON_SHUTDOWN == 0:
self.action_shutdown.setChecked(False)
else:
self.action_shutdown.setChecked(True)
self.menu_setting.addAction(self.action_shutdown)
self.action_lianzhaobujiance = QAction("是否强制把连招搓完", self)
self.action_lianzhaobujiance.triggered.connect(self.hotkey_lianzhaobujiance)
self.action_lianzhaobujiance.setCheckable(True)
if state.ON_LIANZHAOBUJIANCE == 0:
self.action_lianzhaobujiance.setChecked(False)
else:
self.action_lianzhaobujiance.setChecked(True)
self.menu_setting.addAction(self.action_lianzhaobujiance)
# 创建一个动作
self.action_timeout = QAction(f"设置打怪超时 阈值:{state.TIMEOUT_DAGUAI}秒", self)
self.action_timeout.triggered.connect(self.hotkey_timeout)
self.menu_setting.addAction(self.action_timeout)
# 创建一个顶级菜单
self.menu_help = self.menu.addMenu("帮助")
# 创建一个动作
self.action_about = QAction("关于", self)
self.action_about.triggered.connect(
lambda: QMessageBox.information(self, "作者", "python懒人智能 仅供技术研究!请勿用于非法用途否则后果自负!"))
self.menu_help.addAction(self.action_about)
# 创建一个动作
self.action_kaiyuan = QAction("开源地址", self)
self.action_kaiyuan.triggered.connect( lambda: webbrowser.open("https://gitee.com/LanRenZhiNeng/ming-chao-ai"))
self.menu_help.addAction(self.action_kaiyuan)
# 创建一个动作
self.action_zanzhu = QAction("赞助入群", self)
self.action_zanzhu.triggered.connect(
lambda: webbrowser.open("http://w.kami.vip/s/FSUtd45z"))
self.menu_help.addAction(self.action_zanzhu)
# 创建一个动作
self.action_jiaocheng = QAction("快速入门教程", self)
self.action_jiaocheng.triggered.connect(
lambda: webbrowser.open("https://www.bilibili.com/video/BV16E4m1R76J"))
self.menu_help.addAction(self.action_jiaocheng)
self.action_jiaocheng = QAction("高级教程", self)
self.action_jiaocheng.triggered.connect(
lambda: webbrowser.open("https://www.bilibili.com/video/BV1aS421w7i1"))
self.menu_help.addAction(self.action_jiaocheng)
# 创建右键弹出菜单
menu = QMenu(self)
menu.addAction(self.action_selecttaskdir)
# 将菜单关联到工具栏上
self.toolBar.setContextMenuPolicy(Qt.CustomContextMenu)
self.toolBar.customContextMenuRequested.connect(lambda pos: menu.exec_(self.toolBar.mapToGlobal(pos)))
def next_pack(self,old_task):
self.show_tool_item(state.PATH_TASK,old_task)
self.hotkey_runall()
def add_tool_item(self,dir_):
action_item = QWidgetAction(self)
dir_ = dir_.replace("/", "\\")
if dir_[-1]=="\\":
dir_=dir_[:-1]
bt_item = QPushButton(dir_.split("\\")[-1].strip(), self)
try:
with open(dir_+"/"+"使用说明.txt", "r", encoding="utf-8")as f:
txt=f.read()
except:
try:
with open(dir_+"/"+"使用说明.txt", "r", encoding="utf-8")as f:
txt=f.read()
except:
txt="无 \n(可以在任务包文件夹下创建一个 使用说明.txt 文件 来添加说明)"
bt_item.setToolTip(dir_+"\n使用说明:"+txt+"\n")
bt_item.setStyleSheet("border: none; padding: 3px;")
bt_item.clicked.connect(functools.partial(self.show_tool_item, dir_,None))
action_item.setDefaultWidget(bt_item)
self.toolBar.addAction(action_item)
menu = QMenu(self)
action_menu_down = QAction('顺序 ↓', self)
action_menu_down.triggered.connect(functools.partial(self.down_tool_item, len(self.toolBar.actions())))
menu.addAction(action_menu_down)
action_menu_up = QAction('顺序 ↑', self)
action_menu_up.triggered.connect(functools.partial(self.up_tool_item, len(self.toolBar.actions())))
menu.addAction(action_menu_up)
action_menu_del = QAction('删除任务包', self)
action_menu_del.triggered.connect(functools.partial(self.del_tool_item, action_item,bt_item,dir_))
menu.addAction(action_menu_del)
# 将菜单关联到工具栏上
bt_item.setContextMenuPolicy(Qt.CustomContextMenu)
bt_item.customContextMenuRequested.connect(lambda pos: menu.exec_(bt_item.mapToGlobal(pos)))
self.change_tool_show_style( dir_)
def show_tool_item(self,dir_,old_task=None):
self.save(old_task=old_task)
state.PATH_TASK = dir_
self.save_ini_seting()
self.update_tasks()
self.change_tool_show_style(dir_)
logger.info(f"成功设置{state.PATH_TASK}为当前任务文件夹")
def del_tool_item(self,action_item,bt_item,dir_):
self.toolBar.removeAction(action_item)
if state.PATH_TASK.replace("/", "\\") == dir_:
self.datas = []
self.row = 0
self.column = -1
# 清空当前布局
for i in reversed(range(self.g_box.count())):
self.g_box.itemAt(i).widget().setParent(None)
del bt_item,action_item # 删除动作对象和bt对象
txt_=""
packs = state.PACKS_TASK.split("#@@#")
if len(packs) >= 1:
for pack in packs:
if os.path.realpath(dir_)!=os.path.realpath(pack) and pack!="":
txt_=txt_+pack+"#@@#"
state.PACKS_TASK=txt_
logger.info(f"成功移除{dir_}任务包")
def down_tool_item(self,idex):
task_list=state.PACKS_TASK.split("#@@#")
if idex < len(task_list)-1:
# 将指定索引位置的成员与其前一个成员交换位置
task_list[idex], task_list[idex + 1] = task_list[idex + 1], task_list[idex]
state.PACKS_TASK=""
for item in task_list:
if item!="":
state.PACKS_TASK +="#@@#" + item
self.load_task_packs()
def up_tool_item(self,idex):
task_list = state.PACKS_TASK.split("#@@#")
if idex > 0 :
# 将指定索引位置的成员与其后一个成员交换位置
task_list[idex], task_list[idex - 1] = task_list[idex - 1], task_list[idex]
state.PACKS_TASK = ""
for item in task_list:
if item != "":
state.PACKS_TASK += "#@@#" + item
self.load_task_packs()
def change_tool_show_style(self,dir_):
# 获取工具栏上的所有动作
actions_list = self.toolBar.actions()
# 遍历处理每个动作
for action in actions_list:
# 在这里对每个动作进行处理
bt_item = action.defaultWidget()
if dir_ == bt_item.toolTip().replace("/", "\\").split("\n")[0]:
bt_item.setStyleSheet("border-width: 1px; padding: 3px;")
else:
bt_item.setStyleSheet("border: none; padding: 3px;")
def get_next_task(self):
# 获取工具栏上的所有动作
actions_list = self.toolBar.actions()
length=len(actions_list)
if length<=0:
return None
# 遍历处理每个动作
idex=0
for i,action in enumerate(actions_list) :
# 在这里对每个动作进行处理
bt_item = action.defaultWidget()
if state.PATH_TASK == bt_item.toolTip().replace("/", "\\").split("\n")[0]:
idex=i
break
# 如果
if idex<length-1:
bt_item = actions_list[idex+1].defaultWidget()
return bt_item.toolTip().replace("/", "\\").split("\n")[0]
else:
return None
def set_tishi(self, txt):
self.statusbar.showMessage(txt)
if state.开关_是否展预测结果:
self.fromshow.setWindowTitle(txt)
def show_xunlu(self):
if state.开关_是否展预测结果:
if type(state.图片_找图) == bool:
return
# 加载大图
big_img_bk = state.图片_找图
# 将OpenCV图像转换为Qt中的QImage
height, width, channel = big_img_bk.shape
bytesPerLine = 3 * width
qImg = QImage(big_img_bk.data, width, height, bytesPerLine, QImage.Format_BGR888)
pixmap = QPixmap.fromImage(qImg)
self.fromshow.lb_xunlu.setPixmap(pixmap)
# 设置宽度固定,高度自适应
self.fromshow.window_width = int(self.fromshow.window_height * pixmap.width() / pixmap.height())
self.fromshow.lb_xunlu.setFixedHeight(self.fromshow.window_height)
self.fromshow.lb_xunlu.setFixedWidth(self.fromshow.window_width)
self.fromshow.lb_xunlu.setScaledContents(True)
def show_yolov(self):
if state.开关_是否展预测结果:
if type(state.图片_YOLOV) == bool:
return
img1 = QImage(state.图片_YOLOV.data, state.图片_YOLOV.shape[1], state.图片_YOLOV.shape[0],
QImage.Format_BGR888)
pixmap1 = QPixmap.fromImage(img1)
if self.fromshow.width()>=self.fromshow.lb_yolov.width()+self.fromshow.lb_xunlu.width():
self.fromshow.lb_yolov.move(self.fromshow.lb_xunlu.width(), 0)
else:
self.fromshow.lb_yolov.move(0, self.fromshow.lb_xunlu.height())
self.fromshow.lb_yolov.setPixmap(pixmap1)
def dingwei(self,idex):
try:
#展开
#self.datas[idex]["f_item"].is_zd = False
#self.datas[idex]["f_item"].mousePressEvent(None)
self.v_scrollbar.setValue(self.datas[idex]["f_item"].y())
except Exception as err:
print("dingwei",err)
pass
def set_mouse_through(self, bool):
set_mouse_through(int(self.winId()), bool)
if bool:
self.setWindowOpacity(0.9)
else:
self.setWindowOpacity(1)
def show_shutdown_dig(self):
self.dialog = ShutdownConfirmationDialog(self)
self.dialog.show()
def set_ui(self):
# 设置主题样式为 Flatwhite
# 创建 QtitanRibbon 实例
from qt_material import apply_stylesheet
apply_stylesheet(app, theme='dark_red.xml')
self.setStyleSheet("""
QScrollBar::handle:horizontal {
background-color: #A50F2C; /* 设置滑块颜色 */
}
QScrollBar::handle:horizontal:hover{
background-color: #FF1744; /* 设置滑块颜色 */
}
QPushButton:hover{
background-color: #DFC472; /* 设置颜色 */
}
QPlainTextEdit{padding: 0px;margin: 0px;}
QPushButton{padding: 0px;margin: 1px;}
"""+"font-family: {}; font-size: {}pt;".format(font.family(), font.pointSize()))
def tanChu_img(self, imgpath):
'''
弹出图片
:param imgpath:
:return:
'''
# ----------------------
try:
return f'''<img src='{imgpath}' > '''
except Exception as err:
return str(err)
def add_task(self, dir_, config):
'''
添加任务
:return:
'''
# 根据导入的文件
# 获取主窗口的宽度
width = self.centralWidget().width()
# 计算每行可以容纳的组件数量
num_per_row = (width ) // (self.column_step * ratio) # 假设每个组件的宽度为200
if num_per_row < 1:
num_per_row = 1
if num_per_row < 1:
num_per_row = 1
self.column += 1
if self.column == num_per_row:
self.column = 0
self.row += 1
# 加载ini配置文件
f_item = FrameItem()
f_item.setObjectName("frame_cont")
f_item.raise_()
f_item.setStyleSheet("""
#frame_cont:hover {
border: 1px solid red;
}
#frame_cont {
background-color: rgba(0, 0, 0, 0);
}
""")
d = {}
dir_ = dir_.replace("/", "\\")
if dir_[-1]=="\\":
dir_=dir_[:-1]
d["type"] = "1"
try:
config.set('seting', 'name', dir_.split("\\")[-1].strip())
except:
# 添加一个名为 'seting' 的配置节
config.add_section('seting')
config.set('seting', 'name', dir_.split("\\")[-1].strip())
d["name"] = config.get('seting', 'name', fallback=dir_.split("\\")[-1]).strip()
d["map"] = config.get('seting', 'map', fallback='')
d["lujing"] = config.get('seting', 'lujing', fallback='')
d["chuansong"] = config.get('seting', 'chuansong', fallback='')
d["chuansongmoban"] = config.get('seting', 'chuansongmoban', fallback='')
d["maodianmoban"] = config.get('seting', 'maodianmoban', fallback='')
d["cb_is_checked"] = config.get('seting', 'cb_is_checked', fallback='True')
d["cb_wakuang"] = config.get('seting', 'cb_wakuang', fallback='False')
d["cb_daditu"] = config.get('seting', 'cb_daditu', fallback='False')
d["cb_daguai"] = config.get('seting', 'cb_daguai', fallback='True')
f_item.bt_map.setProperty("OK_map", d["map"] != "")
f_item.bt_lujing.setProperty("OK_lujing", d["lujing"] != "")
f_item.bt_chuansong.setProperty("OK_chuansong", d["chuansong"] != "")
f_item.bt_moban.setProperty("OK_chuansongmoban", d["chuansongmoban"] != "")
f_item.bt_moban_maodian.setProperty("OK_maodianmoban", d["maodianmoban"] != "")
f_item.bt_map.setObjectName("bt_map")
f_item.bt_lujing.setObjectName("bt_lujing")
f_item.bt_chuansong.setObjectName("bt_chuansong")
f_item.bt_moban.setObjectName("bt_moban")
f_item.bt_moban_maodian.setObjectName("bt_moban_maodian")
f_item.led_name.setText(d["name"])
f_item.bt_map.setStyleSheet("""
#bt_map[OK_map="true"] {
color: rgb(237,182,43); /* 边框颜色为灰色 */
border-color: rgb(237,182,43); /* 边框颜色为灰色 */
}
""")
f_item.bt_lujing.setStyleSheet("""
#bt_lujing[OK_lujing="true"] {
color: rgb(237,182,43);
border-color: rgb(237,182,43);
}
""")
f_item.bt_chuansong.setStyleSheet("""
#bt_chuansong[OK_chuansong="true"] {
color: rgb(237,182,43);
border-color: rgb(237,182,43);
}
""")
f_item.bt_moban.setStyleSheet("""
#bt_moban[OK_chuansongmoban="true"] {
color: rgb(237,182,43);
border-color: rgb(237,182,43);
}
""")
f_item.bt_moban_maodian.setStyleSheet("""
#bt_moban_maodian[OK_maodianmoban="true"] {
color: rgb(237,182,43);
border-color: rgb(237,182,43);
}
""")
if d["cb_is_checked"] == "True":
f_item.cb_is_checked.setChecked(True)
else:
f_item.cb_is_checked.setChecked(False)
if d["cb_wakuang"] == "True":
f_item.cb_wakuang.setChecked(True)
else:
f_item.cb_wakuang.setChecked(False)
if d["cb_daditu"] == "True":
f_item.cb_daditu.setChecked(True)
else:
f_item.cb_daditu.setChecked(False)
if d["cb_daguai"] == "True":
f_item.cb_daguai.setChecked(True)
else:
f_item.cb_daguai.setChecked(False)
idex = len(self.datas)
#f_item.led_name.editingFinished.connect(self.save)
f_item.bt_map.clicked.connect(functools.partial(self.clickd_bt_map, idex))
f_item.bt_lujing.clicked.connect(functools.partial(self.clickd_bt_lujing, idex))
f_item.bt_chuansong.clicked.connect(functools.partial(self.clickd_bt_chuansong, idex))
f_item.bt_moban.clicked.connect(functools.partial(self.clickd_bt_moban, idex))
f_item.bt_moban_maodian.clicked.connect(functools.partial(self.clickd_bt_moban_maodian, idex))
f_item.bt_start.clicked.connect(functools.partial(self.clickd_bt_start, idex))
f_item.bt_del.clicked.connect(functools.partial(self.clickd_bt_del, idex))
f_item.bt_map.setVisible(False)
f_item.bt_lujing.setVisible(False)
f_item.bt_chuansong.setVisible(False)
f_item.bt_moban.setVisible(False)
f_item.bt_moban_maodian.setVisible(False)
f_item.bt_start.setVisible(False)
f_item.bt_del.setVisible(False)
f_item.cb_wakuang.setVisible(False)
f_item.cb_daditu.setVisible(False)
f_item.cb_daguai.setVisible(False)
f_item.bt_map.setToolTip(self.tanChu_img(dir_ + "/" + d["map"]))
f_item.bt_lujing.setToolTip(self.tanChu_img(dir_ + "/" + d["lujing"]))
f_item.bt_moban.setToolTip(self.tanChu_img(dir_ + "/" + d["chuansongmoban"]))
f_item.bt_moban_maodian.setToolTip(self.tanChu_img(dir_ + "/" + d["maodianmoban"]))
d["f_item"] = f_item
self.datas.append(d)
self.g_box.addWidget(f_item, self.row, self.column)
def add_taskfuben(self, dir_, config):
'''
添加任务
:return:
'''
# 根据导入的文件
# 获取主窗口的宽度
width = self.centralWidget().width()
# 计算每行可以容纳的组件数量
num_per_row = (width) // (self.column_step * ratio) # 假设每个组件的宽度为200
if num_per_row < 1:
num_per_row = 1
if num_per_row < 1:
num_per_row = 1
self.column += 1
if self.column == num_per_row:
self.column = 0
self.row += 1
f_item = FrameItemFuBen()
f_item.setObjectName("frame_cont")
f_item.raise_()
f_item.setStyleSheet("""
#frame_cont:hover {
border: 1px solid red;
}
#frame_cont {
background-color: rgba(0, 0, 0, 0);
}
""")
d = {}
d["type"] = "2"
dir_ = dir_.replace("/", "\\")
if dir_[-1]=="\\":
dir_=dir_[:-1]
try:
config.set('seting', 'name', dir_.split("\\")[-1].strip())
except:
# 添加一个名为 'seting' 的配置节
config.add_section('seting')
config.set('seting', 'name', dir_.split("\\")[-1].strip())
d["name"] = config.get('seting', 'name', fallback=dir_.split("\\")[-1]).strip()
d["cbb_level"] = int(config.get('seting', 'cbb_level', fallback='0'))
d["cb_lingjiang"] = config.get('seting', 'cb_lingjiang', fallback='True')
d["led_cishu"] = config.get('seting', 'led_cishu', fallback='99')
d["chuansong"] = config.get('seting', 'chuansong', fallback='')
d["chuansongmoban"] = config.get('seting', 'chuansongmoban', fallback='')
d["maodianmoban"] = config.get('seting', 'maodianmoban', fallback='')
d["cb_is_checked"] = config.get('seting', 'cb_is_checked', fallback='True')
f_item.bt_chuansong.setProperty("OK_chuansong", d["chuansong"] != "")
f_item.bt_moban.setProperty("OK_chuansongmoban", d["chuansongmoban"] != "")
f_item.bt_moban_maodian.setProperty("OK_maodianmoban", d["maodianmoban"] != "")
f_item.bt_chuansong.setObjectName("bt_chuansong")
f_item.bt_moban.setObjectName("bt_moban")
f_item.bt_moban_maodian.setObjectName("bt_moban_maodian")
f_item.led_name.setText(d["name"])
f_item.led_cishu.setText(d["led_cishu"])
f_item.bt_chuansong.setStyleSheet("""
#bt_chuansong[OK_chuansong="true"] {
color: rgb(237,182,43);
border-color: rgb(237,182,43);
}
""")
f_item.bt_moban.setStyleSheet("""
#bt_moban[OK_chuansongmoban="true"] {
color: rgb(237,182,43);
border-color: rgb(237,182,43);
}
""")
f_item.bt_moban_maodian.setStyleSheet("""
#bt_moban_maodian[OK_maodianmoban="true"] {
color: rgb(237,182,43);
border-color: rgb(237,182,43);
}
""")
f_item.cbb_level.setCurrentIndex(d["cbb_level"])
if d["cb_is_checked"] == "True":
f_item.cb_is_checked.setChecked(True)
else:
f_item.cb_is_checked.setChecked(False)
if d["cb_lingjiang"] == "True":
f_item.cb_lingjiang.setChecked(True)
else:
f_item.cb_lingjiang.setChecked(False)
idex = len(self.datas)
#f_item.led_name.editingFinished .connect(self.save)
f_item.bt_chuansong.clicked.connect(functools.partial(self.clickd_bt_chuansong, idex))
f_item.bt_moban.clicked.connect(functools.partial(self.clickd_bt_moban, idex))
f_item.bt_moban_maodian.clicked.connect(functools.partial(self.clickd_bt_moban_maodian, idex))
f_item.bt_start.clicked.connect(functools.partial(self.clickd_bt_start, idex))
f_item.bt_del.clicked.connect(functools.partial(self.clickd_bt_del, idex))
f_item.bt_chuansong.setVisible(False)
f_item.bt_moban.setVisible(False)
f_item.bt_moban_maodian.setVisible(False)
f_item.bt_start.setVisible(False)
f_item.bt_del.setVisible(False)
f_item.cbb_level.setVisible(False)
f_item.cb_lingjiang.setVisible(False)
f_item.led_cishu.setVisible(False)
f_item.label.setVisible(False)
f_item.bt_moban.setToolTip(self.tanChu_img(dir_ + "/" +d["chuansongmoban"]))
f_item.bt_moban_maodian.setToolTip(self.tanChu_img(dir_ + "/" +d["maodianmoban"] ))
d["f_item"] = f_item
self.datas.append(d)
self.g_box.addWidget(f_item, self.row, self.column)
def add_taskjiaoben(self, dir_, config):
'''
添加脚本任务
:return:
'''
# 根据导入的文件
# 获取主窗口的宽度
width = self.centralWidget().width()
# 计算每行可以容纳的组件数量
num_per_row = (width ) // (self.column_step * ratio) # 假设每个组件的宽度为200
if num_per_row < 1:
num_per_row = 1
if num_per_row < 1:
num_per_row = 1
self.column += 1
if self.column == num_per_row:
self.column = 0
self.row += 1
# 加载ini配置文件
f_item = FrameItemJiaoBen()
f_item.setObjectName("frame_cont")
f_item.raise_()
f_item.setStyleSheet("""
#frame_cont:hover {
border: 1px solid red;
}
#frame_cont {
background-color: rgba(0, 0, 0, 0);
}
""")
d = {}
d["type"] = "3"
dir_ = dir_.replace("/", "\\")
if dir_[-1]=="\\":
dir_=dir_[:-1]
try:
config.set('seting', 'name', dir_.split("\\")[-1].strip())
except:
# 添加一个名为 'seting' 的配置节
config.add_section('seting')
config.set('seting', 'name', dir_.split("\\")[-1].strip())
d["name"] = config.get('seting', 'name', fallback=dir_.split("\\")[-1]).strip()
d["cb_auto_f"] = config.get('seting', 'cb_auto_f', fallback='True')
d["chuansong"] = config.get('seting', 'chuansong', fallback='')
d["jiaoben"] = config.get('seting', 'jiaoben', fallback='')
d["chuansongmoban"] = config.get('seting', 'chuansongmoban', fallback='')
d["maodianmoban"] = config.get('seting', 'maodianmoban', fallback='')
d["cb_is_checked"] = config.get('seting', 'cb_is_checked', fallback='True')
f_item.bt_chuansong.setProperty("OK_chuansong", d["chuansong"] != "")
f_item.bt_jiaoben.setProperty("OK_jiaoben", d["jiaoben"] != "")
f_item.bt_moban.setProperty("OK_chuansongmoban", d["chuansongmoban"] != "")
f_item.bt_moban_maodian.setProperty("OK_maodianmoban", d["maodianmoban"] != "")
f_item.bt_chuansong.setObjectName("bt_chuansong")
f_item.bt_moban.setObjectName("bt_moban")
f_item.bt_moban_maodian.setObjectName("bt_moban_maodian")
f_item.led_name.setText(d["name"])
f_item.bt_jiaoben.setStyleSheet("""
#bt_jiaoben[OK_jiaoben="true"] {
color: rgb(237,182,43);
border-color: rgb(237,182,43);
}
""")
f_item.bt_chuansong.setStyleSheet("""
#bt_chuansong[OK_chuansong="true"] {
color: rgb(237,182,43);
border-color: rgb(237,182,43);
}
""")
f_item.bt_moban.setStyleSheet("""
#bt_moban[OK_chuansongmoban="true"] {
color: rgb(237,182,43);
border-color: rgb(237,182,43);
}
""")
f_item.bt_moban_maodian.setStyleSheet("""
#bt_moban_maodian[OK_maodianmoban="true"] {
color: rgb(237,182,43);
border-color: rgb(237,182,43);
}
""")
if d["cb_is_checked"] == "True":
f_item.cb_is_checked.setChecked(True)
else:
f_item.cb_is_checked.setChecked(False)
if d["cb_auto_f"] == "True":
f_item.cb_auto_f.setChecked(True)
else:
f_item.cb_auto_f.setChecked(False)
idex = len(self.datas)
f_item.bt_jiaoben.clicked.connect(functools.partial(self.clickd_bt_jiaoben, idex))
f_item.bt_chuansong.clicked.connect(functools.partial(self.clickd_bt_chuansong, idex))
f_item.bt_moban.clicked.connect(functools.partial(self.clickd_bt_moban, idex))
f_item.bt_moban_maodian.clicked.connect(functools.partial(self.clickd_bt_moban_maodian, idex))
f_item.bt_start.clicked.connect(functools.partial(self.clickd_bt_start, idex))
f_item.bt_del.clicked.connect(functools.partial(self.clickd_bt_del, idex))
d["f_item"] = f_item
f_item.bt_start.setVisible(False)
f_item.bt_jiaoben.setVisible(False)
f_item.bt_chuansong.setVisible(False)
f_item.bt_moban_maodian.setVisible(False)
f_item.bt_moban.setVisible(False)
f_item.bt_start.setVisible(False)
f_item.bt_del.setVisible(False)
f_item.cb_auto_f.setVisible(False)
f_item.bt_moban.setToolTip(self.tanChu_img(dir_ + "/" + d["chuansongmoban"]))
f_item.bt_moban_maodian.setToolTip(self.tanChu_img(dir_ + "/" + d["maodianmoban"]))
self.datas.append(d)
self.g_box.addWidget(f_item, self.row, self.column)
def add_xuanjue(self, dir_, config):
'''
添加脚本任务
:return:
'''
# 根据导入的文件
# 获取主窗口的宽度
width = self.centralWidget().width()
# 计算每行可以容纳的组件数量
num_per_row = (width) // (self.column_step * ratio) # 假设每个组件的宽度为200
if num_per_row < 1:
num_per_row = 1
if num_per_row < 1:
num_per_row = 1
self.column += 1
if self.column == num_per_row:
self.column = 0
self.row += 1
# 加载ini配置文件
f_item = FrameItemXuanJue()
f_item.setObjectName("frame_cont")
f_item.raise_()
f_item.setStyleSheet("""
#frame_cont:hover {
border: 1px solid red;
}
#frame_cont {
background-color: rgba(0, 0, 0, 0);
}
""")
d = {}
d["type"] = "4"
dir_ = dir_.replace("/", "\\")
if dir_[-1] == "\\":
dir_ = dir_[:-1]
try:
config.set('seting', 'name', dir_.split("\\")[-1].strip())
except:
# 添加一个名为 'seting' 的配置节
config.add_section('seting')
config.set('seting', 'name', dir_.split("\\")[-1].strip())
d["name"] = config.get('seting', 'name', fallback=dir_.split("\\")[-1]).strip()
d["chuansong"] =''
d["cb_is_checked"] = config.get('seting', 'cb_is_checked', fallback='True')
d["cbb_1"] = config.get('seting', 'cbb_1', fallback='漂泊者男')
d["cbb_2"] = config.get('seting', 'cbb_2', fallback='秧秧')
d["cbb_3"] = config.get('seting', 'cbb_3', fallback='白芷')
d["led_main"] = config.get('seting', 'led_main', fallback='1')
if d["cb_is_checked"] == "True":
f_item.cb_is_checked.setChecked(True)
else:
f_item.cb_is_checked.setChecked(False)
idex = len(self.datas)
f_item.bt_start.clicked.connect(functools.partial(self.clickd_bt_start, idex))
f_item.bt_del.clicked.connect(functools.partial(self.clickd_bt_del, idex))
f_item.led_main.setText(d["led_main"])
f_item.led_name.setText(d["name"])
self.set_cbb_items(f_item.cbb_1)
self.set_cbb_items(f_item.cbb_2)
self.set_cbb_items(f_item.cbb_3)
self.set_cbb_item(f_item.cbb_1, d["cbb_1"])
self.set_cbb_item(f_item.cbb_2, d["cbb_2"])
self.set_cbb_item(f_item.cbb_3, d["cbb_3"])
f_item.cbb_1.setVisible(False)
f_item.cbb_2.setVisible(False)
f_item.cbb_3.setVisible(False)
f_item.lb_zhanchang.setVisible(False)
f_item.led_main.setVisible(False)
f_item.bt_del.setVisible(False)
f_item.bt_start.setVisible(False)
d["f_item"] = f_item
self.datas.append(d)
self.g_box.addWidget(f_item, self.row, self.column)
def add_xuanlianzhao(self, dir_, config):
'''
添加脚本任务
:return:
'''
# 根据导入的文件
# 获取主窗口的宽度
width = self.centralWidget().width()
# 计算每行可以容纳的组件数量
num_per_row = (width) // (self.column_step * ratio) # 假设每个组件的宽度为200
if num_per_row < 1:
num_per_row = 1
if num_per_row < 1:
num_per_row = 1
self.column += 1
if self.column == num_per_row:
self.column = 0
self.row += 1
# 加载ini配置文件
f_item = FrameItemLianZhao()
f_item.setObjectName("frame_cont")
f_item.raise_()
f_item.setStyleSheet("""
#frame_cont:hover {
border: 1px solid red;
}
#frame_cont {
background-color: rgba(0, 0, 0, 0);
}
""")
d = {}
d["type"] = "5"
dir_ = dir_.replace("/", "\\")
if dir_[-1] == "\\":
dir_ = dir_[:-1]
try:
config.set('seting', 'name', dir_.split("\\")[-1].strip())
except:
# 添加一个名为 'seting' 的配置节
config.add_section('seting')
config.set('seting', 'name', dir_.split("\\")[-1].strip())
d["name"] = config.get('seting', 'name', fallback=dir_.split("\\")[-1]).strip()
d["chuansong"] = ''
d["cb_is_checked"] = config.get('seting', 'cb_is_checked', fallback='True')
d["cbb_lianzhao"] = config.get('seting', 'cbb_lianzhao', fallback='')
if d["cb_is_checked"] == "True":
f_item.cb_is_checked.setChecked(True)
else:
f_item.cb_is_checked.setChecked(False)
idex = len(self.datas)
f_item.bt_start.clicked.connect(functools.partial(self.clickd_bt_start, idex))
f_item.bt_del.clicked.connect(functools.partial(self.clickd_bt_del, idex))
folder_path = state.PATH_JIAOBEN
f_item.led_name.setText(d["name"])
# 遍历文件夹及其子文件夹中的所有文件
for root, dirs, files in os.walk(folder_path):
for file in files:
# 检查文件扩展名是否为.png
if file.endswith('.txt'):
# 打印PNG文件的完整路径
file_name = os.path.splitext(file)[0]
f_item.cbb_lianzhao.addItem(file_name)
f_item.cbb_lianzhao.setCurrentText(d["cbb_lianzhao"] )
f_item.bt_start.setVisible(False)
f_item.cbb_lianzhao.setVisible(False)
f_item.bt_del.setVisible(False)
d["f_item"] = f_item
self.datas.append(d)
self.g_box.addWidget(f_item, self.row, self.column)
def returnPressed_name(self, idex):
try:
if self.datas[idex]["f_item"].led_name.text() == self.datas[idex]["name"]:
return
dir_ = os.path.join(state.PATH_TASK, self.datas[idex]["f_item"].led_name.text()).strip()
if self.datas[idex]["name"] != "":
dir_old = os.path.join(state.PATH_TASK, self.datas[idex]["name"])
if not os.path.exists(dir_old):
dir_old = None
else:
dir_old = None
if not os.path.exists(dir_):
if dir_old != None:
try:
os.rename(dir_old, dir_)
self.datas[idex]["name"] = self.datas[idex]["f_item"].led_name.text()
logger.info(f'重命名成功{self.datas[idex]["name"]}')
except:
QMessageBox.information(self, "提示", "重命名失败!请检查是不是有特殊符号或者文件夹已经存在了")
self.datas[idex]["f_item"].led_name.setText(self.datas[idex]["name"])
else:
try:
os.makedirs(dir_)
self.datas[idex]["name"] = self.datas[idex]["f_item"].led_name.text()
logger.info(f'重命名成功{self.datas[idex]["name"]}')
except:
QMessageBox.information(self, "提示", "重命名失败!请检查是不是有特殊符号或者文件夹已经存在了")
self.datas[idex]["f_item"].led_name.setText(self.datas[idex]["name"])
except Exception as err:
QMessageBox.information(self, "提示", "重命名失败!"+str(err))
self.datas[idex]["f_item"].led_name.setText(self.datas[idex]["name"])
def clickd_bt_map(self, idex):
try:
temp_path, ok = QFileDialog.getOpenFileName(self, "选择地图", "", "图片文件 (*.png)")
if ok:
dir_ = os.path.join(state.PATH_TASK, self.datas[idex]["name"])
if not os.path.exists(dir_):
os.makedirs(dir_)
# 并且将jiaoben.ini文件也填入数据然后生成
# 将图片复制到指定目录
path = dir_ + "/地图.png"
shutil.copy(temp_path, path)
self.datas[idex]["map"] = "地图.png"
self.datas[idex]["f_item"].bt_map.setProperty("OK_map", True)
self.datas[idex]["f_item"].bt_map.setStyleSheet("""
#bt_map[OK_map="true"] {
color: rgb(237,182,43); /* 边框颜色为灰色 */
border-color: rgb(237,182,43); /* 边框颜色为灰色 */
}
""")
logger.info(f"导入地图成功:{path}")
self.save_ini(dir_, self.datas[idex])
except Exception as err:
logger.info(f"导入地图失败:{path}\n失败原因:{err}")
def clickd_bt_jiaoben(self, idex):
# 弹出一个选择弹窗 选项为 录制还是文件中选择
msgBox = QMessageBox(self)
msgBox.setWindowTitle("请选择一个配置方式") # 设置消息框标题
msgBox.setIcon(QMessageBox.Information)
msgBox.setText("技巧:尽量少用鼠标转动镜头\n可以用键盘方向键配合鼠标中键进行转向")
msgBox.addButton("录制", QMessageBox.AcceptRole)
msgBox.addButton("回放", QMessageBox.ApplyRole)
msgBox.addButton("文件中选择", QMessageBox.RejectRole)
result = msgBox.exec_()
if result == QMessageBox.AcceptRole:
logger.info("可以开始录制了,按F8开始/停止")
self.sg.mysig_tishi.emit("可以开始录制了,按F8开始/停止")
state.状态_是否禁止录制 = False
state.状态_是否开始录制 = False
state.录制_当前任务索引 = idex
state.录制_脚本文本 = ""
state.录制_当前脚本名 = self.datas[idex]["name"]
tangbaowss.send_msg( "是否禁止录制#@@#假")
tangbaowss.send_msg( "是否开始录制#@@#假")
tangbaowss.send_msg( f"全局脚本名#@@#{state.录制_当前脚本名}")
hwnd = win32gui.FindWindow("UnityWndClass", state.GAME_TITLE) # 替换成你实际的窗口句柄
tangbaowss.send_msg( f"全局hwnd#@@#{hwnd}")
self.timer_luzhi.start(200)
elif result == QMessageBox.RejectRole:
if state.状态_是否回放中 == True:
return
dir_ = os.path.join(state.PATH_TASK, self.datas[idex]["name"])
if not os.path.exists(dir_):
os.makedirs(dir_)
state.状态_是否回放中 = True
state.状态_循环开关 = True
jiaoben = os.path.abspath(os.path.join(dir_, self.datas[idex]["jiaoben"]))
message = f"解析脚本#@@#{jiaoben}"
tangbaowss.send_msg( message)
hwnd = win32gui.FindWindow("UnityWndClass", state.GAME_TITLE) # 替换成你实际的窗口句柄
set_window_activate(hwnd)
tangbaowss.send_msg( "脚本执行#@@#1")
self.timer_huifang.start(200)
elif result == QMessageBox.Warning:
# 弹出一个有分组框的窗口
temp_path, ok = QFileDialog.getOpenFileName(self, "脚本", "", "脚本文件 (*.txt)")
if ok:
dir_ = os.path.join(state.PATH_TASK, self.datas[idex]["name"])
if not os.path.exists(dir_):
os.makedirs(dir_)
# 并且将jiaoben.ini文件也填入数据然后生成
path = dir_ + "/脚本.txt"
shutil.copy(temp_path, path)
self.datas[idex]["jiaoben"] = "脚本.txt"
self.datas[idex]["f_item"].bt_jiaoben.setProperty("OK_jiaoben", True)
logger.info(f"导入脚本成功:{path}")
self.sg.mysig_tishi.emit(f"导入脚本成功:{path}")
self.datas[idex]["f_item"].bt_jiaoben.setStyleSheet("""
#bt_jiaoben[OK_jiaoben="true"] {
color: rgb(237,182,43);
border-color: rgb(237,182,43);
}
""")
self.save_ini(dir_, self.datas[idex])
def clickd_bt_chuansong(self, idex):
# 弹出一个选择弹窗 选项为 录制还是文件中选择
msgBox = QMessageBox(self)
msgBox.setWindowTitle("设置传送脚本") # 设置消息框标题
msgBox.setIcon(QMessageBox.Information)
msgBox.setText("请选择一个配置方式")
msgBox.addButton("录制", QMessageBox.AcceptRole)
msgBox.addButton("回放", QMessageBox.ApplyRole)
msgBox.addButton("文件中选择", QMessageBox.RejectRole)
result = msgBox.exec_()
if result == QMessageBox.AcceptRole:
logger.info("可以开始录制了,按F8开始/停止")
self.sg.mysig_tishi.emit("可以开始录制了,按F8开始/停止")
state.状态_是否禁止录制 = False
state.状态_是否开始录制 = False
state.录制_当前任务索引 = idex
state.录制_脚本文本 = ""
state.录制_当前脚本名 = self.datas[idex]["name"]
tangbaowss.send_msg( "是否开始录制#@@#假")
tangbaowss.send_msg( "是否禁止录制#@@#假")
tangbaowss.send_msg( f"全局脚本名#@@#传送-{state.录制_当前脚本名}")
hwnd = win32gui.FindWindow("UnityWndClass", state.GAME_TITLE) # 替换成你实际的窗口句柄
tangbaowss.send_msg( f"全局hwnd#@@#{hwnd}")
self.timer_luzhi_chuansong.start(200)
elif result == QMessageBox.RejectRole:
if state.状态_是否回放中 == True:
return
dir_ = os.path.join(state.PATH_TASK, self.datas[idex]["name"])
if not os.path.exists(dir_):
os.makedirs(dir_)
logger.info("回放脚本中! 按F9停止")
self.sg.mysig_tishi.emit("回放脚本中! 按F9停止")
state.状态_循环开关 = True
state.状态_是否回放中 = True
jiaoben = os.path.abspath(os.path.join(dir_, self.datas[idex]["chuansong"]))
message = f"解析脚本#@@#{jiaoben}"
tangbaowss.send_msg( message)
hwnd = win32gui.FindWindow("UnityWndClass", state.GAME_TITLE) # 替换成你实际的窗口句柄
set_window_activate(hwnd)
tangbaowss.send_msg( "脚本执行#@@#1")
self.timer_huifang.start(200)
elif result == QMessageBox.Warning:
# 弹出一个有分组框的窗口
temp_path, ok = QFileDialog.getOpenFileName(self, "传送脚本", "", "脚本文件 (*.txt)")
if ok:
dir_ = os.path.join(state.PATH_TASK, self.datas[idex]["name"])
if not os.path.exists(dir_):
os.makedirs(dir_)
# 并且将jiaoben.ini文件也填入数据然后生成
# 将图片复制到指定目录
path = dir_ + "/传送脚本.txt"
shutil.copy(temp_path, path)
self.datas[idex]["chuansong"] = "传送脚本.txt"
self.datas[idex]["f_item"].bt_chuansong.setProperty("OK_chuansong", True)
logger.info(f"导入传送脚本成功:{path}")
self.sg.mysig_tishi.emit(f"导入传送脚本成功:{path}")
self.datas[idex]["f_item"].bt_chuansong.setStyleSheet("""
#bt_chuansong[OK_chuansong="true"] {
color: rgb(237,182,43);
border-color: rgb(237,182,43);
}
""")
self.save_ini(dir_, self.datas[idex])
def clickd_bt_moban(self, idex):
temp_path, ok = QFileDialog.getOpenFileName(self, "传送模板图片", "", "图片文件 (*.png)")
if ok:
dir_ = os.path.join(state.PATH_TASK, self.datas[idex]["name"])
if not os.path.exists(dir_):
os.makedirs(dir_)
# 并且将jiaoben.ini文件也填入数据然后生成
# 将图片复制到指定目录
path = dir_ + "/传送模板.png"
shutil.copy(temp_path, path)
self.datas[idex]["chuansongmoban"] = "传送模板.png"
self.datas[idex]["f_item"].bt_moban.setProperty("OK_chuansongmoban", True)
self.datas[idex]["f_item"].bt_moban.setStyleSheet("""
#bt_moban[OK_chuansongmoban="true"] {
color: rgb(237,182,43);
border-color: rgb(237,182,43);
}
""")
self.save_ini(dir_, self.datas[idex])
self.sg.mysig_tishi.emit(f"导入传送模板成功:{path}")
logger.info(f"导入传送模板成功:{path}")
def clickd_bt_moban_maodian(self, idex):
temp_path, ok = QFileDialog.getOpenFileName(self, "锚点模板图片", "", "图片文件 (*.png)")
if ok:
dir_ = os.path.join(state.PATH_TASK, self.datas[idex]["name"])
if not os.path.exists(dir_):
os.makedirs(dir_)
# 并且将jiaoben.ini文件也填入数据然后生成
# 将图片复制到指定目录
path = dir_ + "/锚点模板.png"
shutil.copy(temp_path, path)
self.datas[idex]["maodianmoban"] = "锚点模板.png"
self.datas[idex]["f_item"].bt_moban_maodian.setProperty("OK_maodianmoban", True)
self.datas[idex]["f_item"].bt_moban_maodian.setStyleSheet("""
#bt_moban_maodian[OK_maodianmoban="true"] {
color: rgb(237,182,43);
border-color: rgb(237,182,43);
}
""")
self.save_ini(dir_, self.datas[idex])
logger.info(f"导入锚点模板成功:{path}")
self.sg.mysig_tishi.emit(f"导入锚点模板成功:{path}")
def clickd_bt_start(self, idex):
global ylmc
is_ACE = checkACEPresence()
if is_ACE and not state.IGNORE_ACE:
QApplication.quit()
elif is_ACE==None and not state.IGNORE_ACE:
logger.info("扫描是否有ACE失败了!建议手动看看有没有(ACE-Guard Client,ACE-Guard Service,SGuard64.exe,SGuard32.exe)进程如果有则不建议继续运行!")
hwnd = win32gui.FindWindow(state.GAME_CLASS, state.GAME_TITLE) # 替换成你实际的窗口句柄
if hwnd == 0:
logger.info("错误:请先开游戏!")
return
left, top, right, bottom = win32gui.GetClientRect(hwnd)
width = right - left
height = bottom - top
if width != 1920 or height != 1080:
logger.info("错误:游戏分辨率不对!请确保游戏分辨率是1920x1080 \n建议重新设置分辨率(如果改了需要重开软件和游戏并且随便先选一个分辨率 然后再改成1920*1080)")
return
#判断是否挡住小地图
rect = win32gui.GetWindowRect(hwnd)
if is_intersecting([rect[0]+8, rect[1], rect[0]+8+222,rect[1]+216], [self.x(), self.y(), self.x()+self.width(), self.y()+self.height()]):
logger.info(
"错误:界面不能挡住小地图")
self.sg.mysig_tishi.emit("错误:界面不能挡住小地图")
return
self.save()
def run(idex):
ret = False
self.sg.mysig_mouse_through.emit(True)
state.计次_传送重试次数 = 0
state.状态_全局暂停 = False
self.datas[idex]['f_item'].cb_is_checked.setChecked(True)
for rt in range(self.run_times):
if self.action_runstartwith.isChecked() :
logger.info(f"任务包:{state.PATH_TASK} {rt+1}/{self.run_times}")
while idex < len(self.datas):
if state.状态_检测中:
time.sleep(1)
continue
if self.datas[idex]['f_item'].cb_is_checked.isChecked():
ret = self.run(idex)
if state.状态_循环开关 == False:
break
if ret == False:
if state.状态_需重新传送 == True:
state.计次_传送重试次数 += 1
if state.计次_传送重试次数 >= 5:
state.计次_传送重试次数 = 0
logger.info("传送重试次数过多,放弃该任务!")
else:
logger.info(f"传送重试{state.计次_传送重试次数}")
time.sleep(2)
continue
else:
break
if self.action_runstartwith.isChecked()==False:
break
state.计次_传送重试次数 = 0
idex += 1
if self.action_runstartwith.isChecked() == False:
break
if state.状态_循环开关 == False:
break
idex=0
state.状态_寻路中 = False
state.状态_已经有寻路了 = False
state.状态_需重新传送 = False
if state.状态_循环开关 != False:
if self.action_runstartwith.isChecked():
#切下一个任务包 继续
next_tas=self.get_next_task()
if state.ON_NEXTPACK==1 and next_tas!=None:
logger.info("切下一个任务包!")
old_task=copy.copy(state.PATH_TASK)
state.PATH_TASK=next_tas
self.sg.mysig_mouse_through.emit(False)
self.sg.mysig_next_pack.emit(old_task)
return
if ret == True and state.ON_JIXING == 1:
ylmc.run_jixing()
if ret == True and state.ON_SHUTDOWN == 1:
self.sg.mysig_shutdown.emit()
self.sg.mysig_mouse_through.emit(False)
state.状态_循环开关 = False
t = threading.Thread(target=run, args=(idex,))
if state.python_var > 9:
t.daemon = True
else:
t.setDaemon(True)
t.start()
def run(self, idex):
global ylmc,ammc
if not state.状态_YOLOV:
logger.info("还在启动相关服务中..请稍等")
return False
dir_ = os.path.join(state.PATH_TASK, self.datas[idex]["name"])
txt = "执行:"+ self.datas[idex]["name"] + "任务"
logger.info(txt)
self.sg.mysig_tishi.emit(txt)
self.sg.mysig_dingwei.emit(idex)
if not os.path.exists(dir_):
logger.info("没有找到任务文件夹,请先设定任务")
return False
if state.状态_已经有寻路了:
logger.info("请勿重复启动!已经有任务在运行了")
# 弹出提示,不要重复开
return False
state.计数_没找到任何目标 = 0
state.计数_没找到怪物 = 0
state.状态_在爬墙 = False
state.状态_需重新传送 = False
state.状态_循环开关 = True
state.状态_传送中 = True
if self.datas[idex]["chuansong"]!="":#如果没有录传送,那就不传送了
# 运行传送脚本动作
jiaoben = os.path.abspath(os.path.join(dir_, self.datas[idex]["chuansong"]))
ret = ylmc.run_chuansongjiaoben(jiaoben)
if ret == False:
logger.info("执行传送脚本!失败")
return False
# 传送模板 点击
chuansong_path = os.path.join(dir_, self.datas[idex]['chuansongmoban'])
maodian_path = os.path.join(dir_, self.datas[idex]['maodianmoban'])
ret = ammc.run_chuansong(chuansong_path, maodian_path)
if ret == False:
logger.info("识别传送点击!失败")
return False
else:
logger.info("没发现传送脚本,不传送")
state.状态_传送中 = False
state.计数_没找到任何目标 = 0
state.计数_没找到怪物 = 0
state.计数_连招次数 = 0
state.状态_已经有寻路了 = True
if self.datas[idex]["type"] == "2":
return ylmc.run_fuben(int(self.datas[idex]['f_item'].led_cishu.text()),
self.datas[idex]['f_item'].cbb_level.currentIndex(),self.datas[idex]['f_item'].cb_lingjiang.isChecked())
elif self.datas[idex]["type"] == "3":
return ylmc.run_jiaoben(os.path.abspath(os.path.join(dir_, self.datas[idex]["jiaoben"])),
self.datas[idex]['f_item'].cb_auto_f.isChecked())
elif self.datas[idex]["type"] == "4":
names=[
f"{state.PATH_JUESE}/{self.datas[idex]['f_item'].cbb_1.itemData(self.datas[idex]['f_item'].cbb_1.currentIndex())}.png",
f"{state.PATH_JUESE}/{self.datas[idex]['f_item'].cbb_2.itemData(self.datas[idex]['f_item'].cbb_2.currentIndex())}.png",
f"{state.PATH_JUESE}/{self.datas[idex]['f_item'].cbb_3.itemData(self.datas[idex]['f_item'].cbb_3.currentIndex())}.png",
]
return ylmc.run_huanjue(names,self.datas[idex]['f_item'].led_main.text())
elif self.datas[idex]["type"] == "5":
lianzhao_path=self.datas[idex]['f_item'].cbb_lianzhao.currentText()+".txt"
state.状态_需重新传送 = False
state.状态_已经有寻路了 = False
if lianzhao_path!="":
state.LIANZHAO=lianzhao_path
logger.info(f"切换连招脚本: {lianzhao_path} 成功")
return True
else:
return False
else:
t2 = threading.Thread(target=ylmc.run_fight,args=(self.datas[idex]['f_item'].cb_wakuang.isChecked(),self.datas[idex]['f_item'].cb_daguai.isChecked()))
if state.python_var > 9:
t2.daemon = True
else:
t2.setDaemon(True)
t2.start()
try:
image_path = os.path.join(dir_, self.datas[idex]['map'])
image_path_barrier = os.path.join(dir_, self.datas[idex]['lujing'])
if self.datas[idex]['f_item'].cb_daditu.isChecked():
return ammc.run_playback_daditu(image_path_barrier, image_path,self.datas[idex]['f_item'].cb_wakuang.isChecked())
else:
return ammc.run_playback(image_path_barrier, image_path,self.datas[idex]['f_item'].cb_wakuang.isChecked())
except:
state.状态_需重新传送 = False
state.状态_已经有寻路了 = False
return False
def clickd_bt_del(self, idex):
dir_ = os.path.join(state.PATH_TASK, self.datas[idex]["name"])
try:
# 删除整个文件夹
shutil.rmtree(dir_)
logger.info(f"文件夹 {dir_} 已被删除")
self.update_tasks()
except Exception as e:
self.update_tasks()
logger.info(f"删除文件夹时出现错误:{e}")
def save(self,old_task=None):
if old_task==None:
old_task= copy.copy(state.PATH_TASK)
for idex in range(len(self.datas)):
self.returnPressed_name(idex)
# 重写closeEvent方法,在窗口关闭时调用quit()退出应用程序
for i, data in enumerate(self.datas):
dir_ = os.path.join(old_task, data["name"])
self.save_ini(dir_, data)
self.update_tasks()
self.save_ini_seting()
def closeEvent(self, event):
self.save()
app.quit()
def clickd_bt_lujing(self, idex):
dir_ = os.path.join(state.PATH_TASK, self.datas[idex]["name"])
if not os.path.exists(dir_):
state.状态_全局暂停 = True
QMessageBox.information(self, "提示", "没有找到任务文件夹,请先设定任务")
return False
if state.状态_已经有寻路了:
# 弹出提示,不要重复开
QMessageBox.information(self, "提示", "已经有在运行的AI了,请先关闭!")
return False
state.状态_全局暂停 = True
state.状态_循环开关 = True
if self.datas[idex]['f_item'].cb_daditu.isChecked():
reply = QMessageBox.information(self, '是否开始录制',
"请控制角色去你的目的地,\n每隔一段距离按M打开地图后会记录点位\n(仅需要录制一些关键转弯的位置,控制好距离)",
QMessageBox.Ok | QMessageBox.Cancel)
if reply == QMessageBox.Cancel:
return False
else:
reply = QMessageBox.information(self, '是否开始录制',"请控制角色去你的目的地,它会自己记录路线 \n 如果录的结果不好有以下几种可能:\n1.小地图上有追踪标点波纹影响定位\n2.地图给的范围过于小了小到不够小地图当前定位的范围\n3.过于透明或者没特征(建议勾选大地图再录)",
QMessageBox.Ok | QMessageBox.Cancel)
if reply == QMessageBox.Cancel:
return False
self.datas[idex]['lujing'] = "路径.png"
image_path = os.path.join(dir_, self.datas[idex]['map'])
image_path_lujing = os.path.join(dir_, self.datas[idex]['lujing'])
self.datas[idex]["f_item"].bt_lujing.setProperty("OK_lujing", True)
self.datas[idex]["f_item"].bt_lujing.setStyleSheet("""
#bt_lujing[OK_lujing="true"] {
color: rgb(237,182,43);
border-color: rgb(237,182,43);
}
""")
t = threading.Thread(target=ammc.run_rec, args=(image_path, image_path_lujing,self.datas[idex]['f_item'].cb_daditu.isChecked()))
if state.python_var > 9:
t.daemon = True
else:
t.setDaemon(True)
t.start()
self.save_ini(dir_, self.datas[idex])
return True
def save_ini(self, dir_, d):
try:
# 创建 ConfigParser 对象
config = configparser.ConfigParser()
# 添加节和键-值对
if d["type"] == "2":
config['seting'] = {
'type': d["type"],
'name': d["name"],
'cbb_level':d["f_item"].cbb_level.currentIndex(),
'cb_lingjiang': d["f_item"].cb_lingjiang.isChecked(),
'led_cishu': d["f_item"].led_cishu.text(),
'chuansong': d["chuansong"],
'chuansongmoban': d["chuansongmoban"],
'maodianmoban': d["maodianmoban"],
'cb_is_checked': d["f_item"].cb_is_checked.isChecked()
}
elif d["type"] == "3":
config['seting'] = {
'type': d["type"],
'name': d["name"],
'cb_auto_f': d["f_item"].cb_auto_f.isChecked(),
'jiaoben': d["jiaoben"],
'chuansong': d["chuansong"],
'chuansongmoban': d["chuansongmoban"],
'maodianmoban': d["maodianmoban"],
'cb_is_checked': d["f_item"].cb_is_checked.isChecked()
}
elif d["type"] == "4":
config['seting'] = {
'type': d["type"],
'name': d["name"],
'chuansong': d["chuansong"],
'cb_is_checked': d["f_item"].cb_is_checked.isChecked(),
'cbb_1':d["f_item"].cbb_1.itemData(d["f_item"].cbb_1.currentIndex()),
'cbb_2': d["f_item"].cbb_2.itemData(d["f_item"].cbb_2.currentIndex()),
'cbb_3': d["f_item"].cbb_3.itemData(d["f_item"].cbb_3.currentIndex()),
"led_main":d["f_item"].led_main.text()
}
elif d["type"] == "5":
config['seting'] = {
'type': d["type"],
'name': d["name"],
'chuansong': d["chuansong"],
'cb_is_checked': d["f_item"].cb_is_checked.isChecked(),
'cbb_lianzhao':d["f_item"].cbb_lianzhao.currentText(),
}
else:
config['seting'] = {
'type': d["type"],
'name': d["name"],
'map': d["map"],
'lujing': d["lujing"],
'chuansong': d["chuansong"],
'chuansongmoban': d["chuansongmoban"],
'maodianmoban': d["maodianmoban"],
'cb_is_checked': d["f_item"].cb_is_checked.isChecked(),
'cb_wakuang': d["f_item"].cb_wakuang.isChecked(),
'cb_daditu': d["f_item"].cb_daditu.isChecked(),
'cb_daguai': d["f_item"].cb_daguai.isChecked()
}
# 写入配置到 INI 文件
with open(os.path.join(dir_, "jiaoben.ini"), 'w') as configfile:
config.write(configfile)
except Exception as err:
print(err)
def hotkey_importtask(self):
# 弹出通用对话框选择文件夹
source_folder = QFileDialog.getExistingDirectory(self, "选择文件夹")
if source_folder == "":
return
destination_folder = os.path.join(state.PATH_TASK, source_folder.split('/')[-1])
if not os.path.exists(destination_folder):
os.makedirs(destination_folder)
else:
QMessageBox.information(self, "提示", "已经有这个名字的任务了,请重命名后再试")
return
logger.info("导入任务 "+destination_folder)
# 将整个文件夹的内容全部复制到test文件夹
# 获取源文件夹中所有项的列表
items = os.listdir(source_folder)
# 循环处理列表中的每个项
for item in items:
# 构建源文件/文件夹的完整路径
source = os.path.join(source_folder, item)
# 构建目标文件/文件夹的完整路径
destination = os.path.join(destination_folder, item)
# 如果该项为文件,则使用shutil.copy()函数复制文件
if os.path.isfile(source):
shutil.copy(source, destination)
# 如果该项为文件夹,则递归调用该函数复制文件夹
elif os.path.isdir(source):
shutil.copytree(source, destination)
self.update_tasks()
def hotkey_addtask(self):
try:
dir_ = os.path.join(state.PATH_TASK, "任务" + str(int(time.time())) + str(random.randint(10, 100)))
if not os.path.exists(dir_):
os.makedirs(dir_)
# 创建 ConfigParser 对象
config = configparser.ConfigParser()
# 加载 INI 文件
config.read(os.path.join(dir_, "jiaoben.ini"))
config.read(os.path.join(dir_, "jiaoben.ini"))
self.add_task(dir_, config)
self.save_ini(dir_, self.datas[-1])
except:
pass
def hotkey_addtaskjiaoben(self):
dir_ = os.path.join(state.PATH_TASK, "任务" + str(int(time.time())) + str(random.randint(10, 100)))
if not os.path.exists(dir_):
os.makedirs(dir_)
# 创建 ConfigParser 对象
config = configparser.ConfigParser()
# 加载 INI 文件
config.read(os.path.join(dir_, "jiaoben.ini"))
self.add_taskjiaoben(dir_, config)
self.save_ini(dir_, self.datas[-1])
def hotkey_qiejue(self):
dir_ = os.path.join(state.PATH_TASK, "切换角色" + str(int(time.time())) + str(random.randint(10, 100)))
if not os.path.exists(dir_):
os.makedirs(dir_)
# 创建 ConfigParser 对象
config = configparser.ConfigParser()
# 加载 INI 文件
config.read(os.path.join(dir_, "jiaoben.ini"))
self.add_xuanjue(dir_, config)
self.save_ini(dir_, self.datas[-1])
def hotkey_qiehuanlianzhao(self):
dir_ = os.path.join(state.PATH_TASK, "切换连招" + str(int(time.time())) + str(random.randint(10, 100)))
if not os.path.exists(dir_):
os.makedirs(dir_)
# 创建 ConfigParser 对象
config = configparser.ConfigParser()
# 加载 INI 文件
config.read(os.path.join(dir_, "jiaoben.ini"))
self.add_xuanlianzhao(dir_, config)
self.save_ini(dir_, self.datas[-1])
def hotkey_addtaskfuben(self):
dir_ = os.path.join(state.PATH_TASK, "任务" + str(int(time.time())) + str(random.randint(10, 100)))
if not os.path.exists(dir_):
os.makedirs(dir_)
# 创建 ConfigParser 对象
config = configparser.ConfigParser()
# 加载 INI 文件
config.read(os.path.join(dir_, "jiaoben.ini"))
self.add_taskfuben(dir_, config)
self.save_ini(dir_, self.datas[-1])
def hotkey_opentaskdir(self):
os.startfile(os.path.abspath(state.PATH_TASK)) # 使用startfile方法打开文件夹
def hotkey_selecttaskdir(self):
# 弹出通用对话框选择文件夹
source_folder = QFileDialog.getExistingDirectory(self, "选择任务文件夹", state.PATH_TASK)
if source_folder == "":
return
state.PATH_TASK = source_folder
self.add_tool_item(state.PATH_TASK)
state.PACKS_TASK+="#@@#"+state.PATH_TASK
self.save_ini_seting()
self.update_tasks()
logger.info(f"成功设置{state.PATH_TASK}为当前任务文件夹")
def hotkey_setlianzhao(self):
# 弹出一个有分组框的窗口
temp_path, ok = QFileDialog.getOpenFileName(self, "连招脚本", state.PATH_JIAOBEN, "脚本文件 (*.txt)")
if ok:
_, state.LIANZHAO = os.path.split(temp_path)
dir_ = os.path.join(state.PATH_JIAOBEN, state.LIANZHAO)
try:
shutil.copy(temp_path, dir_)
except:
pass
logger.info("选择连招脚本成功!")
self.save_ini_seting()
def hotkey_addlianzhao(self):
# 弹出一个选择弹窗 选项为 录制还是文件中选择
msgBox = QMessageBox(self)
msgBox.setWindowTitle("配置连招") # 设置消息框标题
msgBox.setIcon(QMessageBox.Information)
msgBox.setText("当前连招:" + state.LIANZHAO+"\n请选择一个配置方式:" )
msgBox.addButton("录制", QMessageBox.AcceptRole)
msgBox.addButton("回放", QMessageBox.ApplyRole)
msgBox.addButton("文件中选择", QMessageBox.RejectRole)
result = msgBox.exec_()
if result == QMessageBox.AcceptRole:
try:
text, ok = QInputDialog.getText(self, '提示', '请输入脚本名:',text=state.LIANZHAO)
if not ok:
return
if text=="":
return
elif text[-4:]!=".txt":
state.LIANZHAO=text+".txt"
else:
state.LIANZHAO = text
logger.info("可以开始录制了,按F8开始/停止")
self.sg.mysig_tishi.emit("可以开始录制了,按F8开始/停止")
state.状态_是否禁止录制 = False
state.状态_是否开始录制 = False
state.录制_脚本文本 = ""
tangbaowss.send_msg( "是否禁止录制#@@#假")
tangbaowss.send_msg( "是否开始录制#@@#假")
tangbaowss.send_msg( f"全局脚本名#@@#{state.LIANZHAO.replace('.txt','')}")
hwnd = win32gui.FindWindow(state.GAME_CLASS, state.GAME_TITLE) # 替换成你实际的窗口句柄
tangbaowss.send_msg( f"全局hwnd#@@#{hwnd}")
self.timer_luzhi_lianzhao.start(200)
except:
pass
elif result == QMessageBox.RejectRole:
if state.状态_是否回放中 == True:
return
if not os.path.exists(state.PATH_JIAOBEN):
os.makedirs(state.PATH_JIAOBEN)
state.状态_是否回放中 = True
state.状态_循环开关 = True
jiaoben = os.path.abspath(os.path.join(state.PATH_JIAOBEN,state.LIANZHAO ))
message = f"解析脚本#@@#{jiaoben}"
tangbaowss.send_msg( message)
hwnd = win32gui.FindWindow(state.GAME_CLASS, state.GAME_TITLE) # 替换成你实际的窗口句柄
set_window_activate(hwnd)
tangbaowss.send_msg( "脚本执行#@@#1")
self.timer_huifang.start(200)
elif result == QMessageBox.Warning:
self.hotkey_setlianzhao()
def save_ini_seting(self):
try:
hwnd = ctypes.windll.kernel32.GetConsoleWindow()
if hwnd:
rect = win32gui.GetWindowRect(hwnd)
x, y, w, h = rect[0], rect[1], rect[2] - rect[0], rect[3] - rect[1]
else:
x, y, w, h = state.CMD_LEFT, state.CMD_TOP, state.CMD_WIDTH, state.CMD_HEIGHT
# 创建 ConfigParser 对象
config = configparser.ConfigParser()
# 添加节和键-值对
config['seting'] = {
"GAME_TITLE":state.GAME_TITLE,
'GAME_CLASS':state.GAME_CLASS,
'LIANZHAO': state.LIANZHAO,
'LIANZHAOFUWU': state.LIANZHAOFUWU,
'DUANGKOUHAO': state.DUANGKOUHAO,
'PATH_TASK': state.PATH_TASK,
'PATH_JIAOBEN': state.PATH_JIAOBEN,
'PACKS_TASK':state.PACKS_TASK,
'WEIGHTS': state.WEIGHTS,
'PROVIDERS': state.PROVIDERS,
'IMGSIZE_WIDTH':str(state.IMGSIZE_WIDTH),
'IMGSIZE_HEIGHT':str(state.IMGSIZE_HEIGHT),
'WINDOW_WIDTH': str(self.width()),
'WINDOW_HEIGHT': str(self.height()),
'WINDOW_LEFT': str(self.x()),
'WINDOW_TOP': str(self.y()),
'CMD_WIDTH': str(w),
'CMD_HEIGHT': str(h),
'CMD_LEFT': str(x),
'CMD_TOP': str(y),
'ON_SHUTDOWN': str(state.ON_SHUTDOWN),
'ON_JIXING': str(state.ON_JIXING),
'ON_NEXTPACK':str(state.ON_NEXTPACK),
'ON_LIANZHAOBUJIANCE':str(state.ON_LIANZHAOBUJIANCE),
'IGNORE_ACE': str(state.IGNORE_ACE),
'TIMEOUT_DAGUAI':str(state.TIMEOUT_DAGUAI)
}
# 写入配置到 INI 文件
with open("./datas/setting.ini", 'w') as configfile:
config.write(configfile)
except:
pass
def hotkey_all_ck(self):
for item in self.datas:
item['f_item'].cb_is_checked.setChecked(True)
def hotkey_all_not_ck(self):
for item in self.datas:
item['f_item'].cb_is_checked.setChecked(False)
def hotkey_all_fan_ck(self):
for item in self.datas:
item['f_item'].cb_is_checked.setChecked(not item['f_item'].cb_is_checked.isChecked())
def hotkey_runall(self):
global ylmc
is_ACE = checkACEPresence()
if is_ACE==True and not state.IGNORE_ACE:
QApplication.quit()
elif is_ACE==None and not state.IGNORE_ACE:
logger.info("扫描是否有ACE失败了!建议手动看看有没有(ACE-Guard Client,ACE-Guard Service,SGuard64.exe,SGuard32.exe)进程如果有则不建议继续运行!")
hwnd = win32gui.FindWindow(state.GAME_CLASS, state.GAME_TITLE) # 替换成你实际的窗口句柄
if hwnd == 0:
logger.info("错误:请先开游戏!")
return
left, top, right, bottom = win32gui.GetClientRect(hwnd)
width = right - left
height = bottom - top
if width!=1920 or height!=1080:
logger.info("错误:游戏分辨率不对!请确保游戏分辨率是1920x1080 建议重新设置分辨率")
return
# 判断是否挡住小地图
rect = win32gui.GetWindowRect(hwnd)
if is_intersecting([rect[0]+8, rect[1], rect[0]+8 + 222, rect[1] + 216],
[self.x(), self.y(), self.x() + self.width(), self.y() + self.height()]):
logger.info(
"错误:界面不能挡住小地图")
self.sg.mysig_tishi.emit("错误:界面不能挡住小地图")
return
self.save()
def run():
self.sg.mysig_mouse_through.emit(True)
#运行 N 次
ret = False
for rt in range(self.run_times):
logger.info(f"任务包:{state.PATH_TASK} {rt+1}/{self.run_times}")
idex = 0
state.计次_传送重试次数 = 0
state.状态_全局暂停 = False
while idex < len(self.datas):
if state.状态_检测中:
time.sleep(1)
continue
if self.datas[idex]['f_item'].cb_is_checked.isChecked():
ret = self.run(idex)
if state.状态_循环开关 == False:
break
if ret == False:
if state.状态_需重新传送 == True:
state.计次_传送重试次数 += 1
if state.计次_传送重试次数 >= 5:
state.计次_传送重试次数 = 0
logger.info("传送重试次数过多,放弃该任务!")
else:
logger.info(f"传送重试{state.计次_传送重试次数}" )
time.sleep(2)
continue
else:
break
state.计次_传送重试次数 = 0
idex += 1
if state.状态_循环开关 == False:
break
state.状态_寻路中 = False
state.状态_已经有寻路了 = False
state.状态_需重新传送 = False
if state.状态_循环开关 != False:
# 切下一个任务包 继续
next_tas = self.get_next_task()
if state.ON_NEXTPACK == 1 and next_tas != None:
logger.info("切下一个任务包!")
old_task = copy.copy(state.PATH_TASK)
state.PATH_TASK = next_tas
self.sg.mysig_mouse_through.emit(False)
self.sg.mysig_next_pack.emit(old_task)
return
if ret == True and state.ON_JIXING == 1:
ylmc.run_jixing()
if ret == True and state.ON_SHUTDOWN == 1:
self.sg.mysig_shutdown.emit()
self.sg.mysig_mouse_through.emit(False)
state.状态_循环开关 = False
t = threading.Thread(target=run)
if state.python_var>9:
t.daemon=True
else:
t.setDaemon(True)
t.start()
def hotkey_keys_ack(self):
text, ok = QInputDialog.getText(self, '提示', '请输入关键字:', text="狗粮")
if not ok:
return
if text == "":
return
for item in self.datas:
if text in item['f_item'].led_name.text():
item['f_item'].cb_is_checked.setChecked(True)
def hotkey_num_ck(self):
text, ok = QInputDialog.getText(self, '提示', '请输入包含某数字的区间:', text="0-100")
if not ok:
return
if text == "":
return
try:
min_, main_=list(map(int, text.split("-")))
except:
return
for item in self.datas:
if main_>= extract_number(item['f_item'].led_name.text())>=min_:
item['f_item'].cb_is_checked.setChecked(True)
def hotkey_find(self):
text, ok = QInputDialog.getText(self, '提示', '请输入要定位的任务关键字:', text="绝缘")
if not ok:
return
if text == "":
return
for idex,item in enumerate(self.datas) :
if text in item['f_item'].led_name.text():
self.dingwei(idex)
def hotkey_deltask(self):
for idex, item in enumerate(self.datas):
if item['f_item'].cb_is_checked.isChecked():
self.clickd_bt_del(idex)
def hotkey_isShow(self):
state.开关_是否展预测结果 = self.action_isShow.isChecked()
if self.action_isShow.isChecked():
# 判断窗口是否存在
if not hasattr(self, "fromshow"):
self.fromshow = FormShow(self)
self.addDockWidget(Qt.TopDockWidgetArea, self.fromshow)
self.fromshow.show()
else:
if hasattr(self, "fromshow"):
self.fromshow.close()
def hotkey_yunduanlist(self):
self.formyunfilelist = FormYunFileList()
threading.Thread(target=self.formyunfilelist.update).start()
self.formyunfilelist.show()
self.formyunfilelist.lb_ing.show()
self.formyunfilelist.lb_ing.move(self.formyunfilelist.width()-self.formyunfilelist.lb_ing.width(),self.formyunfilelist.height()-self.formyunfilelist.lb_ing.height())
def hotkey_shutdown(self):
if self.action_shutdown.isChecked():
state.ON_SHUTDOWN = 1
else:
state.ON_SHUTDOWN = 0
self.save_ini_seting()
def hotkey_timeout(self):
try:
text, ok = QInputDialog.getText(self, '超时阈值', '请输入打怪超时阈值 单位秒:\n注意最低不能小于60秒', text=str(state.TIMEOUT_DAGUAI))
if not ok:
return
if text == "":
return
if int(text)<60:
state.TIMEOUT_DAGUAI=60
else:
state.TIMEOUT_DAGUAI = int(text)
self.action_timeout.setText(f"设置打怪超时 阈值:{state.TIMEOUT_DAGUAI}秒")
logger.info("设置打怪超时阈值为:"+str(state.TIMEOUT_DAGUAI))
self.save_ini_seting()
except:
pass
def hotkey_run_times(self):
try:
text, ok = QInputDialog.getText(self, '执行次数', f'当前任务包:{state.PATH_TASK}\n请输入执行次数:', text=str(self.run_times))
if not ok:
return
if text == "":
return
if int(text)<1:
self.run_times=1
else:
self.run_times= int(text)
self.action_run_times.setText(f"设置:当前任务包 执行次数:{self.run_times}")
logger.info(f"设置:当前任务包 执行次数:{self.run_times}")
# 创建 ConfigParser 对象
config_main = configparser.ConfigParser()
# 添加节和键-值对
config_main['seting'] = {
"run_times": str(self.run_times),
}
# 写入配置到 INI 文件
with open( os.path.join(state.PATH_TASK, "细节参数.ini"), 'w') as configfile:
config_main.write(configfile)
except:
pass
def hotkey_lianzhaobujiance(self):
if self.action_lianzhaobujiance.isChecked():
state.ON_LIANZHAOBUJIANCE = 1
else:
state.ON_LIANZHAOBUJIANCE = 0
self.save_ini_seting()
def hotkey_jixing(self):
if self.action_jixing.isChecked():
state.ON_JIXING = 1
else:
state.ON_JIXING = 0
self.save_ini_seting()
def hotkey_nextpack(self):
if self.action_nextpack.isChecked():
state.ON_NEXTPACK = 1
else:
state.ON_NEXTPACK = 0
self.save_ini_seting()
def hotkey_stitchimg(self):
# 弹出通用对话框选择文件夹
source_folder = QFileDialog.getExistingDirectory(self, "选择文件夹", "./datas/img")
if source_folder == "":
return
si = StitchImages()
image_paths = si.get_image_paths(source_folder)
ret = si.stitch_images(image_paths, "./datas/max_map/max_map.png", True)
if not ret:
QMessageBox.information(self, "提示", "合成全景图失败,检查一下是不是每张图都有相交的地方")
def hotkey_guai(self):
for item in self.datas:
if item['f_item'].cb_is_checked.isChecked():
if item["type"] == "1":
item['f_item'].cb_daguai.setChecked(self.action_guai.isChecked())
def hotkey_kuang(self):
for item in self.datas:
if item['f_item'].cb_is_checked.isChecked():
if item["type"] == "1":
item['f_item'].cb_wakuang.setChecked(self.action_kuang.isChecked())
def hotkey_hua(self):
for item in self.datas:
if item['f_item'].cb_is_checked.isChecked():
if item["type"] == "1":
item['f_item'].cb_daditu.setChecked(self.action_hua.isChecked())
def set_cbb_items(self,cbb):
cbb .clear()
#遍历文件夹下的所有png文件
# 定义要遍历的文件夹路径
folder_path =state.PATH_JUESE
# 遍历文件夹及其子文件夹中的所有文件
for root, dirs, files in os.walk(folder_path):
for file in files:
# 检查文件扩展名是否为.png
if file.endswith('.png'):
# 打印PNG文件的完整路径
file_name = os.path.splitext(file)[0]
cbb.addItem("",file_name)
# 获取下拉列表的视图部件
view = cbb.view()
# 设置特定子项的工具提示和相应的图片
for index in range(cbb.count()):
file_name = cbb.itemData(index)
image_path = f"{folder_path}/{file_name}.png"
if image_path:
item = view.model().item(index, 0)
pixmap = QPixmap(image_path)
item.setIcon(QIcon(pixmap))
# item.setToolTip(image_path)
cbb.setIconSize(QSize(int(40*ratio), int(50*ratio))) # 设置图标大小为40x40像素
def set_cbb_item(self,cbb, name):
# 设置特定子项的工具提示和相应的图片
for index in range(cbb.count()):
file_name = cbb.itemData(index)
if file_name==name:
cbb.setCurrentIndex(index)
if __name__ == '__main__':
if ctypes.windll.shell32.IsUserAnAdmin():
vardata = get_var_data()
if vardata != False:
updatetxt = get_updatetxt()
print(updatetxt)
print("当前版本号:" + state.版本号)
if float(vardata[1]) > float(state.版本号):
print("如果更新失败手动下更新包手动覆盖: https://gitee.com/LanRenZhiNeng/ming-chao-ai/releases")
var = input(f"发现更新的版本 v{vardata[1]} 是否需要更新? (输入yes or no 默认更新)\n")
if var == "":
var = "yes"
if var.lower() != "no":
if float(state.版本号) >= float(vardata[3]):
update_process = subprocess.Popen(f'update.exe "{vardata[0]}.exe" "{vardata[2]}"',
creationflags=subprocess.CREATE_NEW_CONSOLE)
time.sleep(1)
sys.exit()
else:
print(f"更新失败!因为你当前版本低于{vardata[3]}最低可自动更新的版本,需要去下载最新的一键安装包")
is_ACE = checkACEPresence()
if is_ACE and not state.IGNORE_ACE:
input("禁止使用! 按回车结束")
exit()
elif is_ACE==None and not state.IGNORE_ACE:
logger.info("扫描是否有ACE失败了!建议手动看看有没有(ACE-Guard Client,ACE-Guard Service,SGuard64.exe,SGuard32.exe)进程如果有则不建议继续运行!")
#检测当前桌面的缩放比例
if not get_windows_screen_scale()==1:
input(f"桌面缩放比例不是100% 禁止使用!请在桌面 右键 显示设置 缩放与布局改成100%\n设置好后如果还不行请检查是否有多个屏幕 可以拔掉其它屏幕 单独设置缩放100% 然后重启电脑\n如果非要用按回车继续")
# 检测 连招服务是否存在
if not os.path.exists(state.LIANZHAOFUWU):
webbrowser.open("https://www.runker.net/windows-defender.html")
input(f"文件 '{state.LIANZHAOFUWU}' 不存在!极有可能被杀毒软件干掉了!请关闭杀毒软件后重新安装!")
exit()
# 运行需要管理员权限的代码
kernel32 = ctypes.windll.kernel32
kernel32.SetConsoleMode(kernel32.GetStdHandle(-10), 128)
# 设置cmd窗口位置
set_console_position(state.CMD_LEFT, state.CMD_TOP, state.CMD_WIDTH, state.CMD_HEIGHT)
# 在事件循环中创建一个任务对象并加入事件循环
ylmc = YolovMingChao(weights=state.WEIGHTS, providers=state.PROVIDERS, dic_labels=state.dic_labels,
model_h=state.IMGSIZE_WIDTH, model_w=state.IMGSIZE_HEIGHT)# 启动yolov检测服务
ammc = MingChaoAutoMap() # 启动寻路类
app = QApplication(sys.argv) # 初始化Qt应用
ratio = screen_width / 2560 # 分辨率比例
# 设置全局字体大小
# 计算字体大小
base_font_size = 12
# 基准字体大小,适合1920*1080分辨率
new_font_size = int(base_font_size * ratio)
font = QFont("Arial", new_font_size)
# 子控件的宽度
item_width=350
item_height=243
item_height_min = 60
window_main = MainWindow()
window_main.show()
sys.exit(app.exec_()) # 监听消息不关闭
else:
# 如果不是管理员,则请求以管理员权限重新运行程序
ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1)
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。