Ai
1 Star 0 Fork 16

吴侃/代码编辑器

forked from 阿德/代码编辑器 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
texteditor2.py 63.97 KB
一键复制 编辑 原始数据 按行查看 历史
阿德 提交于 2020-06-05 14:58 +08:00 . Signed-off-by: huangweide001 85042684@qq.com
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342
#!/usr/bin/env python3
import sys, time
import os, codecs
import logging
from array import array
import PyQt5.sip
import binascii
#========
import serial
import serial.tools.list_ports
from PyQt5.QtCore import QSettings,QFile, QByteArray, QEvent, pyqtSignal, Qt , QSignalMapper, \
QTextCodec, QFileInfo, QTimer
#(QFile, QFileInfo, , QSignalMapper,\ QTextCodec, QTimer,Qt,QByteArray, QEvent, )
from PyQt5.QtWidgets import (QAction, QApplication, QFileDialog,QTreeWidget, QDockWidget , QTreeWidgetItem, \
QSplitter, QMainWindow, QMessageBox, QTextEdit,QMdiArea,QWidget, QMenu, QActionGroup, QFontDialog)
from PyQt5.QtGui import QIcon,QKeySequence, QCursor, QFont, QCloseEvent
from textedit import QtextEditClick, SciTextEdit
import qrc_resources
from Dom_do_cbp import Dom4cbp
from compileProject import compileProject
from stcflash import *
from downloadSetting import Setting
from lexer_c_getfunc import lexer_c_getfunc, g_allFuncList, g_includeList
from _compileSetting import complierSetting
from Ui_FineText import FindText
from ColorDlg import ColorDlg, g_colorDict
from pyserial_demo import Pyqt5_Serial
import copy
PROTOCOL_12C5A = "12c5a"
PROTOCOL_15F2K ="15F2K"
PROTOCOL_8F2K ="8F2K"
__version__ = "1.0.0"
class MainWindow(QMainWindow):
Jump2Func_Signal = pyqtSignal(str)
Jump2IncludeFile_Signal = pyqtSignal(str)
def __init__(self, parent=None):
global g_colorDict
super(MainWindow, self).__init__(parent)
self.isComplierPathDefault='0'
self.isXdataDefault = '0'
self.XdataLen = '8192'
self.downloadWay=''
self.DIYString=''
self.baudArray=[9600, 19200, 38400, 57600, 115200]
self.baudIndex=0
self.Chipstr=''
self.Portstr=''
self.fullfile='' #project file
self.ProjectDir=''
self.Hexfile=''
self.file_list = [] #c文件,h文件列表初始化 self.h_list = []
#self.includeList=[]
self.file_list.clear()
self.fileFuncDict={}
self.autoOpenCOM='0'
self.mycbp=''
self.compileIncldue=''
self.Code51_dir = os.getcwd().replace("\\", "/").replace("\\", "/") # 本软件所在的路径
self.EditFont = QFont('Courier', 12)
self.colorDict=copy.deepcopy(g_colorDict)
#窗口布局:
self.tree=QTreeWidget() #树状控件,内置于工程视图
self.tree.setColumnCount(1) #设置列数
self.tree.header().hide() #隐藏 置树形控件头部的标题,有多列时有用。
#1.1创建 工程视图(标题,自身窗口),占右边
self.dockProject=QDockWidget('Project',self)
self.dockProject.setWidget(self.tree)
self.dockProject.setMinimumSize(180,600) # 设置最小尺寸:宽=180,高=600
#1.2创建多文档视图
self.mdi = QMdiArea()
self.mdi.setViewMode(QMdiArea.TabbedView) #设置为Tab多页显示模式
self.mdi.setTabsClosable(1) #设置多文档页面可关闭
self.text_browser = QtextEditClick(self) #QtextEditClick继承自QTextEdit,内置于信息输出视图
self.text_browser.setReadOnly(True) #仅作为信息输出,设置“只读”属性
#1.3创建信息输出视图
self.dockBuilt=QDockWidget('Built output',self)
self.dockBuilt.setMinimumSize(600,150) # 宽=600,高= 150
self.dockBuilt.setWidget(self.text_browser)
#1.4QSplitter(分隔布局容器)布局分上下(垂直),比例3:1
splitter1 = QSplitter(Qt.Vertical)
splitter1.addWidget(self.mdi) #多文档视图占布局右上
splitter1.addWidget(self.dockBuilt) #信息输出视图占布局右下
self.addDockWidget(Qt.LeftDockWidgetArea,self.dockProject)#工程视图占布局左边
self.setCentralWidget(splitter1)
#splitter1.setStretchFactor(0, 2) #splitter1.setStretchFactor(1, 1)
#2.生成菜单,工具栏
fileNewAction = self.createAction("&New", self.fileNew,
QKeySequence.New, "filenew", "Create a text file")
fileOpenAction = self.createAction("&Open...", self.fileOpen,
QKeySequence.Open, "fileopen",
"Open an existing text file")
fileSaveAction = self.createAction("&Save", self.fileSave,
QKeySequence.Save, "filesave", "Save the text")
fileSaveAsAction = self.createAction("Save &As...",
self.fileSaveAs, icon="filesaveas",
tip="Save the text using a new filename")
fileSaveAllAction = self.createAction("Save A&ll",
self.fileSaveAll, "filesave",
tip="Save all the files")
fileQuitAction = self.createAction("&Quit", self.close,
"Ctrl+Q", "filequit", "Close the application")
editUndoAction = self.createAction("&Copy", self.editUndo,
QKeySequence.Undo, "undo",
"Undo")
editRedoAction = self.createAction("&Redo", self.editRedo,
QKeySequence.Redo, "redo",
"Redo")
editCopyAction = self.createAction("&Copy", self.editCopy,
QKeySequence.Copy, "editcopy",
"Copy text to the clipboard")
editCutAction = self.createAction("Cu&t", self.editCut,
QKeySequence.Cut, "editcut",
"Cut text to the clipboard")
editPasteAction = self.createAction("&Paste", self.editPaste,
QKeySequence.Paste, "editpaste",
"Paste in the clipboard's text")
editFindAction = self.createAction("&Find", self.editFind,
QKeySequence.Find, 'find',
"Find text in files")
editFontAction = self.createAction("&Font Select选字体", self.getFont,
None, None,
"Select Font 选择字体")#getFont
projectNewAction =self.createAction("&New", self.ProjectNew, None, None,
'Creat a project')
projectOpenAction =self.createAction("&Open", self.ProjectOpen, None, None,
'Open project file')
projectCloseAction =self.createAction("&Close", self.ProjectClose, None, None,
'Close project')
projectBuiltAction =self.createAction("&Built", self.ProjectBuilt, Qt.Key_F8, "built",
'Built 编译 F8')
projectCleanAction =self.createAction("&Clean", self.ProjectClean, None, "clean",
'Clean project')#loadHEX2stc
projectLoadAction =self.createAction("&Download", self.ProjectDownload, Qt.Key_F9, "download2",
'donewload HEX 下载到芯片 F9')#
projectBuiltLoadAction =self.createAction("Built and &load", self.ProjectBuiltLoad, Qt.Key_F10, "built_down1",
'先编译后下载 F10')#
#TabbedAction = self.createAction("tabbed", self.setMdiTabbedWindow)
self.windowNextAction = self.createAction("&Next",
self.mdi.activateNextSubWindow, QKeySequence.NextChild)
self.windowPrevAction = self.createAction("&Previous",
self.mdi.activatePreviousSubWindow,
QKeySequence.PreviousChild)
self.windowCascadeAction = self.createAction("Casca&de",
self.mdi.cascadeSubWindows)
self.windowTileAction = self.createAction("&Tile",
self.mdi.tileSubWindows)
self.windowTabbedAction = self.createAction("tabbed", self.setMdiTabbedWindow)
self.windowRestoreAction = self.createAction("&Restore All",
self.windowRestoreAll)
self.windowMinimizeAction = self.createAction("&Iconize All",
self.windowMinimizeAll)
#self.windowArrangeIconsAction = self.createAction( "&Arrange Icons", self.mdi.arrangeIcons)
self.windowArrangeIconsAction = self.createAction(
"&Arrange Icons", self.windowMinimizeAll)
self.windowCloseAction = self.createAction("&Close",
self.mdi.closeActiveSubWindow, QKeySequence.Close)
self.windowShowProjectAction = self.createAction("&Project-Viewer",
self.showProjectWindow, None, None, checkable=True)
self.windowShowBuiltAction = self.createAction("&Built-Viewer",
self.showBuiltWindow, None, None, checkable=True)
self.windowMapper = QSignalMapper(self)
self.windowMapper.mapped[QWidget].connect(self.mdi.setActiveSubWindow)
#菜单1.file
fileMenu = self.menuBar().addMenu("&File")
#“fileMenu” 增加exampleMenu,再增加子菜单,example文件夹下面的每个子文件夹就是一个子菜单
#子菜单再增加Action,每个子子文件夹对应一个Action(就是工程名)
exampleMenu = QMenu('example', self)
fileMenu.addMenu(exampleMenu)
#0. exampleMenu 上的动作项链接到槽函数 OpenRecentProject
exampleMenu.triggered[QAction].connect(self.OpenRecentProject)
if os.path.exists(self.Code51_dir+'/example'):
#1. 遍历examp 文件夹下面的子文件夹
for dir in os.listdir(self.Code51_dir+'/example'):
if os.path.isfile(dir): #1.2 为文件 则忽略
continue
#2. 子文件夹也生成一个子子菜单
exampleSubMenu=QMenu(dir, self)
exampleMenu.addMenu(exampleSubMenu)
fulldir = self.Code51_dir+'/example'+'/'+dir
#3. 遍历子文件夹里面的子子文件夹,子子文件夹就是工程所在
for _dir in os.listdir(fulldir):
if os.path.isfile(_dir):
continue
# example dir _dir _dir.cbp
#3.1 举例 example/01BasicCode/01target001/01target001.cbp
sub_fulldir=fulldir+'/'+_dir+'/'+_dir+'.cbp'
#4. 将工程名创建为一个动作。
if os.path.exists(sub_fulldir):
fileAction = self.createAction(sub_fulldir, None, None, None,
'Open an example project', checkable=False)
exampleSubMenu.addAction(fileAction)
#================增加exampleMenu--完毕=====================
self.addActions(fileMenu, (fileNewAction, fileOpenAction,
fileSaveAction, fileSaveAsAction, fileSaveAllAction,
None, fileQuitAction))
editMenu = self.menuBar().addMenu("&Edit")
self.addActions(editMenu, (editUndoAction, editRedoAction, editCopyAction, editCutAction,
editPasteAction, editFindAction, editFontAction))#, TabbedAction
#创建project Menu
projectMenu = self.menuBar().addMenu("&Project")
self.addActions(projectMenu, (projectNewAction, projectOpenAction, projectCloseAction,
projectBuiltAction, projectCleanAction, projectLoadAction,
projectBuiltLoadAction))
#1. 创建RecentProject 子菜单,依附在 Project 菜单的最后一项
self.RecentProject = QMenu('recent Project', self)
projectMenu.addMenu(self.RecentProject)
fileGroup = QActionGroup(self)
#2.从《setting.ini》读入10个工程路径
settings=QSettings("setting.ini",QSettings.IniFormat)
settings.setIniCodec(QTextCodec.codecForName("utf-8"))
filesize= settings.beginReadArray("recentProject")
if filesize is not None:
#3. 每个 工程路径 就是一个动作项 Action
for i in range(filesize):
settings.setArrayIndex(i)
fileAction = self.createAction(settings.value("File_Name"), None, None, None,
'Open a project', checkable=True)
self.RecentProject.addAction(fileAction)
fileGroup.addAction(fileAction)
settings.endArray()
#4. 动作项触发信号链接到槽函数 OpenRecentProject
self.RecentProject.triggered[QAction].connect(self.OpenRecentProject)
#创建setting——menu
# -----Chip-select 1]12C5A ; 2]15F2K; 3]8F2K
# -----Port-select
SettingMenu = self.menuBar().addMenu("&Setting")
self.ChipMenu = QMenu('Chip', self)
self.ChipMenu.setIcon(QIcon(":/{0}.png".format("chip")))
SettingMenu.addMenu(self.ChipMenu)
Chip1 = self.createAction(PROTOCOL_12C5A, self.ChangChip, None, None,
'STC12C5A08S2',checkable=True )
Chip2 = self.createAction(PROTOCOL_15F2K, self.ChangChip, None, None,
'STC15F2K60S2', checkable=True)
Chip3 = self.createAction(PROTOCOL_8F2K, self.ChangChip, None, None,
'STC8F2K32S2', checkable=True)
PortGroup = QActionGroup(self) #QActionGroup 里面的项是互斥的,只能有一个被选中
PortGroup.addAction(Chip1)
PortGroup.addAction(Chip2)
PortGroup.addAction(Chip3)
self.addActions(self.ChipMenu, (Chip1, Chip2, Chip3))
# 根据 保存的设置信息,将对应的芯片项打钩
actions = self.ChipMenu.actions()
self.Chipstr = settings.value("Download/Chip" )
if self.Chipstr is not None:
for i in range(len(actions)):
if actions[i].text() == self.Chipstr:
actions[i].setChecked(True)
break
#生成 串口子菜单
self.PortMenu = QMenu('Port', self)
self.PortMenu.setIcon(QIcon(":/{0}.png".format("com32")))
DetectAct = self.createAction("&Detect Port", self.DetectPort, None, None,
'Creat a project')
SettingMenu.addMenu(self.PortMenu)
self.addActions(self.PortMenu,(DetectAct, None) )
#检测有效串口
self.DetectPort()
# 根据 保存的设置信息,将对应的串口打钩
actions = self.PortMenu.actions()
self.Portstr = settings.value("Download/Port" )
if self.Portstr is not None:
for i in range(2, len(actions)):
if actions[i].text() == self.Portstr:
actions[i].setChecked(True)
break
#在设置菜单3中增加一个弹出对话框,用于选择下载方式:1]断电;2]默认指令;3]自定义指令
SettingAction = self.createAction("Download way下载方式", self.OpenSettingDlg, None, None,
'选择下载方式', checkable=False)
self.downloadWay = settings.value("Download/way" )
if self.downloadWay is None:
self.downloadWay = '2'
self.DIYString=settings.value("Download/baudrateIndex")
if self.DIYString is not None: #借用DIYString
self.baudIndex=int(self.DIYString)
else:
self.baudIndex = 1
self.DIYString = settings.value("Download/DIY_Data" )
if self.DIYString is None:
self.DIYString = ''
#在设置菜单4中增加【编译设置】对话框,用于设置:1]编译路径;2]外部ram大小 --xdata 从工程文件中读取
complierSettingAction = self.createAction("complier编译设置", self.OpenComplierSettingDlg, None, None,
'设置编译器路径和外部ram大小', checkable=False)
colorSettingAction = self.createAction("颜色设置", self.OpenColorSettingDlg, None, None,
'设置关键字颜色', checkable=False)
self.addActions(SettingMenu,(SettingAction, complierSettingAction,colorSettingAction ))
self.isComplierPathDefault=settings.value("Complier/Path/Default" )
if self.isComplierPathDefault != None and self.isComplierPathDefault == '1':
self.compilePath = self.Code51_dir
else:
self.compilePath =settings.value("Complier/Path/Input" )
if self.compilePath is None:
self.compilePath = self.Code51_dir
self.compileIncldue = settings.value("Complier/Path/Include" )
if self.compileIncldue is None:
self.compileIncldue = ''
self.isXdataDefault=settings.value("Complier/Xdata/Default" )
if self.isXdataDefault is None:
self.isXdataDefault = '1'
#======菜单栏->工具->[1.转换文件编码格式;2.串口工具]
ToolMenu = self.menuBar().addMenu("&Tool")
toolEncodUTF8Action =self.createAction("&Encode to UTF8", self.encode2UTF8, None, None,
'Creat a project')
toolSerialAction =self.createAction("串口工具", self.OpenSerialDlg, None, None,
'打开串口调试工具')
self.addActions(ToolMenu, (toolEncodUTF8Action,toolSerialAction, None))
#===========================================================
self.windowMenu = self.menuBar().addMenu("&Window")
self.windowMenu.aboutToShow.connect(self.updateWindowMenu)
fileToolbar = self.addToolBar("File")
fileToolbar.setObjectName("FileToolbar")
self.addActions(fileToolbar, (fileNewAction, fileOpenAction,
fileSaveAction))
editToolbar = self.addToolBar("Edit")
editToolbar.setObjectName("EditToolbar")
self.addActions(editToolbar, (editUndoAction, editRedoAction,editCopyAction, editCutAction,
editPasteAction, editFindAction))
#builtToolbar
builtToolbar = self.addToolBar("Built")
builtToolbar.setObjectName("BuiltToolbar")
self.addActions(builtToolbar, (projectBuiltAction, projectLoadAction,
projectBuiltLoadAction))
self.autoOpenCOM=settings.value("Download/autoOpenCOM")
if self.autoOpenCOM == None:
self.autoOpenCOM = '0'
#settings = QSettings()
if settings.value("MainWindow/Geometry") or settings.value("MainWindow/State"):
self.restoreGeometry(
QByteArray(settings.value("MainWindow/Geometry")))
self.restoreState(
QByteArray(settings.value("MainWindow/State")))
fontFamily=settings.value("Font/Family")
if fontFamily == None:
fontFamily='Courier'
self.EditFont.setFamily(fontFamily)
fsize = settings.value("Font/pointSize")
if fsize !=None and fsize.isdigit():
self.EditFont.setPointSize(int(fsize))
else:
self.EditFont.setPointSize(12)
fsize = settings.value("Font/isBold")
if fsize =='1':
self.EditFont.setBold(True)
status = self.statusBar()
status.setSizeGripEnabled(False)
status.showMessage("Ready", 5000)
#读取 style 颜色
for style in self.colorDict.keys():
str1 = 'color/' + style
str1 = settings.value(str1)
if str1 is not None:
self.colorDict[style] = str1
# 给节点添加响应事件
self.tree.doubleClicked.connect(self.onTreeDoubleClicked)
self.updateWindowMenu()
#self.setWindowTitle("Text Editor")
#给树状文件列表添加右键菜单
self.tree.setContextMenuPolicy(Qt.CustomContextMenu)#开放右键策略
self.tree.customContextMenuRequested.connect(self.OnTreeRightMenuShow)#关联右键槽函数
#给SciTextEdit 文档编辑窗口右键菜单 发过来的消息
self.Jump2Func_Signal[str].connect(self.do_Jump2Function)#右键跳转到函数
self.Jump2IncludeFile_Signal[str].connect(self.do_Jump2IncludeFile)#右键跳转到包含文件
#给builtOutput窗口添加双击响应
self.text_browser.TextEdit2Click_Signal.connect(self.Jump2Error)
#串口工具-子窗口
self.SerialDlg = Pyqt5_Serial()
self.setGeometry(300, 300, 800, 600)
self.setWindowTitle('Editor for STC51')
self.setObjectName('Editor4STC51')
self.setWindowIcon(QIcon(":/{0}.png".format("writeC51")))
self.show()
def OpenSerialDlg(self):
if self.SerialDlg.bIsRunning is False:#还没有打开“串口工具”,可以打开
self.SerialDlg.bIsRunning=True
self.SerialDlg.show()
pass
def OpenColorSettingDlg(self):
SettingDlg = ColorDlg(self)
#2.打开对话框
ret = SettingDlg.exec_()
if not ret :
return
#3.保存设置
settings=QSettings("setting.ini",QSettings.IniFormat)
for style in self.colorDict.keys():
str1 = 'color/' + style
settings.setValue(str1, self.colorDict[style])
#4.将打开的文件关闭再重新打开
self.repaintMDI()
def GB2313_to_utf8(self, fullfilename):
fdir,fename=os.path.split(fullfilename)
newName=fdir+'/utf8-tmp.txt'
try:
f = open(fullfilename,'r', encoding="gb2312", errors="strict")
text=f.read()
except :
self.SetTipString("转换失败,源文件的编码格式不是gb2312。")
f.close()
return
newfile = codecs.open(newName,'w+', encoding="utf-8")
newfile.write(text.encode("utf-8").decode( encoding="utf-8" ))
newfile.flush()
newfile.close()
f.close()
time.sleep(0.05)
os.remove(fullfilename) #删除源文件
# 重命名新文件为旧文件名 os.rename(src , dst)
try:
os.rename( newName, fullfilename)
except(FileNotFoundError):
pass
#print("目录不存在")
def do_Jump2IncludeFile(self, str1):
end = len(str1)-1
start = 1
if str1[0] == '"': # "driver/STC8F.h" 可能1
if str1[1]=='.': # "./driver/STC8F.h" 可能2
start = 3
elif str1[1]=="\\" or str1[1]=="/" :# "/driver/STC8F.h" 可能3
start = 2
else:
pass
textEdit = self.mdi.activeSubWindow()
textEdit=textEdit.widget()
if textEdit is None :
return
_fdir,_fename=os.path.split(textEdit.filename)
fileName = _fdir+'/'+str1[start:end]
elif str1[0] == '<': #系统的包含文字在编译器目录下的 '/include/mcs51/'
_fdir,_fename=os.path.split(str1[1:end])
if 'nt' in os.name:#winndows系统
fileName = self.compilePath+'/include/mcs51/'+_fename
else:
fileName = self.compileIncldue+'/include/mcs51/'+_fename
else:
return
self.loadFile(fileName)
def do_Jump2Function(self, str1):
#传入参数str1 为函数名
for file in self.file_list: #查找文件列表中的c文件
if file[-2: ]=='.c' or file[-2: ]=='.C' :
[dirname,filename]=os.path.split(file)
_dict=self.fileFuncDict[filename] #这个字典是存放文件名,函数名,函数所在行信息的。
funcs=list(_dict.keys())
for func in funcs:
if func == str1: #1. 字典中的函数名和传参相等,则查找结束,跳转
for textEdit_MSW in self.mdi.subWindowList(): #1.1 遍历已打开文档,判断函数所在的文件是否已经打开
textEdit=textEdit_MSW.widget()
if textEdit.filename == file:
self.mdi.setActiveSubWindow(textEdit_MSW)
break
else: #1.2 确认该文件还没有打开,需要打开
self.loadFile(file)
textEdit=self.mdi.currentSubWindow().widget()
#2.跳转到该函数名所在的文件的行数
if textEdit != None:
# self.fileFuncDict[filename][str1] 就是行数,在字典中先查文件名,再查函数名
textEdit.setCursorPosition(self.fileFuncDict[filename][str1], 0 ) #设置光标的行数,列数
textEdit.setCaretLineBackgroundColor(Qt.lightGray) #光标所在行显示灰色
textEdit.setFocus() #当前文档赋给焦点
return
def encode2UTF8(self):
textEdit = self.mdi.activeSubWindow()
textEdit=textEdit.widget()
if textEdit is None :#or not isinstance(textEdit, QTextEdit)
return
#关闭文件 -->修改编码 --> 重新打开文件
file = textEdit.filename
if os.path.exists(file) ==False:
return
self.mdi.closeActiveSubWindow() #关闭窗口
self.GB2313_to_utf8(file) #修改编码格式
self.loadFile(file) #打开文件
pass
def OpenComplierSettingDlg(self):
if len(self.fullfile) ==0 or not isinstance(self.mycbp, Dom4cbp):
self.SetTipString("工程没有打开,无法设置Xdata。请打开工程。")
return
settings=QSettings("setting.ini",QSettings.IniFormat)
SettingDlg = complierSetting(self)
#1.初始化设置,xdata的参数不是通用的,每个工程都可以不同,要保存在工程文件中。
if self.isComplierPathDefault == '1':
SettingDlg.rdb_pathDefault.setChecked(True)
else:
SettingDlg.rdb_pathSelect.setChecked(True)
SettingDlg.lineEdit_path.setText(settings.value("Complier/Path/Input" ))
SettingDlg.lineEdit_include.setText(self.compileIncldue)
#1.1 非windows系统,把check_include 打钩
if 'nt' not in os.name :
SettingDlg.check_incPath.setChecked(True)
if self.isXdataDefault == '1':
SettingDlg.rdb_xdataDefault.setChecked(True)
SettingDlg.lineEdit_xdata.setEnabled(False)
else:
SettingDlg.radioButton.setChecked(True)
SettingDlg.lineEdit_xdata.setText(self.XdataLen)
#2.打开对话框
ret = SettingDlg.exec_()
if not ret :
return
#3.保存设置
if SettingDlg.rdb_pathDefault.isChecked():
self.isComplierPathDefault = '1'
else:
self.isComplierPathDefault = '0'
settings.setValue("Complier/Path/Default",self.isComplierPathDefault)
self.compilePath=SettingDlg.lineEdit_path.text()
self.compileIncldue = SettingDlg.lineEdit_include.text()
settings.setValue("Complier/Path/Input",self.compilePath)
settings.setValue("Complier/Path/Include",self.compileIncldue)
if SettingDlg.rdb_xdataDefault.isChecked():
self.isXdataDefault = '1'
SettingDlg.lineEdit_xdata.setText('8192')
else:
self.isXdataDefault = '0'
self.XdataLen = SettingDlg.lineEdit_xdata.text()
settings.setValue("Complier/Xdata/Default",self.isXdataDefault)
#settings.setValue("Complier/Xdata/Input",SettingDlg.lineEdit_xdata.text())
#写人工程文件
self.mycbp.SetOptionOfXram(self.XdataLen)
def OpenSettingDlg(self):
SettingDlg = Setting()
#1. 初始化对话框参数
if self.downloadWay == '1' :
SettingDlg.radioButton_1.setChecked(True)
elif self.downloadWay == '2' :
SettingDlg.radioButton_2.setChecked(True)
else :
SettingDlg.radioButton_3.setChecked(True)
SettingDlg.lineEdit.setText(self.DIYString)
SettingDlg.comboBox.setCurrentIndex(self.baudIndex)
SettingDlg.checkBox.setChecked(self.autoOpenCOM=='1')
#2.显示对话框
ret = SettingDlg.exec_()
#3. 对话框按下 OK 时,保存设置改动
if ret:
settings=QSettings("setting.ini",QSettings.IniFormat)
if SettingDlg.radioButton_1.isChecked():
self.downloadWay = '1'
settings.setValue("Download/way" , self.downloadWay)
elif SettingDlg.radioButton_2.isChecked():
self.downloadWay = '2'
settings.setValue("Download/way" , self.downloadWay)
else :
self.downloadWay = '3'
settings.setValue("Download/way" , self.downloadWay)
if SettingDlg.checkBox.isChecked():
self.autoOpenCOM='1'
else:
self.autoOpenCOM='0'
settings.setValue("Download/autoOpenCOM" ,self.autoOpenCOM)
self.DIYString=SettingDlg.lineEdit.text()
self.baudIndex=SettingDlg.comboBox.currentIndex()
settings.setValue("Download/DIY_Data" ,self.DIYString)
settings.setValue("Download/baudrateIndex", self.baudIndex)
def Jump2Error(self):
tc =self.text_browser.textCursor()
str1 = tc.block().text()
for filename in self.file_list:
if filename in str1:#找到错误行中的文件名,判断是否已经打开
for textEdit_MSW in self.mdi.subWindowList():
textEdit=textEdit_MSW.widget()
if textEdit.filename == filename:
self.mdi.setActiveSubWindow(textEdit_MSW)
break
else:
self.loadFile(filename)
str2 = str1[len(filename)+1:] # 错误提示格式:文件名+‘:'+行数+':'+错误信息,所有文件名长度要加1
split_list=str2.split(':', 1)
textEdit=self.mdi.currentSubWindow().widget()
if textEdit != None:
textEdit.setCursorPosition(int(split_list[0])-1, 0 )
textEdit.setFocus()
break
def OnTreeRightMenuShow(self, point): #当点击“source”和“header” 显示添加文件菜单;点击具体文件名时,显示删除文件菜单
item=self.tree.currentItem() #获取鼠标所在的树状列表的项
self.tree.popMenu = QMenu()
if '.' in item.text(0) and '.cbp' not in item.text(0):#该项是文件名,添加右键[删除菜单]
delectFile4Proj=QAction('Delect file from project', self)
self.tree.popMenu.addAction(delectFile4Proj)
delectFile4Proj.triggered.connect(self.do_delectFile4Proj)
else: #该项非文件名,添加右键[添加菜单]
addFile2Proj=QAction('Add file to project', self)
self.tree.popMenu.addAction(addFile2Proj)
addFile2Proj.triggered.connect(self.do_addFile2Proj)
self.tree.popMenu.exec_(QCursor.pos()) #在鼠标位置显示
def do_delectFile4Proj(self):
item=self.tree.currentItem()
#1.工程文件中删除此文件
self.mycbp.delectFileFromCbp(item.text(0))
#2.从文件列表中删除
for i in range(len(self.file_list)):
if item.text(0) in self.file_list[i]:
del self.file_list[i]
break
#3.从窗口中删除
if item.parent() is not None:
item.parent().removeChild(item)
#函数字典中删除,如果真的要删除,必须确保字典中包含了这个项目
#del self.fileFuncDict[item.text(0)]
def do_addFile2Proj(self): #先把文件名添加到界面,再写入cbp文件
fullfile,filetype = QFileDialog.getOpenFileName(self, "Select source or header file",
self.ProjectDir,"files(*.c *.h)")
if not fullfile:
return
for file in self.file_list:
if file == fullfile: #文件已经存在于工程中,添加失败
self.text_browser.append("文件已经存在于工程中,不要重复添加。")
return
item=self.tree.currentItem() #os.path.basename(fullfile)
childItem = QTreeWidgetItem(item)
if fullfile[-1] =='c' or fullfile[-1] =='C':
childItem.setIcon(0,QIcon(":/{0}.png".format("Cfile")))
else:
childItem.setIcon(0,QIcon(":/{0}.png".format("Hfile")))
childItem.setText(0, os.path.basename(fullfile))
self.file_list.append(fullfile) #1】.向文件列表增加文件
self.mycbp.AddFile2cbp(fullfile) #2】向工程文件增加文件子项
#3】如果是.c 文件生成函数列表
if fullfile[-1] =='c' or fullfile[-1] =='C':
c_getfunc =lexer_c_getfunc(self.file_list[-1])
_fname, _dict= c_getfunc.lexer_analysis()
self.fileFuncDict.setdefault(_fname, _dict)
funcs=list(_dict.keys())
for func in funcs: #将函数名添加到对应的文件名下的子项
subsubchild = QTreeWidgetItem(childItem)
subsubchild.setText(0,func)
subsubchild.setIcon(0,QIcon(":/{0}.png".format("func2")))
#self.mycbp
def setMdiTabbedWindow(self):
self.mdi.setViewMode(QMdiArea.TabbedView) #Tab多页显示模式
self.mdi.setTabsClosable(1)#页面可关闭
self.actCascade.setEnabled(0)
self.actTile.setEnabled(0)
def createAction(self, text, slot=None, shortcut=None, icon=None,
tip=None, checkable=False, signal="triggered()"):
action = QAction(text, self)
if icon is not None:
action.setIcon(QIcon(":/{0}.png".format(icon)))
if shortcut is not None:
action.setShortcut(shortcut)
if tip is not None:
action.setToolTip(tip)
action.setStatusTip(tip)
if slot is not None:
action.triggered.connect(slot)
if checkable:
action.setCheckable(True)
return action
def addActions(self, target, actions):
for action in actions:
if action is None:
target.addSeparator()
else:
target.addAction(action)
def closeEvent(self, event):
if self.SerialDlg.bIsRunning : # 如果串口工具已经打开,请关闭
e = QCloseEvent()
self.SerialDlg.closeEvent(e)
pass
failures = []
for textEdit in self.mdi.subWindowList():
textEdit=textEdit.widget()
if textEdit.isModified():
try:
textEdit.save()
except IOError as e:
failures.append(str(e))
if (failures and
QMessageBox.warning(self, "Text Editor -- Save Error",
"Failed to save{0}\nQuit anyway?".format(
"\n\t".join(failures)),
QMessageBox.Yes|QMessageBox.No) ==
QMessageBox.No):
event.ignore()
return
#settings = QSettings()
settings=QSettings("setting.ini",QSettings.IniFormat)
settings.setIniCodec(QTextCodec.codecForName("utf-8"))
settings.setValue("MainWindow/Geometry", self.saveGeometry())
settings.setValue("MainWindow/State", self.saveState())
self.mdi.closeAllSubWindows()
def loadFiles(self):
if len(sys.argv) > 1:
for filename in sys.argv[1:31]: # Load at most 30 files
filename = filename
if QFileInfo(filename).isFile():
self.loadFile(filename)
QApplication.processEvents()
else:
settings = QSettings()
#files = settings.value("CurrentFiles").toStringList()
if settings.value("CurrentFiles"):
files=settings.value("CurrentFiles")
for filename in files:
filename = filename
if QFile.exists(filename):
self.loadFile(filename)
QApplication.processEvents()
def fileNew(self):
textEdit = SciTextEdit('', self)
self.mdi.addSubWindow(textEdit)
textEdit.show()
def fileOpen(self):
filename,filetype = QFileDialog.getOpenFileName(self,
"Text Editor -- Open File")
if filename:
for textEdit_MSW in self.mdi.subWindowList():
textEdit=textEdit_MSW.widget()
if textEdit.filename == filename:
self.mdi.setActiveSubWindow(textEdit_MSW)
break
else:
self.loadFile(filename)
def loadFile(self, filename):
textEdit = SciTextEdit(filename, self)
try:
textEdit.load()
except EnvironmentError as e:
QMessageBox.warning(self, "Text Editor -- Load Error",
"Failed to load {0}: {1}".format(filename, e))
textEdit.close()
del textEdit
else:
self.mdi.addSubWindow(textEdit)
textEdit.show()
def fileSave(self):
try:
textEdit = self.mdi.activeSubWindow()
textEdit=textEdit.widget()
if textEdit is None or not isinstance(textEdit, SciTextEdit):
return True
try:
textEdit.save()
textEdit.setModified(False)
return True
except EnvironmentError as e:
QMessageBox.warning(self, "Text Editor -- Save Error",
"Failed to save {0}: {1}".format(textEdit.filename, e))
return False
except:
QMessageBox.warning(self,"WARN",'222')
def fileSaveAs(self):
try:
textEdit = self.mdi.activeSubWindow()
textEdit=textEdit.widget()
if textEdit is None or not isinstance(textEdit, QTextEdit):
return
filename,filetype = QFileDialog.getSaveFileName(self,
"Text Editor -- Save File As",
textEdit.filename, "Text files (*.txt *.*)")
if filename:
textEdit.filename = filename
return self.fileSave()
return True
except:
QMessageBox.warning(self,"WARN",'111')
def fileSaveAll(self):
errors = []
for textEdit in self.mdi.subWindowList():
textEdit=textEdit.widget()
if textEdit.isModified():
try:
textEdit.save()
except EnvironmentError as e:
errors.append("{0}: {1}".format(textEdit.filename, e))
if errors:
QMessageBox.warning(self,
"Text Editor -- Save All Error",
"Failed to save\n{0}".format("\n".join(errors)))
def editUndo(self):
textEdit = self.mdi.activeSubWindow()
textEdit=textEdit.widget()
if textEdit is None :#or not isinstance(textEdit, QTextEdit)
return
textEdit.SendScintilla(textEdit.SCI_UNDO, 0, 0)
def editRedo(self):
textEdit = self.mdi.activeSubWindow()
textEdit=textEdit.widget()
if textEdit is None :#or not isinstance(textEdit, QTextEdit)
return
textEdit.SendScintilla(textEdit.SCI_REDO, 0, 0)
def editCopy(self):
textEdit = self.mdi.activeSubWindow()
textEdit=textEdit.widget()
if textEdit is None :#or not isinstance(textEdit, QTextEdit)
return
textEdit.SendScintilla(textEdit.SCI_COPY, 0, 0)
def editCut(self):
textEdit = self.mdi.activeSubWindow()
textEdit=textEdit.widget()
if textEdit is None :#or not isinstance(textEdit, QTextEdit)
return
textEdit.SendScintilla(textEdit.SCI_CUT, 0, 0)
def editPaste(self):
textEdit = self.mdi.activeSubWindow()
textEdit=textEdit.widget()
if textEdit is None :#or not isinstance(textEdit, QTextEdit)
return
textEdit.SendScintilla(textEdit.SCI_PASTE, 0, 0)
#空操作
def editFind(self):#
#1. 获取Mdi的焦点窗口
textEdit = self.mdi.activeSubWindow()
if textEdit is None :
return
#2. 获取窗口里面的 SciTextEdit
textEdit=textEdit.widget()
if textEdit is None :
return
#3. 初始化 查找窗口,传入SciTextEdit 中选中的文字
FindDlg = FindText(self)
FindDlg.lineEdit_destText.setText(textEdit.selectedText())
#4. 显示窗口
FindDlg.exec_()
def DetectPort(self):
#1]检测所有存在的串口,将信息存储在字典中
PortGroup = QActionGroup(self)
port_list = list(serial.tools.list_ports.comports())
actions = self.PortMenu.actions()
#2]self.PortMenu.保留前2项,其它清空
for i in range(2, len(actions)):
self.PortMenu.removeAction(actions[i])
#3]将port_list 添加到菜单中
for port in port_list:
portAction = self.createAction(port[0], self.ChangPort, None, None,
'选择下载口', checkable=True)
self.PortMenu.addAction(portAction)
PortGroup.addAction(portAction)
def ChangChip(self): #选择芯片就是选择下载协议
actions = self.ChipMenu.actions()
for i in range(len(actions)):
if actions[i].isChecked():
self.Chipstr = actions[i].text()
settings=QSettings("setting.ini",QSettings.IniFormat)
settings.setIniCodec(QTextCodec.codecForName("utf-8"))
settings.setValue("Download/Chip",self.Chipstr )
break
def ChangPort(self):
actions = self.PortMenu.actions()
for i in range(2, len(actions)):
if actions[i].isChecked():
#print('%s'%actions[i].text())
self.Portstr = actions[i].text()
settings=QSettings("setting.ini",QSettings.IniFormat)
settings.setIniCodec(QTextCodec.codecForName("utf-8"))
settings.setValue("Download/Port", self.Portstr)
pass
def OpenRecentProject(self, qaction):
#1. 已打开了工程,先关闭
if len(self.fullfile) !=0:
self.ProjectClose()
#2. 获取工程完整路径
self.fullfile = qaction.text()
if os.path.exists(self.fullfile)==None:
self.SetTipString("工程文件名不存在。打开失败。")
#3. 打开工程
self.OpenProjectByName()
def ProjectBuiltLoad(self):
if self.ProjectBuilt() == True:
self.ProjectDownload()
def ProjectBuilt(self):
self.fileSaveAll()
if len(self.fullfile) == 0 or os.path.exists(self.fullfile) == False:
self.text_browser.setText('工程无效!')
return False
self.compilePro = compileProject(self)
self.compilePro.projectClean()
self.compilePro.CreatObjFolder()
if self.compilePro.complieAllFile() == True:
if self.compilePro.LinkAllFile() == True:
self.Hexfile=self.compilePro.ihx2hex()
if self.Hexfile == None:
return False
return True
def ProjectClean(self):
if self.fullfile == None:
self.text_browser.setText('工程无效!')
self.compilePro.projectClean()
pass
def Init_QTreeWidgetItem(self):
root=QTreeWidgetItem(self.tree)
[dirname,filename]=os.path.split(self.fullfile)
root.setText(0,filename)
root.setIcon(0,QIcon(":/{0}.png".format("Project")))
#2.创建一级子节点source和 header
child1=QTreeWidgetItem(root)
child1.setText(0,'source')
child1.setIcon(0,QIcon(":/{0}.png".format("Folder")))
child2=QTreeWidgetItem(root)
child2.setText(0,'header')
child2.setIcon(0,QIcon(":/{0}.png".format("Folder")))
pass
def ProjectClose(self):#1.关闭所有窗口;2.清空树状列表;3.工程名,文件列表清空
self.closeEvent(QEvent.Close)
self.tree.clear()
self.fullfile=''
self.file_list.clear()
pass
def ProjectNew(self):
self.fullfile,filetype = QFileDialog.getSaveFileName(self, "Select project file",
self.Code51_dir,'project ( *.cbp )')
self.mycbp=Dom4cbp(self, self.fullfile)
self.mycbp.CreatNewCbp()
self.Init_QTreeWidgetItem()
#self.tree.expandAll()
self.tree.expandToDepth(2)
def OpenProjectByName(self):
global g_allFuncList
global g_includeList
if len(self.fullfile) ==0:
return
if os.path.exists(self.fullfile) == None:
QMessageBox.warning(self,"警告",'工程文件 %s不存在,请检测文件路径...'%self.fullfile)
return
g_allFuncList.clear()
self.mycbp=Dom4cbp(self, self.fullfile)
#1设置根节点(project name)
root1=QTreeWidgetItem(self.tree)
[self.ProjectDir,filename]=os.path.split(self.fullfile)
root1.setText(0,filename)
root1.setIcon(0,QIcon(":/{0}.png".format("Project")))
#2.创建一级子节点source和 header
child1=QTreeWidgetItem(root1)
child1.setText(0,'source')
child1.setIcon(0,QIcon(":/{0}.png".format("Folder")))
child2=QTreeWidgetItem(root1)
child2.setText(0,'header')
child2.setIcon(0,QIcon(":/{0}.png".format("Folder")))
#3.从工程文件中读入文件列表 及 --xram-size 的参数
self.file_list,self.XdataLen = self.mycbp.getFileList_xdata_In_cbp()
for str1 in self.file_list: #遍历所有文件,c文件和h文件分开处理
#3.1 c文件,加入一级节点source
if str1[-2: ]=='.c' or str1[-2: ]=='.C' :
subchild1=QTreeWidgetItem(child1)
subchild1.setIcon(0,QIcon(":/{0}.png".format("Cfile")))
subDirect, _fname=os.path.split(str1)
subchild1.setText(0,_fname)
#3.1.1] C 文件还要添加函数名作为三级节点
c_getfunc =lexer_c_getfunc(str1)
_fname, _dict= c_getfunc.lexer_analysis()
self.fileFuncDict.setdefault(_fname, _dict)
funcs=list(_dict.keys())
for func in funcs:
subsubchild = QTreeWidgetItem(subchild1)
subsubchild.setText(0,func)
subsubchild.setIcon(0,QIcon(":/{0}.png".format("func2")))
#3.2 h文件,加入一级节点header
elif str1[-2: ]=='.h' or str1[-2: ]=='.H' :
subchild1=QTreeWidgetItem(child2)
subchild1.setIcon(0,QIcon(":/{0}.png".format("Hfile")))
subDirect, _fname=os.path.split(str1)
subchild1.setText(0,_fname)
#3.3 将系统头文件也包含进列表
for str1 in g_includeList:
_fdir,_fename=os.path.split(str1)
#if 'nt' in os.name:#winndows系统
if self.isComplierPathDefault == '1':
fileName = self.compilePath+'/sdcc/include/mcs51/'+_fename
else:
fileName = self.compileIncldue+'/include/mcs51/'+_fename
self.file_list.append(fileName)
subchild1=QTreeWidgetItem(child2)
subchild1.setIcon(0,QIcon(":/{0}.png".format("Hfile")))
subchild1.setText(0,_fename)
pass
self.tree.expandToDepth(1)
#4.将当前工程写入setting.ini
settings=QSettings("setting.ini",QSettings.IniFormat)
settings.setIniCodec(QTextCodec.codecForName("utf-8"))
filesize= settings.beginReadArray("recentProject")
fileList=[]
for i in range(filesize):
settings.setArrayIndex(i)
if self.fullfile != settings.value("File_Name"):
fileList.append(settings.value("File_Name"))
settings.endArray()
fileList.insert(0, self.fullfile) #本工程将位于菜单Project->recentProject列表的第1位
filesize =min(10, len(fileList)) #只记录最近打开的10个工程
settings.beginWriteArray("recentProject", filesize)
for i in range(filesize):
settings.setArrayIndex(i)
settings.setValue("File_Name", fileList[i])
settings.endArray()
#5.初始化 HEX文件名
self.Hexfile = self.ProjectDir+'/obj/'+os.path.splitext(filename)[0]+'.hex'
pass
def ProjectOpen(self):
if len(self.fullfile) !=0:
self.ProjectClose()
self.fullfile,filetype = QFileDialog.getOpenFileName(self, "Select project file",
None,'project ( *.cbp )', None, QFileDialog.DontUseNativeDialog)
self.OpenProjectByName()
def onTreeDoubleClicked(self,qmodeLindex): #对工程列表中的文件双击,以打开c或者h文件
item=self.tree.currentItem()
#print(item.parent().text(0))
#1.双击文件名
if item.parent().text(0) =='source' or item.parent().text(0) =='header':
for filename in self.file_list:
if item.text(0) in filename:#找到在文件列表中的位置后,判断是否已经打开
for textEdit_MSW in self.mdi.subWindowList():
textEdit=textEdit_MSW.widget()
if textEdit.filename == filename:
self.mdi.setActiveSubWindow(textEdit_MSW)
break
else:
self.loadFile(filename)
return
#print(item1)
#2.双击函数名
elif '.c' in item.parent().text(0) or '.C' in item.parent().text(0):
for filename in self.file_list:
if item.parent().text(0) in filename:#找到在文件列表中的位置后,判断是否已经打开
for textEdit_MSW in self.mdi.subWindowList():
textEdit=textEdit_MSW.widget()
if textEdit.filename == filename:
self.mdi.setActiveSubWindow(textEdit_MSW)
break
else:
self.loadFile(filename)
break
pass
textEdit=self.mdi.currentSubWindow().widget()
if textEdit != None:#3.跳转到该函数
textEdit.setCursorPosition(self.fileFuncDict[item.parent().text(0) ][item.text(0)], 0 )
textEdit.setCaretLineBackgroundColor(Qt.lightGray)
#textEdit.show()
textEdit.setFocus()
def windowRestoreAll(self):
for textEdit in self.mdi.subWindowList():
textEdit=textEdit.widget()
textEdit.showNormal()
def windowMinimizeAll(self):
for textEdit in self.mdi.subWindowList():
textEdit=textEdit.widget()
textEdit.showMinimized()
def showProjectWindow(self):
if self.dockProject.isVisible():
self.windowShowProjectAction.setChecked(False)
return
self.dockProject.show()
def showBuiltWindow(self):
if self.dockBuilt.isVisible():
self.windowShowBuiltAction.setChecked(False)
return
self.dockBuilt.show()
def updateWindowMenu(self):
self.windowMenu.clear()
if self.dockProject.isVisible(): #判断 工程列表视图 是否可见
self.windowShowProjectAction.setChecked(True)
else:
self.windowShowProjectAction.setChecked(False)
if self.dockBuilt.isVisible(): #判断 编译结果视图 是否可见
self.windowShowBuiltAction.setChecked(True)
else:
self.windowShowBuiltAction.setChecked(False)
self.addActions(self.windowMenu, (self.windowNextAction,
self.windowPrevAction, self.windowCascadeAction,
self.windowTileAction, self.windowRestoreAction,
self.windowMinimizeAction,
self.windowArrangeIconsAction, None,
self.windowShowProjectAction, self.windowShowBuiltAction,
self.windowCloseAction, None))
textEdits = self.mdi.subWindowList()
if not textEdits:
return
self.windowMenu.addSeparator()
i = 1
menu = self.windowMenu
for textEdit_MSW in textEdits:
textEdit=textEdit_MSW.widget()
title = textEdit.windowTitle()
if i == 10:
self.windowMenu.addSeparator()
menu = menu.addMenu("&More")
accel = ""
if i < 10:
accel = "&{0} ".format(i)
elif i < 36:
accel = "&{0} ".format(chr(i + ord("@") - 9))
action = menu.addAction("{0}{1}".format(accel, title))
self.windowMapper.setMapping(action, textEdit_MSW)
action.triggered.connect(self.windowMapper.map)
i += 1
def hex2bin(self, code):
buf = bytearray()
base = 0
line = 0
for rec in code.splitlines():
# Calculate the line number of the current record
line += 1
try: # bytes(...) is to support python<=2.6 # bytearray(...) is to support python<=2.7bytesbytes
n = bytearray(binascii.a2b_hex((rec[1:3])))[0]
dat = bytearray(binascii.a2b_hex((rec[1:n*2+11])))
except:
MsgStr = "Line %d: Invalid format" % line
QMessageBox.information(self, "标题", MsgStr, QMessageBox.Yes | QMessageBox.No , QMessageBox.Yes )
#raise Exception("Line %d: Invalid format" % line)
if rec[0] != ord(":"):
MsgStr = "Line %d: Missing start code \":\""% line
QMessageBox.information(self, "标题", MsgStr, QMessageBox.Yes | QMessageBox.No , QMessageBox.Yes )
if sum(dat) & 0xFF != 0:
MsgStr = "Line %d: Incorrect checksum" % line
QMessageBox.information(self, "标题", MsgStr, QMessageBox.Yes | QMessageBox.No , QMessageBox.Yes )
if dat[3] == 0: # Data record
addr = base + (dat[1] << 8) + dat[2]
# Allocate memory space and fill it with 0xFF
buf[len(buf):] = [0xFF] * (addr + n - len(buf))
# Copy data to the buffer
buf[addr:addr+n] = dat[4:-1]
elif dat[3] == 1: # EOF record
if n != 0:
raise Exception("Line %d: Incorrect data length" % line)
elif dat[3] == 2: # Extended segment address record
if n != 2:
raise Exception("Line %d: Incorrect data length" % line)
base = ((dat[4] << 8) + dat[5]) << 4
elif dat[3] == 4: # Extended linear address record
if n != 2:
raise Exception("Line %d: Incorrect data length" % line)
base = ((dat[4] << 8) + dat[5]) << 16
else:
raise Exception("Line %d: Unsupported record type" % line)
return buf
def ProjectDownload(self): # self.Hexfile,Chipstr,Portstr
if self.SerialDlg.bIsOpened :
self.SerialDlg.port_close()
if self.Hexfile is None or not os.path.exists(self.Hexfile):
self.SetTipString( '找不到HEX文件。终止操作。')
return
if self.Chipstr is None:
self.SetTipString( '没有选择芯片。终止操作。')
return
if self.Portstr is None:
self.SetTipString( '没有选择串口。终止操作。')
return
try:
fo = open(self.Hexfile, 'rb')
except IOError:
QMessageBox.warning(self, "Open file Error",
"Failed to open {0}: {1}".format(self.Hexfile))
try:
str0 = (fo.read())
fo.close()
except:
self.SetTipString( '打开文件失败.')
return
#if os.path.splitext(self.Hexfile)[1] in (".hex", ".ihx"): HEX --> BIN
str0 = self.hex2bin( str0)
self.SetTipString( '打开文件成功.')
try:
with serial.Serial(port=self.Portstr,
baudrate=2400,
parity=serial.PARITY_NONE) as conn:
self.MyProgram(Programmer(self, conn,self.Chipstr), str0, None)
except IOError:
self.SetTipString("打开串口 {0} 失败".format(self.Portstr))
#检测是否打开串口
if self.SerialDlg.bIsRunning and self.autoOpenCOM =='1':
self.SerialDlg.port_open()
def SetTipString(self, str1):
self.text_browser.append("<font color=block>%s </font> " %str1)
QApplication.processEvents()
def Myprint_info(self, prog):
self.SetTipString(" FOSC: %.3fMHz" % prog.fosc)
self.SetTipString(" Model: %s (ver%s) " % (prog.name, prog.version))
if prog.romsize is not None:
self.SetTipString(" ROM: %dKB" % prog.romsize)
def MyProgram(self, prog, code, erase_eeprom=None):
#下面的语句是打印调试信息到 《test.log》文件,有需要就取消注释
#logging.basicConfig(filename="test.log", filemode="w",
# format="%(asctime)s %(name)s:%(levelname)s:%(message)s",
# datefmt="%d-%M-%Y %H:%M:%S", level=logging.DEBUG)
#0.判断是否发送下载指令
if self.downloadWay == '2':
prog.sendISPcmd(self.baudArray[self.baudIndex])
elif self.downloadWay == '3':
prog.sendISPcmd(self.baudArray[self.baudIndex], self.DIYString)
#1.开始检测芯片
self.SetTipString( '正在检测 MCU,请给芯片上电。' )
ok=prog.detect()
if not ok:
self.SetTipString("检测芯片失败. 请重试...")
return
self.SetTipString("检测芯片完成. done")
self.Myprint_info(prog) #打印检测芯片的结果:1 】晶振频率;2】芯片型号;3】ROMM
if prog.protocol is None:
self.SetTipString("目标芯片无法识别. 终止下载。")
return
if code is None:
self.SetTipString("下载文件内容为空。 终止下载。")
return
prog.comfirm_MCU_model()
#2.建立更到波特率
self.SetTipString("尝试更高波特率...")
prog.handshake()
self.SetTipString("波特率为 %d " % prog.baudrate)
#3.擦除芯片
prog.prepare_for_erase()
self.SetTipString("开始擦除芯片......" )
prog.erase()
self.SetTipString("擦除芯片成功。")
#4.开始写入程序数据
self.SetTipString("开始写入,程序数据大小为%d bytes... " % len(code))
oldbar = 0
for progress in prog.flash(code):
bar = progress
self.SetTipString("#%d - %d bytes 已完成..." %( oldbar,bar ))
oldbar = bar
self.SetTipString("全部写入完毕,运行程序...")
prog.unknown_packet_3()
#5.结束整个流程
prog.terminate()
pass
def repaintMDI(self):
#将打开的文件关闭再重新打开
winlist=[]
textEditWin = self.mdi.activeSubWindow() #记录当前窗口
#1.关闭所有窗口,并记录文件名
for textEdit_MSW in self.mdi.subWindowList():
textEdit=textEdit_MSW.widget()
winlist.append( textEdit.filename)
if textEdit.isModified():
try:
textEdit.save()
except IOError as e:
failures.append(str(e))
self.mdi.closeAllSubWindows()
#2.打开所有刚刚关闭的窗口
for filename in winlist:
self.loadFile(filename)
#3.设置之前的活动窗口为当前活动窗口
for textEdit_MSW in self.mdi.subWindowList():
textEdit=textEdit_MSW.widget()
if textEditWin.widget().filename == textEdit.filename:
self.mdi.setActiveSubWindow(textEdit_MSW)
break
def getFont(self):
font,ok=QFontDialog.getFont(self.EditFont)
if ok:
self.EditFont=font
#settings = QSettings()
settings=QSettings("setting.ini",QSettings.IniFormat)
settings.setIniCodec(QTextCodec.codecForName("utf-8"))
settings.setValue("Font/Family", font.family())
settings.setValue("Font/pointSize", font.pointSize())
if font.bold():
settings.setValue("Font/isBold", '1')
else:
settings.setValue("Font/isBold", '0')
#将打开的文件关闭再重新打开
self.repaintMDI()
if __name__ == "__main__":
app = QApplication(sys.argv)
app.setWindowIcon(QIcon(":/icon.png"))
app.setOrganizationName("Qtrac Ltd.")
app.setOrganizationDomain("qtrac.eu")
app.setApplicationName("Text Editor")
form = MainWindow()
form.show()
app.exec_()
'''
#sys.stdout.write("Setting options...") sys.stdout.flush()
#if prog.options(erase_eeprom=erase_eeprom):
# print(" done")
#else:
# print(" failed")
#5.结束整个流程
'''
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Python
1
https://gitee.com/wekay/code4STC51.git
git@gitee.com:wekay/code4STC51.git
wekay
code4STC51
代码编辑器
master

搜索帮助