1 Star 0 Fork 24

walkskyer / SerialGenius

forked from edwinfound / SerialGenius 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
SerialGenius.py 18.06 KB
一键复制 编辑 原始数据 按行查看 历史
Eamon 提交于 2015-08-30 03:05 . feature: 初始化版本
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541
#coding:utf-8
import sys;
import new;
import Config;
import wx;
import os;
import webbrowser;
import IniFile;
import wx.lib.rcsizer as rcs;
import wx.lib.intctrl;
import Global;
import Loading;
import string;
import ELog;
import traceback;
import array;
import time;
import numpy;
import matplotlib;
import matplotlib.figure;
import matplotlib.backends.backend_wxagg;
import matplotlib.backends.backend_wx;
# matplotlib采用WXAgg为后台,将matplotlib嵌入wxPython中
#matplotlib.use("WXAgg")
try:
from agw import fourwaysplitter as FWS
except ImportError: # if it's not there locally, try the wxPython lib.
try:
import wx.lib.agw.fourwaysplitter as FWS
except ImportError:
exit()
#菜单ID
from AppIds import *
import SerialUtil
import wx.lib.newevent
#Frame start
SERIAL_GENIUS_FS_CHAR=0x0F;
#Slash
SERIAL_GENIUS_SL_CHAR=0x1F;
#主要的4个窗口
class PanelMain(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent, id = ID_WINDOW_PANEL_MAIN)
self.splitter = FWS.FourWaySplitter(self, agwStyle=wx.SP_LIVE_UPDATE);
self.splitter.SetAGWWindowStyleFlag(wx.SP_LIVE_UPDATE)
sizer = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(self.splitter, 1, wx.EXPAND)
self.SetSizer(sizer)
self.windowShowIndexs=[];
#动态导入所有的模块并加载
self.modules=[];
for mod in Global.Modules:
try:
exec 'import module.'+mod;
exec 'self.modules.append(module.'+mod+'.'+(mod.capitalize())+'(self.splitter))';
except:
ELog.Trace();
pass
#初始化模块
for mod in self.modules:
mod.Hide();
mod.isUsing=False;
flag=False;
for i in range(0, len(self.modules)):
if Config.APP_CONFIG['setting']['show_modules'].find('['+str(i)+']')>=0:
self.UseModule(i,True);
flag=True;
#如果没有预设的窗口,显示0 1 2 3
if not flag:
self.UseModule(0,True);
self.UseModule(1,True);
self.UseModule(2,True);
self.UseModule(3,True);
#返回已使用的模块数
def UsedModuleNumber(self):
return len(self.windowShowIndexs);
#设置模块可用与否
def UseModule(self, index, use):
if index<0 or index>len(self.modules)-1:
return;
if use:
if self.UsedModuleNumber()>=4:
return;
findWindow=False;
for i in range(0, len(self.windowShowIndexs)):
if self.windowShowIndexs[i]==index:
findWindow=True;
if not findWindow:
self.windowShowIndexs.append(index);
Global.var['PanelTool'].checkboxLayouts[index].SetValue(True);
self.splitter.AppendWindow(self.modules[index]);
self.modules[index].Show();
self.modules[index].isUsing=True;
else:
if self.UsedModuleNumber()<=1:
return;
findWindow=False;
findIndex=0;
for i in range(0, len(self.windowShowIndexs)):
if self.windowShowIndexs[i]==index:
findIndex=i;
findWindow=True;
if findWindow:
del self.windowShowIndexs[findIndex];
Global.var['PanelTool'].checkboxLayouts[index].SetValue(False);
self.splitter.DetachWindow(self.modules[index]);
self.modules[index].Hide();
self.modules[index].isUsing=False;
if self.UsedModuleNumber()==1:
self.splitter.SetExpanded(0)
elif self.UsedModuleNumber()==2:
self.splitter.SetExpanded(-1)
self.splitter.SetVSplit(10000)
else:
self.splitter.SetExpanded(-1)
self.splitter.SetVSplit(5000)
# 左侧工具栏窗口
class PanelTool(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent, id = ID_WINDOW_PANEL_TOOL)
sizer = wx.BoxSizer(wx.VERTICAL)
#串口
ports=["None"];
for port in SerialUtil.GetValidPort():
ports.append('COM'+str(port+1));
sizer.Add(wx.StaticText(self, -1, u"串口"), 0, wx.ALL, 2)
self.comboPort = wx.ComboBox(self, -1, choices=ports,
style=wx.CB_READONLY|wx.CB_DROPDOWN)
if Config.APP_CONFIG['setting']['default_port'] in ports:
self.comboPort.SetStringSelection(Config.APP_CONFIG['setting']['default_port']);
else:
self.comboPort.SetStringSelection("None")
sizer.Add(self.comboPort, 0, wx.ALL , 2)
#刷新
self.btnRefreshPort = wx.Button(self, 0, u"刷新", size=(50,-1))
self.btnRefreshPort.Bind(wx.EVT_BUTTON, self.OnRefreshPort)
self.btnRefreshPort.SetSize(self.btnRefreshPort.GetBestSize())
sizer.Add(self.btnRefreshPort, 0, wx.ALL , 2)
#波特率
sizer.Add(wx.StaticText(self, -1, u"波特率"), 0, wx.ALL, 2)
baudrates=[];
for rate in SerialUtil.BAUDRATES:
baudrates.append(str(rate))
self.comboBaudrate = wx.ComboBox(self, -1, choices=baudrates,
style=wx.CB_READONLY|wx.CB_DROPDOWN)
if Config.APP_CONFIG['setting']['default_baudrate'] in baudrates:
self.comboBaudrate.SetStringSelection(Config.APP_CONFIG['setting']['default_baudrate']);
else:
self.comboBaudrate.SetStringSelection("9600")
sizer.Add(self.comboBaudrate, 0, wx.ALL , 2)
#数据位
sizer.Add(wx.StaticText(self, -1, u"数据位"), 0, wx.ALL, 2)
bytesizes=list(SerialUtil.BYTESIZES);
default_bytesize=None;
for i in range(0,len(bytesizes)):
bytesizes[i]=str(bytesizes[i]);
if Config.APP_CONFIG['setting']['default_bytesize']==bytesizes[i]:
default_bytesize=bytesizes[i];
bytesizes.sort();
self.comboBytesize = wx.ComboBox(self, -1, choices=bytesizes,
style=wx.CB_READONLY|wx.CB_DROPDOWN)
if default_bytesize:
self.comboBytesize.SetStringSelection(default_bytesize);
else:
self.comboBytesize.SetStringSelection(bytesizes[0])
sizer.Add(self.comboBytesize, 0, wx.ALL , 2)
#停止位
sizer.Add(wx.StaticText(self, -1, u"停止位"), 0, wx.ALL, 2)
stopbits=list(SerialUtil.STOPBITS);
default_stopbit=None;
for i in range(0,len(stopbits)):
stopbits[i]=str(stopbits[i])
if Config.APP_CONFIG['setting']['default_stopbits']==stopbits[i]:
default_stopbit=stopbits[i];
stopbits.sort();
self.comboStopbits = wx.ComboBox(self, -1, choices=stopbits,
style=wx.CB_READONLY|wx.CB_DROPDOWN)
if default_stopbit:
self.comboStopbits.SetStringSelection(default_stopbit);
else:
self.comboStopbits.SetStringSelection(stopbits[0])
sizer.Add(self.comboStopbits, 0, wx.ALL , 2)
#校验
sizer.Add(wx.StaticText(self, -1, u"校验"), 0, wx.ALL, 2)
paritys=[];
default_parity=None;
for key, value in SerialUtil.PARITY_NAMES.items():
paritys.append(value);
if Config.APP_CONFIG['setting']['default_parity']==value:
default_parity=value;
paritys.sort();
self.comboParity = wx.ComboBox(self, -1, choices=paritys,
style=wx.CB_READONLY|wx.CB_DROPDOWN)
if default_bytesize:
self.comboParity.SetStringSelection(default_parity);
else:
self.comboParity.SetStringSelection(paritys[0])
sizer.Add(self.comboParity, 0, wx.ALL , 2)
#打开
sizer.Add(wx.StaticText(self, -1, u""), 0, wx.ALL, 2) #占位
self.btnOpenPort = wx.Button(self, 0, u"打开")
self.btnOpenPort.Bind(wx.EVT_BUTTON, self.OnOpenPort)
sizer.Add(self.btnOpenPort, 0, wx.ALL , 2)
#显示所有模块
self.checkboxLayouts=[];
for modname in Global.ModulesName:
cb = wx.CheckBox(self, -1, modname);
sizer.Add(cb, 0, wx.ALL, 2);
self.checkboxLayouts.append(cb);
cb.Bind(wx.EVT_CHECKBOX, self.OnLayoutNumberChange);
#意见反馈
try:
try:
from agw import hyperlink as hl
except ImportError:
import wx.lib.agw.hyperlink as hl
sizer.Add(wx.StaticText(self, -1, u""), 0, wx.ALL, 2) #占位
sizer.Add(hl.HyperLinkCtrl(self, -1, u"意见反馈", URL=Global.app['suggestion_url']))
except:
pass
#设置布局
border = wx.BoxSizer()
border.Add(sizer, 1, wx.EXPAND|wx.ALL, 5)
self.SetSizer(border)
#更改显示模块
def OnLayoutNumberChange(self, event):
passed=True;
if event.GetEventObject().GetValue():
if Global.var['PanelMain'].UsedModuleNumber()>=4:
wx.MessageBox(u'最多只能显示4个');
passed=False;
else:
if Global.var['PanelMain'].UsedModuleNumber()<=1:
wx.MessageBox(u'至少选择一个');
passed=False;
if passed:
Config.APP_CONFIG['setting']['show_modules']='';
for i in range(0, len(self.checkboxLayouts)):
Global.var['PanelMain'].UseModule(i,self.checkboxLayouts[i].GetValue());
if self.checkboxLayouts[i].GetValue():
Config.APP_CONFIG['setting']['show_modules']+='['+str(i)+']';
else:
event.GetEventObject().SetValue(not event.GetEventObject().GetValue());
Global.var['PanelMain'].splitter.Refresh();
Global.var['PanelMain'].Refresh();
Global.var['PanelTool'].Refresh();
#打开串口
def OnOpenPort(self, event, forceClose=False):
if (Global.SerialGeniusPort and Global.SerialGeniusPort.running ) or forceClose:
Global.SerialGeniusPort.stop();
self.btnOpenPort.SetLabel(u'打开');
self.comboPort.Enable(True);
self.btnRefreshPort.Enable(True);
self.comboBaudrate.Enable(True);
self.comboBytesize.Enable(True);
self.comboStopbits.Enable(True);
self.comboParity.Enable(True);
return;
if self.comboPort.GetCurrentSelection() <= 0:
wx.MessageBox(u"请选择串口", u"提示");
return;
try:
Config.APP_CONFIG['setting']['default_port']=self.comboPort.GetStringSelection();
t_port=int(Config.APP_CONFIG['setting']['default_port'][3:])-1;
Config.APP_CONFIG['setting']['default_baudrate']=self.comboBaudrate.GetStringSelection();
t_baudrate=int(Config.APP_CONFIG['setting']['default_baudrate']);
Config.APP_CONFIG['setting']['default_bytesize']=self.comboBytesize.GetStringSelection();
t_bytesize=int(Config.APP_CONFIG['setting']['default_bytesize']);
Config.APP_CONFIG['setting']['default_parity']=self.comboParity.GetStringSelection();
t_parity=Config.APP_CONFIG['setting']['default_parity'];
for key, value in SerialUtil.PARITY_NAMES.items():
if t_parity==value:
t_parity=key;
break;
Config.APP_CONFIG['setting']['default_stopbits']=self.comboStopbits.GetStringSelection();
t_stopbits=float(Config.APP_CONFIG['setting']['default_stopbits']);
if t_stopbits==1.0:
t_stopbits=1;
elif t_stopbits==2.0:
t_stopbits=2;
except:
wx.MessageBox( u"打开串口失败:0x01", u"提示");
ELog.Trace();
return;
t_timeout=2
#print t_port, t_baudrate, t_bytesize, t_parity, t_stopbits, t_timeout
Global.SerialGeniusPort=SerialUtil.SerialThread(port=t_port,
baudrate=t_baudrate,
bytesize=t_bytesize,
parity=t_parity,
stopbits=t_stopbits,
timeout=t_timeout);
if False==Global.SerialGeniusPort.start():
wx.MessageBox( u"打开串口失败:0x02", u"提示");
return;
else:
self.comboPort.Enable(False);
self.btnRefreshPort.Enable(False);
self.comboBaudrate.Enable(False);
self.comboBytesize.Enable(False);
self.comboStopbits.Enable(False);
self.comboParity.Enable(False);
self.btnOpenPort.SetLabel(u'关闭');
#刷新串口
def OnRefreshPort(self, event):
Loading.Show();
self.comboPort.Clear()
self.comboPort.Append("None");
for port in SerialUtil.GetValidPort():
self.comboPort.Append('COM'+str(port+1));
self.comboPort.SetStringSelection("None");
Loading.Hide();
#布局Panel
class PanelLayout(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
sizer = wx.BoxSizer(wx.HORIZONTAL);
Global.var['PanelTool']=PanelTool(self);
sizer.Add(Global.var['PanelTool']);
Global.var['PanelMain']=PanelMain(self);
sizer.Add(Global.var['PanelMain'], 1, wx.EXPAND);
self.SetSizer(sizer);
#主框架
class MainFrame(wx.Frame):
def __init__(self, parent, title):
#获取系统环境信息
self._EnvironmentInit()
wx.Frame.__init__( self,
parent,
id=-1,
title=title,
pos=wx.DefaultPosition,
size=(800, 600),
style=wx.DEFAULT_FRAME_STYLE | wx.SUNKEN_BORDER | wx.CLIP_CHILDREN )
#窗口初始化
self._WindowInit()
#初始化状态栏
self._StatusBarInit()
#self._UpdateStatusBar(u"正在加载...");
self._UpdateStatusBar(u"欢迎使用SerialGenius!");
#设置Icon
try:
self.icon = wx.Icon(Global.env['app_root']+'dll/ico.dll', wx.BITMAP_TYPE_ICO);
self.SetIcon(self.icon);
except:
ELog.Trace();
# 设置布局
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(PanelLayout(self), 1, wx.EXPAND)
self.SetSizer(sizer)
sizer.Layout()
# startup window
try:
from agw import advancedsplash as AS
except ImportError: # if it's not there locally, try the wxPython lib.
import wx.lib.agw.advancedsplash as AS
try:
frame = AS.AdvancedSplash(self,
bitmap=wx.Bitmap(Global.env['app_root']+"dll/su.dll", wx.BITMAP_TYPE_PNG),
timeout=3000,
agwStyle=AS.AS_TIMEOUT | AS.AS_CENTER_ON_SCREEN)
# remove default click close handler
frame.Bind(wx.EVT_LEFT_DOWN, self.OnYummy)
frame.Bind(wx.EVT_LEFT_UP, self.OnYummy)
frame.Bind(wx.EVT_RIGHT_DOWN, self.OnYummy)
frame.Bind(wx.EVT_RIGHT_UP, self.OnYummy)
except:
pass
# version check
import Version
Version.AutoCheckVersion()
def OnYummy(self, event):
pass
################# Private #################
#环境初始化
def _EnvironmentInit(self):
mm=wx.DisplaySize()
Global.env['screen']['width']=mm[0]
Global.env['screen']['height']=mm[1]
root = os.path.dirname(os.path.abspath(sys.argv[0]))
if root[-1:]!=os.sep:
root = root + os.sep
Global.env['app_root']=root
#窗口初始化
def _WindowInit(self):
#设置最小显示
self.SetMinSize(wx.Size(400, 300))
#关闭提示
self.Bind(wx.EVT_CLOSE,self._OnClose)
#在中间显示
self.CenterOnScreen()
#状态栏初始化
def _StatusBarInit(self):
self._statusbar = self.CreateStatusBar(2, wx.ST_SIZEGRIP)
self._statusbar.SetStatusWidths([-1, 300])
self._statusbar.SetStatusText(Config.APP_CONFIG['copyright'],1)
def _SafetyCloseWindow(self,event):
# 如果串口已打开,尝试关闭
if (Global.SerialGeniusPort and Global.SerialGeniusPort.running ):
Global.SerialGeniusPort.stop();
#保存当前配置
IniFile.Save();
if event == None :
self.Destroy()
else:
event.Skip()
################# Public #################
#改变状态栏
def _UpdateStatusBar(self,text):
self._statusbar.SetStatusText(text, 0)
############## Windows Event #############
def _OnClose(self,event):
self._SafetyCloseWindow(event)
class MainApp(wx.App):
def OnInit(self):
#加载配置
IniFile.Load();
Global.var['Frame'] = MainFrame(None, Config.APP_CONFIG['name']+' V'+Config.APP_CONFIG['version']+' - '+Config.APP_CONFIG['description'])
self.SetTopWindow(Global.var['Frame'])
Global.var['Frame'].Show(True)
return True
if __name__ == '__main__':
app = MainApp();
app.MainLoop();
1
https://gitee.com/walkskyer/SerialGenius.git
git@gitee.com:walkskyer/SerialGenius.git
walkskyer
SerialGenius
SerialGenius
master

搜索帮助