Skip to content

Commit 05f6015

Browse files
committed
Call esptool.main . Divert stdout and stderr to messageBox
1 parent 9ea3482 commit 05f6015

File tree

2 files changed

+55
-75
lines changed

2 files changed

+55
-75
lines changed

Uploader_GUI/RTK_Firmware_Uploader_GUI.py

Lines changed: 55 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
1414
Pyinstaller:
1515
Windows:
16-
pyinstaller --onefile --clean --noconsole --distpath=./Windows_exe --icon=RTK.ico --add-data="esptool.py;." --add-binary="RTK_Surveyor.ino.partitions.bin;." --add-binary="RTK_Surveyor.ino.bootloader.bin;." --add-binary="boot_app0.bin;." --add-binary="RTK.png;." RTK_Firmware_Uploader_GUI.py
16+
pyinstaller --onefile --clean --noconsole --distpath=./Windows_exe --icon=RTK.ico --add-binary="RTK_Surveyor.ino.partitions.bin;." --add-binary="RTK_Surveyor.ino.bootloader.bin;." --add-binary="boot_app0.bin;." --add-binary="RTK.png;." RTK_Firmware_Uploader_GUI.py
1717
Linux:
18-
pyinstaller --onefile --clean --noconsole --distpath=./Linux_exe --icon=RTK.ico --add-data="esptool.py:." --add-binary="RTK_Surveyor.ino.partitions.bin:." --add-binary="RTK_Surveyor.ino.bootloader.bin:." --add-binary="boot_app0.bin:." --add-binary="RTK.png:." RTK_Firmware_Uploader_GUI.py
18+
pyinstaller --onefile --clean --noconsole --distpath=./Linux_exe --icon=RTK.ico --add-binary="RTK_Surveyor.ino.partitions.bin:." --add-binary="RTK_Surveyor.ino.bootloader.bin:." --add-binary="boot_app0.bin:." --add-binary="RTK.png:." RTK_Firmware_Uploader_GUI.py
1919
2020
Pyinstaller needs:
2121
RTK_Firmware_Uploader_GUI.py (this file!)
@@ -68,6 +68,30 @@ def resource_path(relative_path):
6868
base_path = getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__)))
6969
return os.path.join(base_path, relative_path)
7070

71+
class messageRedirect:
72+
"""Wrap a class around a QPlainTextEdit so we can redirect stdout and stderr to it"""
73+
74+
def __init__(self, edit, out=None) -> None:
75+
self.edit = edit
76+
self.out = out
77+
self.edit.setReadOnly(True)
78+
self.edit.clear()
79+
80+
def write(self, msg) -> None:
81+
if msg.startswith("\r"):
82+
self.edit.moveCursor(QTextCursor.StartOfLine, QTextCursor.KeepAnchor)
83+
self.edit.cut()
84+
self.edit.insertPlainText(msg[1:])
85+
else:
86+
self.edit.insertPlainText(msg)
87+
self.edit.ensureCursorVisible()
88+
self.edit.repaint()
89+
if self.out: # Echo to out (stdout) too if desired
90+
self.out.write(msg)
91+
92+
def flush(self) -> None:
93+
None
94+
7195
# noinspection PyArgumentList
7296

7397
class MainWidget(QWidget):
@@ -76,8 +100,6 @@ class MainWidget(QWidget):
76100
def __init__(self, parent: QWidget = None) -> None:
77101
super().__init__(parent)
78102

79-
self.p = None # This will be the esptool QProcess
80-
81103
# File location line edit
82104
self.msg_label = QLabel(self.tr('Firmware File:'))
83105
self.fileLocation_lineedit = QLineEdit()
@@ -118,7 +140,7 @@ def __init__(self, parent: QWidget = None) -> None:
118140
self.messages_label = QLabel(self.tr('Status / Warnings:'))
119141

120142
# Messages Window
121-
self.messages = QPlainTextEdit()
143+
self.messageBox = QPlainTextEdit()
122144

123145
# Arrange Layout
124146
layout = QGridLayout()
@@ -136,33 +158,20 @@ def __init__(self, parent: QWidget = None) -> None:
136158
layout.addWidget(self.upload_btn, 3, 2)
137159

138160
layout.addWidget(self.messages_label, 4, 0)
139-
layout.addWidget(self.messages, 5, 0, 5, 3)
161+
layout.addWidget(self.messageBox, 5, 0, 5, 3)
140162

141163
self.setLayout(layout)
142164

143165
#self._clean_settings() # This will delete all existing settings! Use with caution!
144166

145167
self._load_settings()
146168

147-
# Make the text edit window read-only
148-
self.messages.setReadOnly(True)
149-
self.messages.clear() # Clear the message window
150-
151-
def addMessage(self, msg: str) -> None:
152-
"""Add msg to the messages window, ensuring that it is visible"""
153-
self.messages.moveCursor(QTextCursor.End)
154-
self.messages.ensureCursorVisible()
155-
self.messages.appendPlainText(msg)
156-
self.messages.ensureCursorVisible()
157-
self.repaint() # Update/refresh the message window
158-
159-
def insertMessageText(self, msg: str) -> None:
160-
"""Add msg to the messages window, ensuring that it is visible"""
161-
self.messages.moveCursor(QTextCursor.End)
162-
self.messages.ensureCursorVisible()
163-
self.messages.insertPlainText(msg)
164-
self.messages.ensureCursorVisible()
165-
self.repaint() # Update/refresh the message window
169+
def writeMessage(self, msg) -> None:
170+
self.messageBox.moveCursor(QTextCursor.End)
171+
self.messageBox.ensureCursorVisible()
172+
self.messageBox.appendPlainText(msg)
173+
self.messageBox.ensureCursorVisible()
174+
self.messageBox.repaint()
166175

167176
def _load_settings(self) -> None:
168177
"""Load settings on startup."""
@@ -253,7 +262,7 @@ def closeEvent(self, event: QCloseEvent) -> None:
253262

254263
def on_refresh_btn_pressed(self) -> None:
255264
self.update_com_ports()
256-
self.addMessage("Ports Refreshed\n")
265+
self.writeMessage("Ports Refreshed\n")
257266

258267
def on_browse_btn_pressed(self) -> None:
259268
"""Open dialog to select bin file."""
@@ -267,37 +276,14 @@ def on_browse_btn_pressed(self) -> None:
267276
if fileName:
268277
self.fileLocation_lineedit.setText(fileName)
269278

270-
def handle_stderr(self) -> None:
271-
data = self.p.readAllStandardError()
272-
stderr = bytes(data).decode("utf8")
273-
self.insertMessageText(stderr)
274-
275-
def handle_stdout(self) -> None:
276-
data = self.p.readAllStandardOutput()
277-
stdout = bytes(data).decode("utf8")
278-
self.insertMessageText(stdout)
279-
280-
def handle_state(self, state) -> None:
281-
states = {
282-
QProcess.NotRunning: 'Not running\n',
283-
QProcess.Starting: 'Starting\n',
284-
QProcess.Running: 'Running\n',
285-
}
286-
state_name = states[state]
287-
self.addMessage(f"Upload state changed: {state_name}")
288-
289-
def process_finished(self) -> None:
290-
self.addMessage("Upload finished\n")
291-
self.p = None
292-
293279
def on_upload_btn_pressed(self) -> None:
294280
"""Upload the firmware"""
295281
portAvailable = False
296282
for desc, name, sys in gen_serial_ports():
297283
if (sys == self.port):
298284
portAvailable = True
299285
if (portAvailable == False):
300-
self.addMessage("Port No Longer Available")
286+
self.writeMessage("Port No Longer Available")
301287
return
302288

303289
fileExists = False
@@ -308,37 +294,25 @@ def on_upload_btn_pressed(self) -> None:
308294
fileExists = False
309295
finally:
310296
if (fileExists == False):
311-
self.addMessage("File Not Found")
297+
self.writeMessage("File Not Found")
312298
return
313299
f.close()
314300

315-
if self.p is None:
316-
self.addMessage("Uploading firmware\n")
317-
318-
self.p = QProcess()
319-
self.p.readyReadStandardOutput.connect(self.handle_stdout)
320-
self.p.readyReadStandardError.connect(self.handle_stderr)
321-
self.p.stateChanged.connect(self.handle_state)
322-
self.p.finished.connect(self.process_finished)
323-
324-
command = []
325-
command.append(resource_path("esptool.py"))
326-
command.extend(["--chip","esp32"])
327-
command.extend(["--port",self.port])
328-
command.extend(["--baud",self.baudRate])
329-
command.extend(["--before","default_reset","--after","hard_reset","write_flash","-z","--flash_mode","dio","--flash_freq","80m","--flash_size","detect"])
330-
command.extend(["0x1000",resource_path("RTK_Surveyor.ino.bootloader.bin")])
331-
command.extend(["0x8000",resource_path("RTK_Surveyor.ino.partitions.bin")])
332-
command.extend(["0xe000",resource_path("boot_app0.bin")])
333-
command.extend(["0x10000",self.theFileName])
301+
self.writeMessage("Uploading firmware\n")
334302

335-
self.addMessage("Command: python %s\n" % " ".join(command))
303+
command = []
304+
command.extend(["--chip","esp32"])
305+
command.extend(["--port",self.port])
306+
command.extend(["--baud",self.baudRate])
307+
command.extend(["--before","default_reset","--after","hard_reset","write_flash","-z","--flash_mode","dio","--flash_freq","80m","--flash_size","detect"])
308+
command.extend(["0x1000",resource_path("RTK_Surveyor.ino.bootloader.bin")])
309+
command.extend(["0x8000",resource_path("RTK_Surveyor.ino.partitions.bin")])
310+
command.extend(["0xe000",resource_path("boot_app0.bin")])
311+
command.extend(["0x10000",self.theFileName])
336312

337-
self.p.start('python', command)
313+
self.writeMessage("Command: esptool.main(%s)\n\n" % " ".join(command))
338314

339-
else:
340-
self.addMessage("\nUploader is already running!\n")
341-
315+
esptool.main(command)
342316

343317
if __name__ == '__main__':
344318
from sys import exit as sysExit
@@ -347,5 +321,11 @@ def on_upload_btn_pressed(self) -> None:
347321
app.setApplicationName('SparkFun RTK Firmware Uploader ' + guiVersion)
348322
app.setWindowIcon(QIcon(resource_path("RTK.png")))
349323
w = MainWidget()
324+
if 1:
325+
sys.stdout = messageRedirect(w.messageBox) # Divert stdout to messageBox
326+
sys.stderr = messageRedirect(w.messageBox) # Divert stderr to messageBox
327+
else:
328+
sys.stdout = messageRedirect(w.messageBox, sys.stdout) # Echo to stdout too
329+
sys.stderr = messageRedirect(w.messageBox, sys.stderr) # Echo to stderr too
350330
w.show()
351331
sys.exit(app.exec_())
Binary file not shown.

0 commit comments

Comments
 (0)