1414from os import path , system
1515from sys import platform , exit , argv
1616from glob import glob
17-
1817from src import action_ui
1918# Runtime Type Checking
2019PROGRAM_TYPE_DEBUG = True
2827 #system("python -m pip install pyserial")
2928
3029try :
31- from PySide6 .QtCore import QObject , QThread , Signal , QFile , Qt
30+ from PySide6 .QtCore import QObject , QThread , Signal , QFile , Qt , QEvent , QTimer
3231 from PySide6 .QtWidgets import QApplication , QMainWindow , QMessageBox , QInputDialog
33-
32+ from ui . main_window import Ui_main_window
3433 if (PROGRAM_TYPE_DEBUG ):
3534 from PySide6 .QtUiTools import QUiLoader
36- else : # PROGRAM_TYPE_RELEASE
37- from ui .ui_main_window import Ui_main_window
35+
3836except ImportError as e :
3937 print ("Import Error! I am installing the required libraries: " + str (e ))
4038 #system("pip install {0}".format(str(e).split(" ")[-1]))
@@ -129,7 +127,7 @@ def __init__(self):
129127 self .ui .show ()
130128 else : # PROGRAM_TYPE_RELEASE
131129 print ("UI File Found!" )
132- self .ui = Ui_main_window ()
130+ self .ui = Ui_main_window ()
133131 self .ui .setupUi (self )
134132
135133 if (is_windows_dark_mode (self )):
@@ -141,7 +139,7 @@ def __init__(self):
141139 self .thread = None
142140 self .worker = None
143141
144- self .ui .start_button .clicked .connect (self .start_loop )
142+ self .ui .start_button .clicked .connect (self .on_start_button_clicked )
145143 self .ui .refresh_button .clicked .connect (self .refresh_port )
146144 '''
147145 self.ui.command_edit_1.clicked.connect(self.command1)
@@ -166,6 +164,9 @@ def __init__(self):
166164 self .ui .port_comboBox .addItems (PORTS )
167165 self .ui .send_button .clicked .connect (self .on_send_data_button_clicked )
168166
167+ # when Enter is pressed in send_data_text
168+ self .ui .send_data_text .installEventFilter (self )
169+
169170 self .ui .actionExit .triggered .connect (lambda : exit (0 ))
170171 self .ui .actionAbout .triggered .connect (action_ui .show_about_dialog )
171172 self .ui .actionCheck_for_updates .triggered .connect (action_ui .check_for_updates )
@@ -224,6 +225,14 @@ def move_command4_to_text(self):
224225 self.ui.send_data_text.setText(self.ui.saved_command_4.text())
225226 self.on_send_data_button_clicked()
226227 '''
228+ def eventFilter (self , obj , event ):
229+ # Check if the event is for send_data_text and Enter is pressed
230+ if obj == self .ui .send_data_text and event .type () == QEvent .KeyPress :
231+ if event .key () in (Qt .Key_Return , Qt .Key_Enter ):
232+ self .on_send_data_button_clicked ()
233+ return True # Prevents QTextEdit from adding a new line
234+ return super ().eventFilter (obj , event )
235+
227236 def refresh_port (self ):
228237 """ Refresh the serial port list """
229238 PORTS = get_serial_port ()
@@ -294,9 +303,20 @@ def establish_serial_communication(self):
294303 if SERIAL_DEVICE .isOpen () == False :
295304 SERIAL_DEVICE .open ()
296305
297- def start_loop (self ):
306+ def on_start_button_clicked (self ):
298307 """ Start the loop """
299- self .ui .port_comboBox .setStyleSheet ('background-color: white' )
308+ # Check if the port_comboBox style is red, if so, set it to system default
309+ if self .ui .port_comboBox .styleSheet () == 'background-color: red' :
310+ self .ui .port_comboBox .setStyleSheet ('' )
311+
312+ global is_serial_port_established
313+
314+ if is_serial_port_established :
315+ is_serial_port_established = False
316+ self .ui .start_button .setText ("START" )
317+ self .ui .start_button .setStyleSheet ('color: green;' )
318+ self .on_stop_button_clicked ()
319+ return
300320
301321 # If the serial port is not selected, print a message
302322 if self .ui .port_comboBox .currentText () == "" :
@@ -311,18 +331,11 @@ def start_loop(self):
311331 self .print_message_on_screen (
312332 "Exception occured while trying establish serial communication!" )
313333 return
314-
315- global is_serial_port_established
316-
317- if (is_serial_port_established == True ):
318- is_serial_port_established = False
319- self .on_end_button_clicked ()
320- self .ui .start_button .setText ("START" )
321- return
322-
323334 is_serial_port_established = True
324335 # change start_button to stop button
336+ self .ui .options_textEdit .setText ('Disconnected!' )
325337 self .ui .start_button .setText ("STOP" )
338+ self .ui .start_button .setStyleSheet ('color: red;' )
326339
327340 try :
328341 self .worker = Worker () # a new worker to perform those tasks
@@ -332,27 +345,50 @@ def start_loop(self):
332345 # begin our worker object's loop when the thread starts running
333346 self .thread .started .connect (self .worker .work )
334347 self .worker .serial_data .connect (self .read_data_from_thread )
335- # stop the loop on the stop button click
336- self .ui .end_button .clicked .connect (self .stop_loop )
337348 # tell the thread it's time to stop running
338349 self .worker .finished .connect (self .thread .quit )
339350 # have worker mark itself for deletion
340351 self .worker .finished .connect (self .worker .deleteLater )
341352 # have thread mark itself for deletion
342353 self .thread .finished .connect (self .thread .deleteLater )
354+
355+ self .enable_configuration (False )
356+ self .ui .options_textEdit .setText ('RX/TX Connected!' )
357+ self .ui .status_label .setText ("CONNECTED!" )
358+ self .ui .status_label .setStyleSheet ('color: green' )
343359 # start the thread
344360 self .thread .start ()
345-
346-
347361 except RuntimeError :
348362 self .print_message_on_screen ("Exception in Worker Thread!" )
349363
350- def stop_loop (self ):
364+ def on_stop_button_clicked (self ):
351365 """ Stop the loop """
352- self .worker .working = False
353366 self .ui .options_textEdit .setText ('Stopped!' )
354- # Disconnect the serial port and close it
355- SERIAL_DEVICE .close ()
367+ self .ui .status_label .setText ("DISCONNECTED!" )
368+ self .ui .status_label .setStyleSheet ('color: red' )
369+ self .enable_configuration (True )
370+
371+ # Safely stop the worker thread
372+ if hasattr (self , 'worker' ) and self .worker is not None :
373+ self .worker .working = False
374+
375+ # Safely close the serial device
376+ global SERIAL_DEVICE
377+ try :
378+ if SERIAL_DEVICE .is_open :
379+ SERIAL_DEVICE .close ()
380+ except Exception as e :
381+ print (f"Error closing serial port: { e } " )
382+
383+ def enable_configuration (self , state ):
384+ """ enable/disable the configuration """
385+ self .ui .timeout_comboBox .setEnabled (state )
386+ self .ui .baudrate_comboBox .setEnabled (state )
387+ self .ui .len_comboBox .setEnabled (state )
388+ self .ui .port_comboBox .setEnabled (state )
389+ self .ui .parity_comboBox .setEnabled (state )
390+ self .ui .bit_comboBox .setEnabled (state )
391+ self .ui .flow_comboBox .setEnabled (state )
356392
357393 def read_data_from_thread (self , serial_data ):
358394 """ Write the result to the text edit box"""
@@ -361,49 +397,23 @@ def read_data_from_thread(self, serial_data):
361397 self .print_message_on_screen (
362398 "Serial Port Exception! Please check the serial port"
363399 " Possibly it is not connected or the port is not available!" )
364- self .ui .status_label .setText ("NOT CONNECTED!" )
365- self .ui .status_label .setStyleSheet ('color: red' )
400+ self .on_stop_button_clicked ()
366401 else :
367- self .ui .timeout_comboBox .setEnabled (False )
368- self .ui .baudrate_comboBox .setEnabled (False )
369- self .ui .len_comboBox .setEnabled (False )
370- self .ui .port_comboBox .setEnabled (False )
371- self .ui .parity_comboBox .setEnabled (False )
372- self .ui .bit_comboBox .setEnabled (False )
373- self .ui .flow_comboBox .setEnabled (False )
374- self .ui .start_button .setEnabled (False )
375-
376- self .ui .options_textEdit .setText ('Data Gathering...' )
377- self .ui .status_label .setText ("CONNECTED!" )
378- self .ui .status_label .setStyleSheet ('color: green' )
379402 serial_data = serial_data .replace ('\n ' , '' )
380403 self .ui .data_textEdit .insertPlainText ("{}" .format (serial_data ))
381404 self .ui .data_textEdit .verticalScrollBar ().setValue (
382405 self .ui .data_textEdit .verticalScrollBar ().maximum ())
383406
384- def on_end_button_clicked (self ):
385- """ Stop the process """
386- global is_serial_port_established
387- is_serial_port_established = False
388- self .ui .options_textEdit .setText ('Stopped!' )
389- self .ui .status_label .setText ("DISCONNECTED!" )
390- self .ui .status_label .setStyleSheet ('color: red' )
391- self .ui .timeout_comboBox .setEnabled (True )
392- self .ui .baudrate_comboBox .setEnabled (True )
393- self .ui .len_comboBox .setEnabled (True )
394- self .ui .port_comboBox .setEnabled (True )
395- self .ui .parity_comboBox .setEnabled (True )
396- self .ui .bit_comboBox .setEnabled (True )
397- self .ui .flow_comboBox .setEnabled (True )
398- self .ui .start_button .setEnabled (True )
399-
400407 def on_send_data_button_clicked (self ):
401408 """ Send data to serial port """
402- if (is_serial_port_established ):
409+ if is_serial_port_established :
410+ self .ui .indicate_button .setChecked (True )
403411 mytext = self .ui .send_data_text .toPlainText ().encode ('utf-8' )
404- #SERIAL_DEVICE.flushInput()
405- #SERIAL_DEVICE.flushOutput()
406- SERIAL_DEVICE .write (mytext + b'\r ' )
412+ SERIAL_DEVICE .flushOutput () # Flush output buffer
413+ SERIAL_DEVICE .write (mytext + b'\r \n ' )
414+
415+ # Uncheck after 5 seconds without blocking the UI
416+ QTimer .singleShot (500 , lambda : self .ui .indicate_button .setChecked (False ))
407417 else :
408418 self .print_message_on_screen (
409419 "Serial Port is not established yet! Please establish the serial port first!" )
@@ -413,4 +423,6 @@ def start_ui_design():
413423 """ Start the UI Design """
414424 app = QApplication (argv ) # Create an instance
415425 window_object = MainWindow () # Create an instance of our class
426+ if PROGRAM_TYPE_RELEASE :
427+ window_object .show ()
416428 exit (app .exec ())
0 commit comments