forked from huangxin/ailai
first commit
This commit is contained in:
BIN
Util/__pycache__/util_ini.cpython-39.pyc
Normal file
BIN
Util/__pycache__/util_ini.cpython-39.pyc
Normal file
Binary file not shown.
BIN
Util/__pycache__/util_log.cpython-39.pyc
Normal file
BIN
Util/__pycache__/util_log.cpython-39.pyc
Normal file
Binary file not shown.
BIN
Util/__pycache__/util_math.cpython-39.pyc
Normal file
BIN
Util/__pycache__/util_math.cpython-39.pyc
Normal file
Binary file not shown.
BIN
Util/__pycache__/util_pic.cpython-39.pyc
Normal file
BIN
Util/__pycache__/util_pic.cpython-39.pyc
Normal file
Binary file not shown.
BIN
Util/__pycache__/util_time.cpython-39.pyc
Normal file
BIN
Util/__pycache__/util_time.cpython-39.pyc
Normal file
Binary file not shown.
41
Util/util_ini.py
Normal file
41
Util/util_ini.py
Normal file
@ -0,0 +1,41 @@
|
||||
import configparser
|
||||
|
||||
|
||||
def writeFeedLine_to_ini(feedLine_dirt,file_path:str):
|
||||
config = configparser.ConfigParser()
|
||||
for key,value in feedLine_dirt.items():
|
||||
config.add_section(key)
|
||||
config.set(key,'name',value.name)
|
||||
config.set(key,'SafePosition_x',str(value.safe_position.X))
|
||||
config.set(key,'SafePosition_y',str(value.safe_position.Y))
|
||||
config.set(key,'SafePosition_z',str(value.safe_position.Z))
|
||||
config.set(key,'SafePosition_u',str(value.safe_position.U))
|
||||
config.set(key,'SafePosition_v',str(value.safe_position.V))
|
||||
config.set(key,'SafePosition_w',str(value.safe_position.W))
|
||||
config.set(key, 'brokenposition1_x', str(value.broken1_position.X))
|
||||
config.set(key, 'brokenposition1_y', str(value.broken1_position.Y))
|
||||
config.set(key, 'brokenposition1_z', str(value.broken1_position.Z))
|
||||
config.set(key, 'brokenposition1_u', str(value.broken1_position.U))
|
||||
config.set(key, 'brokenposition1_v', str(value.broken1_position.V))
|
||||
config.set(key, 'brokenposition1_w', str(value.broken1_position.W))
|
||||
config.set(key, 'brokenposition2_x', str(value.broken2_position.X))
|
||||
config.set(key, 'brokenposition2_y', str(value.broken2_position.Y))
|
||||
config.set(key, 'brokenposition2_z', str(value.broken2_position.Z))
|
||||
config.set(key, 'brokenposition2_u', str(value.broken2_position.U))
|
||||
config.set(key, 'brokenposition2_v', str(value.broken2_position.V))
|
||||
config.set(key, 'brokenposition2_w', str(value.broken2_position.W))
|
||||
config.set(key,'ShakePosition_x',str(value.shake_position.X))
|
||||
config.set(key,'ShakePosition_y',str(value.shake_position.Y))
|
||||
config.set(key,'ShakePosition_z',str(value.shake_position.Z))
|
||||
config.set(key,'ShakePosition_u',str(value.shake_position.U))
|
||||
config.set(key,'ShakePosition_v',str(value.shake_position.V))
|
||||
config.set(key,'ShakePosition_w',str(value.shake_position.W))
|
||||
config.set(key,'DropBagPosition_x',str(value.drop_bag_position.X))
|
||||
config.set(key,'DropBagPosition_y',str(value.drop_bag_position.Y))
|
||||
config.set(key,'DropBagPosition_z',str(value.drop_bag_position.Z))
|
||||
config.set(key,'DropBagPosition_u',str(value.drop_bag_position.U))
|
||||
config.set(key,'DropBagPosition_v',str(value.drop_bag_position.V))
|
||||
config.set(key,'DropBagPosition_w',str(value.drop_bag_position.W))
|
||||
|
||||
config.write(open(file_path,'w',encoding='utf-8'))
|
||||
return True
|
||||
10
Util/util_language.py
Normal file
10
Util/util_language.py
Normal file
@ -0,0 +1,10 @@
|
||||
from PyQt5.QtCore import QTranslator, QLocale, QLibraryInfo
|
||||
|
||||
|
||||
def show_translated_message_box(app):
|
||||
# 加载翻译文件
|
||||
translator = QTranslator()
|
||||
locale = QLocale.system().name() # 获取系统语言
|
||||
qt_translations_path = QLibraryInfo.path(QLibraryInfo.TranslationsPath)
|
||||
translator.load(f"qtbase_{locale}", qt_translations_path)
|
||||
app.installTranslator(translator)
|
||||
103
Util/util_log.py
Normal file
103
Util/util_log.py
Normal file
@ -0,0 +1,103 @@
|
||||
import logging
|
||||
import queue
|
||||
import threading
|
||||
import time
|
||||
from logging.handlers import TimedRotatingFileHandler
|
||||
from PySide6.QtCore import Signal, QObject
|
||||
|
||||
|
||||
|
||||
class QTextEditLogger(logging.Handler):
|
||||
def __init__(self, text_widget):
|
||||
super().__init__()
|
||||
self.widget = text_widget
|
||||
|
||||
def emit(self, record):
|
||||
# 格式化日志信息
|
||||
log_message = self.format(record)
|
||||
# 在主线程中更新 QTextEdit
|
||||
self.widget.append(log_message)
|
||||
|
||||
|
||||
|
||||
class Logger(QObject):
|
||||
log_info_signal = Signal(str)
|
||||
log_warning_signal = Signal(str)
|
||||
log_error_signal = Signal(str)
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.logger_textEdit_info = logging.getLogger('info_logger')
|
||||
self.logger_textEdit_info.setLevel(logging.INFO)
|
||||
self.logger_textEdit_warning = logging.getLogger('warning_logger')
|
||||
self.logger_textEdit_warning.setLevel(logging.WARNING)
|
||||
self.logger_file_info = logging.getLogger('file_logger')
|
||||
self.logger_file_info.setLevel(logging.INFO)
|
||||
self.pre_message = ''
|
||||
self.lock = threading.Lock() # 创建锁
|
||||
self.log_queue = queue.Queue()
|
||||
self.logger_thread = threading.Thread(target=self._process_logs, daemon=True)
|
||||
self.logger_thread.start()
|
||||
|
||||
def init_log(self,textEdit_info,textEdit_warning,file_path):
|
||||
text_edit_handler = QTextEditLogger(textEdit_info)
|
||||
formatter = logging.Formatter('%(asctime)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
|
||||
text_edit_handler.setFormatter(formatter)
|
||||
self.logger_textEdit_info.addHandler(text_edit_handler)
|
||||
|
||||
text_edit_handler_warning = QTextEditLogger(textEdit_warning)
|
||||
formatter_warning = logging.Formatter('%(asctime)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
|
||||
text_edit_handler_warning.setFormatter(formatter_warning)
|
||||
self.logger_textEdit_warning.addHandler(text_edit_handler_warning)
|
||||
|
||||
handler = TimedRotatingFileHandler(file_path, when='D', interval=1, backupCount=30)
|
||||
handler.suffix = "%Y-%m-%d"
|
||||
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
|
||||
handler.setFormatter(formatter)
|
||||
self.logger_file_info.addHandler(handler)
|
||||
|
||||
def _process_logs(self):
|
||||
while True:
|
||||
time.sleep(0.1)
|
||||
level, message = self.log_queue.get()
|
||||
if level == logging.INFO:
|
||||
self.log_info_signal.emit(message)
|
||||
# self.logger_textEdit_info.info(message)
|
||||
self.logger_file_info.info(message)
|
||||
elif level == logging.ERROR:
|
||||
# self.logger_textEdit_info.error(message)
|
||||
self.logger_file_info.error(message)
|
||||
# self.logger_textEdit_warning.error(message)
|
||||
self.log_error_signal.emit(message)
|
||||
elif level == logging.WARNING:
|
||||
self.logger_file_info.warning(message)
|
||||
self.log_warning_signal.emit(message)
|
||||
def log_message(self,level,message):
|
||||
self.log_queue.put((level, message))
|
||||
return
|
||||
try:
|
||||
|
||||
with self.lock: # 确保线程安全
|
||||
if message == self.pre_message:
|
||||
return
|
||||
self.pre_message = message
|
||||
|
||||
if level == logging.INFO:
|
||||
|
||||
self.logger_textEdit_info.info(message)
|
||||
#return
|
||||
self.logger_file_info.info(message)
|
||||
|
||||
if level == logging.ERROR:
|
||||
self.logger_textEdit_info.error(message)
|
||||
self.logger_textEdit_warning.error(message)
|
||||
self.logger_file_info.error(message)
|
||||
if level == logging.WARNING:
|
||||
#return
|
||||
self.logger_file_info.warning(message)
|
||||
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
|
||||
|
||||
log = Logger()
|
||||
14
Util/util_math.py
Normal file
14
Util/util_math.py
Normal file
@ -0,0 +1,14 @@
|
||||
import math
|
||||
|
||||
|
||||
def get_distance(p1, p2):
|
||||
"""
|
||||
计算两点间的距离
|
||||
:param p1:
|
||||
:param p2:
|
||||
:return:
|
||||
"""
|
||||
return math.sqrt((p1.X - p2.X) ** 2 + (p1.Y - p2.Y) ** 2+ (p1.Z - p2.Z)**2)
|
||||
|
||||
def is_bit_set(n, position):
|
||||
return (n >> position) & 1 == 1
|
||||
45
Util/util_pic.py
Normal file
45
Util/util_pic.py
Normal file
@ -0,0 +1,45 @@
|
||||
import logging
|
||||
|
||||
import cv2
|
||||
from PySide6.QtGui import QPixmap, QImage
|
||||
|
||||
from Util.util_log import log
|
||||
|
||||
|
||||
def cv2_to_qpixmap(cv_img):
|
||||
"""将OpenCV图像转换为QPixmap"""
|
||||
# img = cv_img.copy()
|
||||
# cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB)
|
||||
try:
|
||||
height, width, channel = cv_img.shape
|
||||
bytes_per_line = channel * width
|
||||
q_image = QImage(cv_img.data, width, height, bytes_per_line, QImage.Format_RGB888)
|
||||
pixmap = QPixmap.fromImage(q_image)
|
||||
return pixmap
|
||||
except Exception as e:
|
||||
print(e)
|
||||
log.log_message(logging.ERROR,e)
|
||||
return None
|
||||
|
||||
# def cv2_to_qpixmap(cv_img):
|
||||
# """将OpenCV图像转换为QPixmap"""
|
||||
# if len(cv_img.shape) !=3:
|
||||
# print("cv_img.shape !=3")
|
||||
# return None
|
||||
# try:
|
||||
# img = cv_img.copy()
|
||||
# height, width, channel = img.shape
|
||||
# bytes_per_line = 3 * width
|
||||
# q_img = QImage(img.data, width, height, bytes_per_line, QImage.Format_RGB888)
|
||||
# return QPixmap.fromImage(q_img)
|
||||
# except Exception as e:
|
||||
# log.log_message(logging.ERROR, e)
|
||||
# return None
|
||||
|
||||
|
||||
# def cv2_to_qpixmap(cv_img):
|
||||
# #g = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB)
|
||||
# height, width, channel = cv_img.shape
|
||||
# bytes_per_line = 3 * width
|
||||
# q_img = QImage(cv_img.data, width, height, bytes_per_line, QImage.Format_RGB888)
|
||||
# return QPixmap.fromImage(q_img)
|
||||
142
Util/util_time.py
Normal file
142
Util/util_time.py
Normal file
@ -0,0 +1,142 @@
|
||||
import time
|
||||
|
||||
class MyTimer:
|
||||
|
||||
@staticmethod
|
||||
def gMyGetTickCount():
|
||||
ts = time.time()
|
||||
return int(ts * 1000) # Convert to milliseconds
|
||||
|
||||
# CTon class equivalent in Python
|
||||
class CTon:
|
||||
def __init__(self):
|
||||
self.m_unET = 0
|
||||
self.m_bLastI = False
|
||||
self.m_bIn = False
|
||||
self.m_bPause = False
|
||||
self.m_bOver = True
|
||||
self.m_unPT = 0
|
||||
self.m_unStartTime = 0
|
||||
self.m_unPauseET = 0
|
||||
|
||||
def GetET(self):
|
||||
if self.m_bIn:
|
||||
nET = self.m_unPT + (self.m_unStartTime - MyTimer.gMyGetTickCount())
|
||||
return max(nET, 0)
|
||||
else:
|
||||
return 0
|
||||
|
||||
def SetReset(self):
|
||||
self.m_bIn = False
|
||||
self.m_bLastI = False
|
||||
self.m_bPause = False
|
||||
|
||||
def SetPause(self, value):
|
||||
if self.m_bIn:
|
||||
self.m_bPause = value
|
||||
if self.m_bPause:
|
||||
self.m_unPauseET = MyTimer.gMyGetTickCount() - self.m_unStartTime
|
||||
|
||||
def SetOver(self, value):
|
||||
self.m_bOver = value
|
||||
|
||||
def GetStartTime(self):
|
||||
return self.m_unStartTime
|
||||
|
||||
def Q(self, value_i, value_pt):
|
||||
self.m_bIn = value_i
|
||||
self.m_unPT = value_pt
|
||||
un_tick = MyTimer.gMyGetTickCount()
|
||||
|
||||
if self.m_bOver and self.m_bIn:
|
||||
self.m_unStartTime = un_tick - self.m_unPT
|
||||
self.m_bOver = False
|
||||
|
||||
if self.m_bPause and self.m_bIn:
|
||||
self.m_unStartTime = un_tick - self.m_unPauseET
|
||||
|
||||
if self.m_bIn != self.m_bLastI:
|
||||
self.m_bLastI = self.m_bIn
|
||||
if self.m_bIn:
|
||||
self.m_unStartTime = un_tick
|
||||
self.m_bPause = False
|
||||
|
||||
return self.m_bIn and (un_tick >= (self.m_unStartTime + self.m_unPT))
|
||||
|
||||
# CClockPulse class equivalent in Python
|
||||
class CClockPulse:
|
||||
def __init__(self):
|
||||
self.m_bFirstOut = True
|
||||
self.m_bTonAOut = False
|
||||
self.m_bTonBOut = False
|
||||
self.m_cTonA = CTon()
|
||||
self.m_cTonB = CTon()
|
||||
|
||||
def Q(self, value_i, run_time, stop_time):
|
||||
if self.m_bFirstOut:
|
||||
self.m_bTonAOut = self.m_cTonA.Q(not self.m_bTonBOut and value_i, run_time)
|
||||
self.m_bTonBOut = self.m_cTonB.Q(self.m_bTonAOut and value_i, stop_time)
|
||||
return not self.m_bTonAOut and value_i
|
||||
else:
|
||||
self.m_bTonAOut = self.m_cTonA.Q(not self.m_bTonBOut and value_i, stop_time)
|
||||
self.m_bTonBOut = self.m_cTonB.Q(self.m_bTonAOut and value_i, run_time)
|
||||
return self.m_bTonAOut and value_i
|
||||
|
||||
# CDelayOut class equivalent in Python
|
||||
class CDelayOut:
|
||||
def __init__(self):
|
||||
self.m_cOutTon = CTon()
|
||||
self.m_cmWaitTon = CTon()
|
||||
|
||||
def Reset(self):
|
||||
self.m_cOutTon.SetReset()
|
||||
self.m_cmWaitTon.SetReset()
|
||||
|
||||
def Q(self, value_i, wait_time, out_time):
|
||||
if self.m_cmWaitTon.Q(value_i, wait_time):
|
||||
if self.m_cOutTon.Q(True, out_time):
|
||||
self.m_cOutTon.SetReset()
|
||||
self.m_cmWaitTon.SetReset()
|
||||
value_i = False
|
||||
return False
|
||||
return True
|
||||
return False
|
||||
|
||||
# CRisOrFall class equivalent in Python
|
||||
class CRisOrFall:
|
||||
def __init__(self):
|
||||
self.m_bTemp = False
|
||||
|
||||
def Q(self, value_i, ris_or_fall):
|
||||
result = False
|
||||
if value_i != self.m_bTemp:
|
||||
if ris_or_fall and value_i: # Rising edge
|
||||
result = True
|
||||
if not ris_or_fall and not value_i: # Falling edge
|
||||
result = True
|
||||
self.m_bTemp = value_i
|
||||
return result
|
||||
|
||||
# CTof class equivalent in Python
|
||||
class CTof:
|
||||
def __init__(self):
|
||||
self.m_cDelayTon = CTon()
|
||||
self.m_bValue = False
|
||||
self.m_cRis = CRisOrFall()
|
||||
|
||||
def SetReset(self):
|
||||
self.m_bValue = False
|
||||
self.m_cDelayTon.SetReset()
|
||||
|
||||
def Q(self, value_i, delay_time):
|
||||
if self.m_cRis.Q(value_i, False):
|
||||
self.m_cDelayTon.SetReset()
|
||||
self.m_bValue = True
|
||||
if self.m_cDelayTon.Q(self.m_bValue, delay_time):
|
||||
self.m_bValue = False
|
||||
self.m_cDelayTon.SetReset()
|
||||
return value_i or self.m_bValue
|
||||
|
||||
# Utility function
|
||||
def gGetNowTime():
|
||||
return int(time.time())
|
||||
Reference in New Issue
Block a user