-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
291 lines (231 loc) · 9.95 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
# -*- coding: utf-8 -*-
"""
Module implementing MainWindow.
"""
from PyQt5.QtCore import pyqtSlot, pyqtSignal, QThread
from PyQt5.QtWidgets import QMainWindow
from PyQt5.QtGui import QIcon, QColor, QFont
from PyQt5.QtWidgets import QAction, QFileDialog
from lexer import CustomLexer
from PyQt5.Qsci import QsciScintilla
from Ui_main import Ui_MainWindow
from interpreter import compile_time
import u_comm
import time
class WorkerPlan(QThread):
move_to_line = pyqtSignal(int)
def __init__(self, parent=None):
super(WorkerPlan, self).__init__(parent)
#设置工作状态与初始num数值
self.working = False
self.current_ptr = 0
#LABEL对应的指针
self.LABEL_prt_dict = {}
self.CMDS_LINES = []
def reset(self):
'''不改变程序,只是恢复到重头开始执行位置'''
self.numline = 0
def load(self, lines_plan):
'''打开新文本'''
self.reset()
lines_plan = [line.strip(' \n') for line in lines_plan ]
#print(lines_plan)
self.CMDS_LINES = compile_time(lines_plan)
self.LABEL_prt_dict = {}
self.current_ptr = 0
# def __del__(self):
# #线程状态改变与线程终止
# self.working = False
# self.wait()
def step(self):
'''一次执行1行 光标移到下一行'''
# 发射信号
num_line1, CMD_LINE1 = self.CMDS_LINES[self.current_ptr]
#改成编辑器界面中从1开始的行号
num_line1 += 1
print(f'执行第{num_line1}行')
if self.current_ptr < len(self.CMDS_LINES):
#单步确认,继续执行
if isinstance(CMD_LINE1, list):
#如果是多行 只移动1次行号
for IL_line1 in CMD_LINE1:
self.run_IL_line1(IL_line1)
self.current_ptr += 1
elif isinstance(CMD_LINE1, tuple):
#单行 goto特殊处理 行号
print(CMD_LINE1)
num_line1_goto = self.run_IL_line1(CMD_LINE1)
if num_line1_goto is not None:
#goto语句 光标跳转了,current_ptr在goto里改变了,不需要+1
num_line1 = num_line1_goto
else:
#没有goto 光标前进1
self.current_ptr += 1
self.move_to_line.emit(num_line1)
else:
print('执行完毕')
def run(self):
self.working = True
while self.current_ptr < len(self.CMDS_LINES):
if self.working:
self.step()
else:
break
print('执行完毕')
def run_IL_line1(self, IL_line1):
'''执行1行plan语句
goto 返回行号
'''
CMD, *para = IL_line1
num_line1_goto = None
if CMD == 'GOTO':
#参数是label
self.current_ptr = self.LABEL_prt_dict[para[0]]
print(f'GOTO {self.CMDS_LINES[self.current_ptr]}')
num_line1_goto, CMD_LINE1 = self.CMDS_LINES[self.current_ptr]
else:
if CMD == 'LABEL':
#参数是label
self.LABEL_prt_dict[para[0]] = self.current_ptr
print('LABEL')
elif CMD == 'MOVE':
u_comm.send1(para[0])
elif CMD == 'WAIT':
print(f'等待 {para[0]} 秒')
time.sleep(para[0])
#用qt线程的定时,不用time
#self.sleep(int(para[0]))
else:
raise Exception(f"invalid IL {CMD}")
return num_line1_goto
class MainWindow(QMainWindow, Ui_MainWindow):
"""
Class documentation goes here.
"""
def __init__(self, parent=None):
"""
Constructor
@param parent reference to the parent widget
@type QWidget
"""
super(MainWindow, self).__init__(parent)
self.setupUi(self)
self.editor.setUtf8(True) # Set encoding to UTF-8
#行号显示区域
#self.editor.setMarginType(0, QsciScintilla::NumberMargin)
self.editor.setMarginLineNumbers(0, True)
self.editor.setMarginWidth(0, 30)
self.editor.setColor(QColor(255, 255, 255)) #设置默认的字体颜色
self.editor.setPaper(QColor(0, 0, 0)) #设置底色
self.editor.setCaretLineBackgroundColor(QColor(0, 0, 255));
#self.editor.setReadOnly(True)
font_normal = QFont("monospace", 14, QFont.Bold)
self.editor.setFont(font_normal) #默认的字体加粗。
sdcc_kwlist = ['BEG', 'END', 'DEFINE', 'BODY', 'WAIT', 'CAMERA', 'MOVE', 'STOP', 'RESET ALL', '↑', '↓', '←', '→']
self.editor.SendScintilla(QsciScintilla.SCI_SETKEYWORDS, 0," ".join(sdcc_kwlist).encode(encoding='utf-8'))
# self.lexer = CustomLexer(self.editor)
# self.editor.setLexer(self.lexer) #QsciScintilla
self.action_new = QAction(QIcon("./images/new.png"), "new", self)
self.toolBar.addAction(self.action_new)
self.action_new.triggered.connect(self.NewPlan)
self.action_open = QAction(QIcon("./images/open.png"), "open", self)
self.toolBar.addAction(self.action_open)
self.action_open.triggered.connect(self.OpenPlan)
self.action_save = QAction(QIcon("./images/save.png"), "save", self)
self.toolBar.addAction(self.action_save)
self.action_save.triggered.connect(self.SavePlan)
self.action_save.setEnabled(False)
self.action_reset = QAction(QIcon("./images/reset.png"), "复位", self)
self.toolBar.addAction(self.action_reset)
self.action_reset.triggered.connect(self.ResetPlan)
self.action_reset.setEnabled(False)
self.action_play = QAction(QIcon("./images/play.png"), "运行", self)
self.toolBar.addAction(self.action_play)
self.action_play.triggered.connect(self.PlayPlan)
self.action_play.setEnabled(False)
self.action_step = QAction(QIcon("./images/step.png"), "单步", self)
self.toolBar.addAction(self.action_step)
self.action_step.triggered.connect(self.StepPlan)
self.action_step.setEnabled(False)
# self.action_stop = QAction(QIcon("./images/stop.png"), "停止", self)
# self.toolBar.addAction(self.action_stop)
# self.action_stop.triggered.connect(self.StopPlan)
# self.action_stop.setEnabled(False)
self.action_pause = QAction(QIcon("./images/pause.png"), "暂停", self)
self.toolBar.addAction(self.action_pause)
self.action_pause.triggered.connect(self.PausePlan)
self.action_pause.setEnabled(False)
self.thread_worker = WorkerPlan()
self.thread_worker.move_to_line.connect(self.set_cursor_numline)
def set_cursor_numline(self, num_line):
self.editor.setCursorPosition(num_line,0)
self.editor.SendScintilla(QsciScintilla.SCI_SETFIRSTVISIBLELINE, num_line+1);
def set_Plan_editing(self):
'''计划文件处于可编辑模式'''
self.editor.setCaretLineVisible(True)
self.editor.setCaretLineBackgroundColor(QColor(0, 255, 0));
self.editor.setReadOnly(False) #可编辑
self.editor.setMouseTracking(True) #可改变光标位置
#可运行
self.action_play.setEnabled(True)
self.action_step.setEnabled(True)
self.action_new.setEnabled(True)
self.action_open.setEnabled(True)
def set_Plan_runtime(self, is_step=True):
'''计划文件处于运行中模式'''
self.editor.setCaretLineBackgroundColor(QColor(0, 0, 255));
self.editor.setMouseTracking(False) #不可改变光标位置
self.editor.setReadOnly(True) #b不可编辑
self.action_pause.setEnabled(True) #可暂停
#运行中不可新建,不可打开别的
self.action_new.setEnabled(False)
self.action_open.setEnabled(False)
# def set_Plan_stop(self):
# '''停止运行,可以新建,打开'''
# self.action_new.setEnabled(True)
# self.action_open.setEnabled(True)
def NewPlan(self, b):
print("pressed new ")
#self.text.setText(a.text())
def OpenPlan(self, b):
print("pressed open ")
# def openfile(self):
openfile_name, *_ = QFileDialog.getOpenFileName(self,'选择计划','./plans','Plan files(*.pln)')
print(openfile_name)
self.editor.setText("")
with open(openfile_name, 'r', encoding='utf-8') as f:
lines_plan = f.readlines()
#加载到编辑器显示
for line in lines_plan:
#self.editor.setText("Hello\n")
self.editor.append(line)
#加载到执行器
self.thread_worker.load(lines_plan)
num_line = 0
self.set_cursor_numline(num_line)
self.set_Plan_editing()
def SavePlan(self, b):
print("pressed save ")
def ResetPlan(self, b):
print("pressed reset ")
#复位 恢复编辑
self.reset()
self.set_Plan_editing()
def PlayPlan(self, b):
print("pressed play ")
self.set_Plan_runtime()
self.action_reset.setEnabled(False) #可复位
self.action_pause.setEnabled(True) #自动模式需要暂停
self.thread_worker.start()
def StepPlan(self, b):
print("pressed step ")
self.set_Plan_runtime()
self.action_reset.setEnabled(True) #可复位
self.action_pause.setEnabled(False) #单步不需要暂停
self.thread_worker.step()
def StopPlan(self, b):
print("pressed step ")
def PausePlan(self, b):
print("pressed pause ")
self.thread_worker.working = False
self.action_reset.setEnabled(True) #可复位