parent
c161407db2
commit
de7d73aa50
@ -0,0 +1,237 @@ |
|||||||
|
# import numpy as np |
||||||
|
|
||||||
|
from pathlib import Path |
||||||
|
|
||||||
|
|
||||||
|
class DataPlot(): |
||||||
|
''' |
||||||
|
从文件读取数据,出来成待显示数据 |
||||||
|
''' |
||||||
|
|
||||||
|
# def __init__(self, mypanel, ): |
||||||
|
def __init__(self, ): |
||||||
|
# self.mypanel = mypanel |
||||||
|
# self.__eventManager = eventManger |
||||||
|
# self.dataSaveFile = DATA_FNAME_WITHOUT_WATER |
||||||
|
# self.axes_title = "Water Attenuation Coefficient" |
||||||
|
# self.axes_xlabel = "Wavelength (nm)" |
||||||
|
# self.axes_ylabel = "Attenuation Coefficient m(-1)" |
||||||
|
# self.axes_title = "Attenuation Coefficient Demo" |
||||||
|
self.demo_time = '' |
||||||
|
self.demo_wl = [] # 纯水 |
||||||
|
self.demo_data = [] # 纯水 |
||||||
|
|
||||||
|
self.wavelength = None |
||||||
|
self.data_one = None |
||||||
|
self.data_multi = None |
||||||
|
# self.mode = "one" # multi |
||||||
|
# self.begin_line = None |
||||||
|
# self.line_interval = None |
||||||
|
self.fpath :Path = Path() |
||||||
|
self.total_lines = 0 |
||||||
|
self.token = ";" |
||||||
|
# self.MPL = myPanel.MPL_Panel(self) # 调用自己建立的 panel 类 |
||||||
|
# self.Figure = self.MPL.Figure |
||||||
|
# self.axes = self.MPL.axes |
||||||
|
# self.FigureCanvas = self.MPL.FigureCanvas |
||||||
|
def set_file_path( self, fpath:Path ): |
||||||
|
self.fpath = fpath |
||||||
|
pass |
||||||
|
|
||||||
|
def set_wavelength(self): |
||||||
|
pass |
||||||
|
|
||||||
|
# def set_mode(self, mode ="one"): |
||||||
|
# self.mode = mode |
||||||
|
# pass |
||||||
|
|
||||||
|
def set_token(self, token =";"): |
||||||
|
self.token = token |
||||||
|
pass |
||||||
|
|
||||||
|
def set_begin_line( self, lineno = 0 ): |
||||||
|
self.begin_line = lineno |
||||||
|
pass |
||||||
|
|
||||||
|
def set_line_interval( self, line_interval = 0 ): |
||||||
|
self.line_interval = line_interval |
||||||
|
pass |
||||||
|
|
||||||
|
def get_total_lines( self, ): |
||||||
|
''' 大文件 ''' |
||||||
|
count = 0 |
||||||
|
thefile = open( self.fpath, 'rb') |
||||||
|
while True: |
||||||
|
buffer = thefile.read(8192*1024) |
||||||
|
if not buffer: |
||||||
|
break |
||||||
|
count += buffer.count(b'\n') |
||||||
|
self.total_lines = count + 1 |
||||||
|
|
||||||
|
def get_wavelength_from_file( self, ): |
||||||
|
tmp = self.get_first_line() |
||||||
|
self.wavelength = tmp.split(self.token)[1:] |
||||||
|
pass |
||||||
|
|
||||||
|
def get_reverse_x_lineno( self, x ): |
||||||
|
line = self.__get_reverse_x_lineno(x) |
||||||
|
line = line.split(self.token) |
||||||
|
return line[0], line[1:] |
||||||
|
pass |
||||||
|
|
||||||
|
def get_multi_by_x_m_n( self, x,m,n ): |
||||||
|
# res_time = [] |
||||||
|
# res_lines = [] |
||||||
|
lines = self.__get_reverse_x_m_n_line(x,m,n) |
||||||
|
# print(f'+++++ {lines}') |
||||||
|
# for i in range(len(lines)): |
||||||
|
# ln = |
||||||
|
# res_time.append( lines[i] [0] ) |
||||||
|
# res_lines.append( lines[i][1:] ) |
||||||
|
# return res_time, res_lines |
||||||
|
return lines |
||||||
|
pass |
||||||
|
|
||||||
|
def __get_reverse_x_lineno(self, x): |
||||||
|
""" |
||||||
|
获得倒数第x行 |
||||||
|
""" |
||||||
|
try: |
||||||
|
# filesize = os.path.getsize(self.fpath) |
||||||
|
filesize = self.fpath.stat().st_size |
||||||
|
if filesize == 0: |
||||||
|
return None |
||||||
|
else: |
||||||
|
with open(self.fpath, 'rb') as fp: # to use seek from end, must use mode 'rb' |
||||||
|
offset = -8 # initialize offset |
||||||
|
while -offset < filesize: # offset cannot exceed file size |
||||||
|
fp.seek(offset, 2) # read # offset chars from eof(represent by number '2') |
||||||
|
lines = fp.readlines() # read from fp to eof |
||||||
|
if len(lines) >= x+1: # if contains at least 2 lines |
||||||
|
return lines[-1*x] # then last line is totally included |
||||||
|
else: |
||||||
|
offset *= 2 # enlarge offset |
||||||
|
fp.seek(0) |
||||||
|
lines = fp.readlines() |
||||||
|
if len(lines) < x: |
||||||
|
raise Exception("行数有误,请重试") |
||||||
|
return lines[-1*x] |
||||||
|
except FileNotFoundError: |
||||||
|
print(self.fpath.name + ' not found!') |
||||||
|
return None |
||||||
|
|
||||||
|
def __get_reverse_x_m_n_line(self, x, m=1, n=1): |
||||||
|
""" |
||||||
|
获得倒数第x行, 间隔m行, 共取n个行 |
||||||
|
""" |
||||||
|
print(f'__get_reverse_x_m_n_line {x} {self.fpath}') |
||||||
|
min_lines = x + m*n |
||||||
|
res_lines = [] |
||||||
|
try: |
||||||
|
# filesize = os.path.getsize(self.fpath) |
||||||
|
filesize = self.fpath.stat().st_size |
||||||
|
if filesize == 0: |
||||||
|
return None |
||||||
|
else: |
||||||
|
with open(self.fpath, 'rb') as fp: # to use seek from end, must use mode 'rb'x |
||||||
|
offset = -8 # initialize offset |
||||||
|
while -offset < filesize: # offset cannot exceed file size |
||||||
|
fp.seek( offset, 2 ) # read # offset chars from eof(represent by number '2') |
||||||
|
lines = fp.readlines() # read from fp to eof |
||||||
|
if len(lines) >= min_lines+1 : |
||||||
|
for i in range(n): |
||||||
|
res_lines.append( lines[-1*(x+m*i)].decode()) |
||||||
|
return res_lines |
||||||
|
else: |
||||||
|
offset *= 2 # enlarge offset |
||||||
|
fp.seek( 0 ) |
||||||
|
lines = fp.readlines( ) |
||||||
|
if len(lines) < min_lines: |
||||||
|
raise Exception("行数有误,请重试") |
||||||
|
for i in range(n): |
||||||
|
res_lines.append( lines[-1*(x+m*i)].decode()) |
||||||
|
return res_lines |
||||||
|
print(res_lines) |
||||||
|
except FileNotFoundError: |
||||||
|
print(self.fpath.name + ' not found!') |
||||||
|
return None |
||||||
|
|
||||||
|
def get_first_line(self, ): |
||||||
|
firstline = '' |
||||||
|
with open(self.fpath, 'rb') as fp: # to use seek from end, must use mode 'rb'x |
||||||
|
firstline = fp.readline() |
||||||
|
return firstline.decode() |
||||||
|
|
||||||
|
def get_last_line(self,filename:Path): |
||||||
|
""" |
||||||
|
获得最后一行 |
||||||
|
:param filename: file name |
||||||
|
:return: last line or None for empty file |
||||||
|
""" |
||||||
|
try: |
||||||
|
filesize = filename.stat().st_size |
||||||
|
if filesize == 0: |
||||||
|
return None |
||||||
|
else: |
||||||
|
with open(filename, 'rb') as fp: # to use seek from end, must use mode 'rb' |
||||||
|
offset = -8 # initialize offset |
||||||
|
while -offset < filesize: # offset cannot exceed file size |
||||||
|
fp.seek(offset, 2) # read # offset chars from eof(represent by number '2') |
||||||
|
lines = fp.readlines() # read from fp to eof |
||||||
|
if len(lines) >= 2: # if contains at least 2 lines |
||||||
|
return lines[-1] # then last line is totally included |
||||||
|
else: |
||||||
|
offset *= 2 # enlarge offset |
||||||
|
fp.seek(0) |
||||||
|
lines = fp.readlines() |
||||||
|
return lines[-1] |
||||||
|
except FileNotFoundError: |
||||||
|
print(filename + ' not found!') |
||||||
|
return None |
||||||
|
|
||||||
|
def tail(file, taillines=500, return_str=True, avg_line_length=None): |
||||||
|
""" |
||||||
|
大文件的尾行,小文件会导致报错 |
||||||
|
taillines : 读取尾部多少行 |
||||||
|
avg_line_length:每行字符平均数, |
||||||
|
return_str:返回类型,默认为字符串,False为列表。 |
||||||
|
offset:每次循环相对文件末尾指针偏移数 |
||||||
|
f.tell() 当前指针位置 |
||||||
|
f.seek(a,b) a 偏移量, b:0 1 2 ,文件头 当前位置 文件尾部 |
||||||
|
""" |
||||||
|
with open(file, errors='ignore') as f: |
||||||
|
if not avg_line_length: |
||||||
|
f.seek(0, 2) |
||||||
|
f.seek(f.tell() - 3000) |
||||||
|
avg_line_length = int(3000 / len(f.readlines())) + 10 |
||||||
|
f.seek(0, 2) |
||||||
|
end_pointer = f.tell() |
||||||
|
offset = taillines * avg_line_length |
||||||
|
if offset > end_pointer: |
||||||
|
f.seek(0, 0) |
||||||
|
lines = f.readlines()[-taillines:] |
||||||
|
return "".join(lines) if return_str else lines |
||||||
|
offset_init = offset |
||||||
|
i = 1 |
||||||
|
while len(f.readlines()) < taillines: |
||||||
|
location = f.tell() - offset |
||||||
|
f.seek(location) |
||||||
|
i += 1 |
||||||
|
offset = i * offset_init |
||||||
|
if f.tell() - offset < 0: |
||||||
|
f.seek(0, 0) |
||||||
|
break |
||||||
|
else: |
||||||
|
f.seek(end_pointer - offset) |
||||||
|
lines = f.readlines() |
||||||
|
if len(lines) >= taillines: |
||||||
|
lines = lines[-taillines:] |
||||||
|
|
||||||
|
return "".join(lines) if return_str else lines |
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__": |
||||||
|
d = DataPlot() |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,126 @@ |
|||||||
|
import threading |
||||||
|
import time |
||||||
|
|
||||||
|
class Mythead(threading.Thread): |
||||||
|
'''线程守护''' |
||||||
|
def __init__(self ): |
||||||
|
super(Mythead, self).__init__() |
||||||
|
pass |
||||||
|
|
||||||
|
def set_task(self, func, *args): |
||||||
|
self.func = func |
||||||
|
self.args = args |
||||||
|
|
||||||
|
def run(self): |
||||||
|
# print(f" --- {len(self.args)}") |
||||||
|
if len(self.args) > 0: |
||||||
|
self.func(self.args) |
||||||
|
else: |
||||||
|
self.func( ) |
||||||
|
|
||||||
|
class Multithread(threading.Thread): |
||||||
|
''' |
||||||
|
多线程 |
||||||
|
子线程.join() -> ( 设置在start之后, 等所有阻塞线程运行完, 再运行主线程 ) |
||||||
|
子线程.setDaemon(True) -> 设置子线程A为守护线程, 主线程所在的进程内所有非守护线程统统运行完毕, |
||||||
|
无论子线程A有没有结束, 程序都结束 |
||||||
|
Method: |
||||||
|
|
||||||
|
''' |
||||||
|
def __init__(self): |
||||||
|
super(Multithread, self).__init__() |
||||||
|
self.__tasks = [] |
||||||
|
self.act = [] |
||||||
|
# self.__block = False |
||||||
|
pass |
||||||
|
|
||||||
|
# def set_task( self, tasks ): |
||||||
|
# self.__tasks = tasks |
||||||
|
|
||||||
|
def add_task(self, func, daemon=False, join=True,args=()): |
||||||
|
tmp_dict = {} |
||||||
|
tmp_dict.update( {"func" : func}) |
||||||
|
if daemon == True: |
||||||
|
tmp_dict.update( {"daemon" : True}) |
||||||
|
else: |
||||||
|
tmp_dict.update( {"daemon" : False}) |
||||||
|
if join == True: |
||||||
|
tmp_dict.update( {"join" : True}) |
||||||
|
else: |
||||||
|
tmp_dict.update( {"join" : False}) |
||||||
|
if args == (): |
||||||
|
tmp_dict.update( {"args" : ()}) |
||||||
|
else: |
||||||
|
tmp_dict.update( {"args" : args}) |
||||||
|
self.__tasks.append( tmp_dict ) |
||||||
|
|
||||||
|
def remove_tasks(self, ): |
||||||
|
self.__tasks = [] |
||||||
|
self.act = [] |
||||||
|
|
||||||
|
def add_task_2_act(self, task): |
||||||
|
t = threading.Thread( target = task['func'], args = task['args'] ) |
||||||
|
self.act.append(t) |
||||||
|
t.start() |
||||||
|
|
||||||
|
def execute_one_act(self,i): |
||||||
|
if self.__tasks[i]['join']: |
||||||
|
self.act[i].join() # 子线程阻塞完毕再运行主线程 |
||||||
|
pass |
||||||
|
|
||||||
|
def prepare_tasks(self): |
||||||
|
self.act = [] |
||||||
|
for task in self.__tasks: |
||||||
|
self.add_task_2_act(task) |
||||||
|
|
||||||
|
def execute_tasks(self): |
||||||
|
try: |
||||||
|
for i in range( len(self.act) ): |
||||||
|
self.execute_one_act( i ) |
||||||
|
pass |
||||||
|
except Exception as e: |
||||||
|
print(e) |
||||||
|
|
||||||
|
def prepare_tasks(self): |
||||||
|
self.act = [] |
||||||
|
for task in self.__tasks: |
||||||
|
t = threading.Thread( target = task['func'], args = task['args'] ) |
||||||
|
self.act.append(t) |
||||||
|
t.start() |
||||||
|
|
||||||
|
def simultaneously_execute_tasks(self): |
||||||
|
self.prepare_tasks() |
||||||
|
self.execute_tasks() |
||||||
|
|
||||||
|
def sequently_execute_tasks(self): |
||||||
|
for task in self.__tasks: |
||||||
|
t = threading.Thread( target = task['func'], args = task['args'] ) |
||||||
|
t.start() |
||||||
|
t.join() |
||||||
|
|
||||||
|
|
||||||
|
def t1(self): |
||||||
|
print("thread1...") |
||||||
|
time.sleep(10) |
||||||
|
print("thread1... after sleep...") |
||||||
|
|
||||||
|
def t2(self): |
||||||
|
print("thread2...") |
||||||
|
time.sleep(5) |
||||||
|
print("thread2... after sleep...") |
||||||
|
|
||||||
|
def t3(self): |
||||||
|
print("thread3...") |
||||||
|
time.sleep(3) |
||||||
|
print("thread3... after sleep...") |
||||||
|
|
||||||
|
if __name__ == '__main__': |
||||||
|
mt = Multithread() |
||||||
|
mt.add_task(mt.t1) |
||||||
|
mt.add_task(mt.t2) |
||||||
|
mt.add_task(mt.t3) |
||||||
|
# mt.prepare_tasks() # 线程同步运行 |
||||||
|
# mt.execute_tasks() |
||||||
|
# mt.simultaneously_execute_tasks() |
||||||
|
mt.sequently_execute_tasks() |
||||||
|
|
||||||
@ -0,0 +1,100 @@ |
|||||||
|
#!/usr/bin/env python |
||||||
|
# -*- encoding: utf-8 -*- |
||||||
|
import wx |
||||||
|
# from configobj import ConfigObj |
||||||
|
from myconfig import MyConfig |
||||||
|
from myconfig import YAML_FILE_NAME |
||||||
|
|
||||||
|
class UI_Plot_Setting(wx.Dialog): |
||||||
|
""" |
||||||
|
@description : 绘图 配置 |
||||||
|
""" |
||||||
|
def __init__(self, parent, id): |
||||||
|
# 串口页面配置 |
||||||
|
super(UI_Plot_Setting, self).__init__( parent ,id = id ) |
||||||
|
self.config = MyConfig() |
||||||
|
self.InitUI() |
||||||
|
self.SetSize((400, 400)) |
||||||
|
self.SetTitle(" 绘图 序列号 ") |
||||||
|
|
||||||
|
def InitUI(self): |
||||||
|
self.config_yml = self.config.read_rtv_yaml() |
||||||
|
|
||||||
|
self.panel = wx.Panel(self) |
||||||
|
self.vbox = wx.BoxSizer(wx.VERTICAL) |
||||||
|
|
||||||
|
self.sb = wx.StaticBox(self.panel, label='指定绘图设置 ') |
||||||
|
self.sbs = wx.StaticBoxSizer(self.sb, orient=wx.VERTICAL) |
||||||
|
|
||||||
|
self.hbox1 = wx.BoxSizer(wx.HORIZONTAL) |
||||||
|
self.staticText1 = wx.StaticText(self.panel, label='起始行号 ',size=(60, -1), style=wx.ALIGN_CENTRE_VERTICAL ) |
||||||
|
self.textCtrl1 = wx.TextCtrl(self.panel, value="",size=(250,25) ) |
||||||
|
tmp = self.get_str_from_config( "LineBegin" ) |
||||||
|
if tmp is not None: |
||||||
|
self.textCtrl1.SetValue(tmp) |
||||||
|
self.hbox1.Add(self.staticText1, flag=wx.TOP|wx.LEFT, border=5) |
||||||
|
self.hbox1.Add(self.textCtrl1, flag=wx.TOP|wx.LEFT, border=5) |
||||||
|
self.sbs.Add(self.hbox1, flag=wx.TOP|wx.LEFT, border= 5) |
||||||
|
|
||||||
|
self.hbox2 = wx.BoxSizer(wx.HORIZONTAL) |
||||||
|
self.staticText2 = wx.StaticText(self.panel, label='间隔行号: ' ,size=(60, -1)) |
||||||
|
# self.staticText2_1 = wx.StaticText(self.panel, label='分钟 ' ,size=(60, -1)) |
||||||
|
self.textCtrl2 = wx.TextCtrl(self.panel, value="",size=(250,25)) |
||||||
|
tmp = self.get_str_from_config( "LineInterval" ) |
||||||
|
if tmp is not None: |
||||||
|
self.textCtrl2.SetValue(tmp) |
||||||
|
self.hbox2.Add(self.staticText2, flag=wx.TOP|wx.LEFT, border=5) |
||||||
|
self.hbox2.Add(self.textCtrl2,flag=wx.TOP|wx.LEFT, border=5) |
||||||
|
# self.hbox2.Add(self.staticText2_1, flag=wx.TOP|wx.LEFT, border=5) |
||||||
|
self.sbs.Add(self.hbox2, flag=wx.TOP|wx.LEFT, border=5) |
||||||
|
|
||||||
|
self.panel.SetSizer(self.sbs) |
||||||
|
|
||||||
|
self.hbox_0 = wx.BoxSizer(wx.HORIZONTAL) |
||||||
|
self.okButton = wx.Button(self, label=u'保存配置') |
||||||
|
self.closeButton = wx.Button(self, label='Close') |
||||||
|
self.hbox_0.Add(self.okButton) |
||||||
|
self.hbox_0.Add(self.closeButton, flag = wx.LEFT, border=5) |
||||||
|
|
||||||
|
# 添加 vbox 到panel |
||||||
|
self.vbox.Add(self.panel, proportion=1, |
||||||
|
flag=wx.ALL | wx.EXPAND, border=5) |
||||||
|
|
||||||
|
self.vbox.Add(self.hbox_0, flag=wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM, border=10) |
||||||
|
|
||||||
|
self.SetSizer(self.vbox) |
||||||
|
|
||||||
|
self.okButton.Bind(wx.EVT_BUTTON, self.OnSave) |
||||||
|
self.closeButton.Bind(wx.EVT_BUTTON, self.OnClose) |
||||||
|
|
||||||
|
def get_str_from_config( self, key ): |
||||||
|
return str(self.config_yml[key]) |
||||||
|
pass |
||||||
|
|
||||||
|
def set_config_by_key_val( self, key, val ): |
||||||
|
# print(f" {key} current type {type( self.config_yml[section][key] )}") |
||||||
|
if type( self.config_yml [key] ) == int: |
||||||
|
self.config_yml [key] = int(val) |
||||||
|
elif type( self.config_yml [key] ) == float: |
||||||
|
self.config_yml [key] = float(val) |
||||||
|
else: |
||||||
|
self.config_yml[key] = val |
||||||
|
pass |
||||||
|
|
||||||
|
|
||||||
|
def saveData(self, e): |
||||||
|
pass |
||||||
|
|
||||||
|
def OnClose(self, e): |
||||||
|
|
||||||
|
self.Destroy() |
||||||
|
|
||||||
|
def OnSave(self, e): |
||||||
|
success = True |
||||||
|
# 赋值字典,写入文件 |
||||||
|
self.set_config_by_key_val( "LineBegin",self.textCtrl1.GetValue( )) |
||||||
|
self.set_config_by_key_val( "LineInterval",self.textCtrl2.GetValue( )) |
||||||
|
self.config.write_rtv_yaml(self.config_yml) |
||||||
|
del self.config |
||||||
|
if success: |
||||||
|
self.EndModal(wx.ID_OK) |
||||||
Loading…
Reference in new issue