class AutosaveThread(QThread): """Threaded autosave to avoid interruption.""" def __init__(self, session: SessionManager): QThread.__init__(self) self.session = session def run(self): self.autosave_thread_function() loop = QEventLoop() loop.exec_() def autosave_thread_function(self): """Thread function, continue until thread is terminated. By default, timer is set to every 5 minutes. TODO: Implement setting for timer. """ LOG_AUTOSAVE.debug("Autosave thread started") self.autosave_timer = QTimer() self.autosave_timer.moveToThread(self) self.autosave_timer.timeout.connect(self.run_autosave) self.autosave_timer.start(1000 * self.session.autosave_interval) def run_autosave(self): """Run the autosave function in current session upon timer expire.""" LOG_AUTOSAVE.info(f'Autosaving! {datetime.now().time()}') # Do autosave self.session.save_mode = SaveMode.AUTOSAVE self.session.save_project() self.session.save_mode = SaveMode.MANUAL def __del__(self): self.wait()
class TimeTriggers(QObject): drop_signal = pyqtSignal() def __init__(self): super().__init__() self.is_done = False self.thread = QThread() self.moveToThread(self.thread) self.thread.started.connect(self.__work__) self.game_update_timer = QTimer() self.game_update_timer.timeout.connect(self.timerEvent) self.game_update_timer.moveToThread(self.thread) self.game_update_timer.start(500) self.thread.start() def start(self): self.thread.start() def timerEvent(self, event): self.drop_barrel() @pyqtSlot() def drop_barrel(self): self.drop_signal.emit() def __work__(self): while not self.is_done: time.sleep(0.03)
class TimeWidget(QWidget): def __init__(self, parent=None): super(TimeWidget, self).__init__(parent) self.timeLabel = QLabel('Time', self) self.timeLabel.setAlignment(Qt.AlignCenter) self.setLayout = QVBoxLayout(self) self.layout().addWidget(self.timeLabel) self.worker = TimeWorker(self) self.timeThread = QThread(self) self.timer = QTimer(self) self.timer.setInterval(1000) self.timer.moveToThread(self.timeThread) self.worker.moveToThread(self.timeThread) self.timer.timeout.connect(self.worker.displayTimer) self.worker.stringForm_Signal.connect(self.updateTime) self.timeThread.started.connect(self.timer.start) self.timeThread.start() QApplication.processEvents() self.setGeometry(40, 40, 400, 120) def updateTime(self, value): self.timeLabel.setText(value)
class ServiceStatusCheckThread(QThread): # Custom signals update_status_title = pyqtSignal(str) update_status_style = pyqtSignal(str) update_service_details = pyqtSignal(dict) update_service_control_btns = pyqtSignal(str) def update_status(self): # Get service details try: service = psutil.win_service_get(SERVICE_NAME) except psutil.NoSuchProcess as e: manager_logger.warning(e) self.update_status_title.emit(f"Service {SERVICE_NAME} not found") self.update_status_style.emit(f"background-color: {self.status_color[None]}; padding: 20px;") self.update_service_details.emit(defaultdict(lambda: None)) self.stop() if is_admin(): self.update_service_control_btns.emit(SERVICE_NOT_FOUND) return service_info = service.as_dict() status = service_info['status'] self.update_status_title.emit(f"{service_info['display_name']} is {status.upper()}") self.update_status_style.emit(f"background-color: {self.status_color[status]}; padding: 20px;") self.update_service_details.emit(service_info) if is_admin(): self.update_service_control_btns.emit(status) def __init__(self, *args, **kwargs): QThread.__init__(self, *args, **kwargs) self.timer = QTimer() self.timer.moveToThread(self) self.finished.connect(self.timer.stop) # When thread is finished, stop timer self.timer.timeout.connect(self.update_status) # region Styles self.status_color = defaultdict(lambda: '#ffff00') # electric yellow self.status_color[psutil.STATUS_RUNNING] = '#90ee90' # medium light shade of green self.status_color[psutil.STATUS_STOPPED] = '#add8e6' # light shade of cyan # endregion def run(self): self.update_status() self.timer.start(SERVICE_STATUS_CHECK_INTERVAL) loop = QEventLoop() loop.exec_() def stop(self): self.exit()
class DataCaptureThread(QThread): my_signal = pyqtSignal(int) def set_is_on(self, data): self.is_on = data def set(self, transform, model, train_model): self.transform = transform self.model = model self.train_model = train_model """ Evaluate the train model by matching it with the camera frames. If the frames are similar it finds the datasets that matches the frames """ def collectProcessData(self): if self.is_on: self.cap = camera ret, self.frame = self.cap.read() self.frame = cv2.cvtColor(self.frame, cv2.COLOR_BGR2RGB) self.img = PIL.Image.fromarray(self.frame) # self.img = self.process_image(self.img) self.img = self.transform(self.img) self.img = self.img.unsqueeze(0) output = self.model(self.img) output = F.softmax(output, dim=1).detach().numpy().flatten() # output = output.detach().numpy() index = output.argmax() self.my_signal.emit(index) print("index", index) in_val = self.train_model.dataset.categories[index] # print("predict val ", in_val) else: self.loop.exit() def __init__(self, *args, **kwargs): QThread.__init__(self, *args, **kwargs) self.dataCollectionTimer = QTimer() self.dataCollectionTimer.moveToThread(self) self.dataCollectionTimer.timeout.connect(self.collectProcessData) def run(self): self.dataCollectionTimer.start(1000) self.loop = QEventLoop() self.loop.exec_() # if __name__ == '__main__': # app = QApplication(sys.argv) # form = App() # form.show() # app.exec_()
class ServiceLogUpdaterThread(QThread): # Custom signals log_fetched = pyqtSignal(str) file_not_found = pyqtSignal() enable_or_disable_buttons = pyqtSignal(bool) def update_log(self): service_log_path = Settings.Service.Logging.log_path try: last_modified = os.path.getmtime(service_log_path) except FileNotFoundError as e: manager_logger.error(e) self.enable_or_disable_buttons.emit(False) self.file_not_found.emit() self.last_widget_update = 0 self.stop() return # if log file was modified since last log widget update, update widget text if last_modified > self.last_widget_update: with open(service_log_path) as file: text = ''.join(deque(file, self.displayed_lines_no)) self.log_fetched.emit(text) self.last_widget_update = time.time() def __init__(self, display_lines_no, *args, **kwargs): QThread.__init__(self, *args, **kwargs) self.timer = QTimer() self.timer.moveToThread(self) self.finished.connect(self.timer.stop) # When thread is finished, stop timer self.timer.timeout.connect(self.update_log) self.last_widget_update = 0 self.displayed_lines_no = display_lines_no def set_displayed_lines_no(self, lines_no): self.displayed_lines_no = lines_no if self.isRunning(): self.last_widget_update = 0 self.update_log() def run(self): self.enable_or_disable_buttons.emit(True) self.update_log() self.timer.start(SERVICE_LOG_UPDATE_INTERVAL) loop = QEventLoop() loop.exec_() def stop(self): self.exit()
class DataCaptureThread(QThread): def collectProcessData(self): print("Collecting Process Data") def __init__(self, *args, **kwargs): QThread.__init__(self, *args, **kwargs) self.dataCollectionTimer = QTimer() self.dataCollectionTimer.moveToThread(self) self.dataCollectionTimer.timeout.connect(self.collectProcessData) # self.dataCollectionTimer.timeout.connect(lambda:self.collectProcessData) def run(self): self.dataCollectionTimer.start(1000) loop = QEventLoop() loop.exec_()
class LCD(QThread): change_time = pyqtSignal(str) def __init__(self, *args, **kwargs): QThread.__init__(self, *args, **kwargs) self.dataCollectionTimer = QTimer() self.dataCollectionTimer.moveToThread(self) self.dataCollectionTimer.timeout.connect(self.show_lcd) def show_lcd(self): time = QtCore.QTime.currentTime() text = time.toString('hh:mm:ss') self.change_time.emit(text) def run(self): self.dataCollectionTimer.start(1000) loop = QEventLoop() loop.exec_()
class GameTimer(QThread): def in_process(self): self.time = self.time.addMSecs(1) if self.time.msecsSinceStartOfDay() >= self.duration: self.terminate() def __init__(self, *args, **kwargs): QThread.__init__(self) self.timer = QTimer() self.timer.moveToThread(self) self.timer.timeout.connect(self.in_process) self.time = QTime(0, 0, 0) self.duration = 0 def run(self): self.timer.start(1) loop = QEventLoop() loop.exec_()
class BeatThread(QThread): signal = pyqtSignal('PyQt_PyObject') def __init__(self, interval=5000, *args, **kwargs): QThread.__init__(self, *args, **kwargs) self.interval = interval self.beat_timer = QTimer() self.beat_timer.moveToThread(self) self.beat_timer.timeout.connect(self.tick) def tick(self): log.info("beat") self.signal.emit(0) def run(self): log.info("starting beat ..") self.beat_timer.start(self.interval) loop = QEventLoop() loop.exec_()
class SplashTimer(QThread): def in_process(self): self.time = self.time.addSecs(1) if self.status == Status.SPLASH_END and self.time.msecsSinceStartOfDay( ) >= 3000: self.terminate() if self.status != Status.SPLASH_END: if self.count > 0: self.label.setText(str(self.count)) elif self.count == 0: self.label.setText("") elif self.count == -1: self.terminate() self.count -= 1 def __init__(self, status, label): QThread.__init__(self) self.timer = QTimer() self.timer.moveToThread(self) self.timer.timeout.connect(self.in_process) self.time = QTime(0, 0, 0) self.status = status self.label = label self.count = 5 self.init_label() def run(self): self.timer.start(1000) loop = QEventLoop() loop.exec_() def init_label(self): if self.status == Status.SPLASH_END: self.label.setText("") else: self.label.setText(str(self.count)) self.count -= 1
class AutosaveThread(QThread): """Threaded autosave to avoid interruption.""" def __init__(self, session: SessionManager): QThread.__init__(self) self.thread_log = logging.getLogger("AutosaveThread") self.session = session def run(self): self.autosave_thread_function() loop = QEventLoop() loop.exec_() def autosave_thread_function(self): """Thread function, continue until thread is terminated. By default, timer is set to every 5 minutes. TODO: Implement setting for timer. """ self.thread_log.info("Autosave thread started") self.autosave_timer = QTimer() self.autosave_timer.moveToThread(self) self.autosave_timer.timeout.connect(self.run_autosave) self.autosave_timer.start(1000 * self.session.autosave_interval) def run_autosave(self): """Run the autosave function in current session upon timer expire.""" self.thread_log.info(f'Autosaving! {datetime.now().time()}') # Remember current session details current_save = self.session.session_filename current_export = self.session.converter.data.export_location # Do autosave self.session.autosaving = True self.make_autosave_file() self.thread_log.info(f"Autosave path {self.session.session_filename}") self.session.exec_save() self.session.autosaving = False # Restore session details self.session.session_filename = current_save self.session.converter.data.export_location = current_export def make_autosave_file(self): autosave_path = os.path.abspath( os.path.join(os.path.dirname(os.path.dirname(__file__)), "..", "autosave")) if not os.path.exists(autosave_path): os.makedirs(autosave_path) self.session.session_filename = os.path.join(autosave_path, "autosave.hermes") self.setup_autosave_file() def setup_autosave_file(self): self.session.converter.data.export_location = mkdtemp() self.session.converter.data.lmf = create_lmf( transcription_language="Transcription", translation_language="Translation", author="Autosaver") self.session.converter.data.lmf['words'] = list() def __del__(self): self.wait()
class CardThread(QThread): def in_process(self): self.time = self.time.addMSecs(30) index = self.time.msecsSinceStartOfDay() if index < 20: return if self.is_finished: self.terminate() if len(self.list) == 0: for i in range(index): self.list.append( self.parser.is_in_range(self.screen_size, self.x, self.y, self.i, self.j, self.proportion)) else: self.list.pop(0) self.list.append( self.parser.is_in_range(self.screen_size, self.x, self.y, self.i, self.j, self.proportion)) red, green, blue = self.get_rgb() if self.list.count(True) / len(self.list) >= 0.4: red, green, blue = self.rgb_to_black(red, green, blue) self.set_rgb(red, green, blue) if self.is_black(): self.label.setStyleSheet( "background-color: rgb(0, 0, 0); color: black;") self.terminate() else: red, green, blue = self.rgb_to_white(red, green, blue) if self.is_initial_color() is False: self.set_rgb(red, green, blue) def __init__(self, label, parser, screen_size, i, j, proportion): QThread.__init__(self) self.timer = QTimer() self.timer.moveToThread(self) self.timer.timeout.connect(self.in_process) self.time = QTime(0, 0, 0) self.label = label self.parser = parser self.screen_size = screen_size self.x = 0 self.y = 0 self.i = i self.j = j self.proportion = proportion self.list = [] self.is_finished = False self.set_rgb(self.parser.get_dwell_rgb(), self.parser.get_dwell_rgb(), self.parser.get_dwell_rgb()) def run(self): self.timer.start(30) loop = QEventLoop() loop.exec_() def get_rgb(self): stylesheet = self.label.styleSheet() regex = r"[Rr][Gg][Bb][\(](((([\d]{1,3})[\,]{0,1})[\s]*){3})[\)]" rgb = re.search(regex, stylesheet).groups() return int(rgb[1]), int(rgb[2]), int(rgb[3]) def rgb_to_black(self, red, green, blue): return red - 1, green - 1, blue - 1 def rgb_to_white(self, red, green, blue): return red + 1, green + 1, blue + 1 def set_rgb(self, red, green, blue): if red < 0 or green < 0 or blue < 0: return if red > 255 or green > 255 or blue > 255: return stylesheet = "background-color: rgb(%d, %d, %d); color: white;" % ( red, green, blue) self.label.setStyleSheet(stylesheet) def is_black(self): red, green, blue = self.get_rgb() return True if red == 0 and green == 0 and blue == 0 else False def is_initial_color(self): red, green, blue = self.get_rgb() color = self.parser.get_dwell_rgb() return True if red == color and green == color and blue == color else False
class ScreenIO(QObject): # ========================================================================= # Settings # ========================================================================= # Update rate of simulation info messages [Hz] siminfo_rate = 2 # Update rate of aircraft update messages [Hz] acupdate_rate = 5 # ========================================================================= # Slots # ========================================================================= @pyqtSlot() def send_siminfo(self): t = time.time() dt = t - self.prevtime qapp.postEvent(qapp.instance(), SimInfoEvent((self.sim.samplecount - self.prevcount) / dt, self.sim.simdt, self.sim.simt, self.sim.traf.ntraf, self.sim.mode)) self.prevtime = t self.prevcount = self.sim.samplecount @pyqtSlot() def send_aircraft_data(self): data = ACDataEvent() data.id = list(self.sim.traf.id) data.lat = np.array(self.sim.traf.lat, dtype=np.float32, copy=True) data.lon = np.array(self.sim.traf.lon, dtype=np.float32, copy=True) data.alt = np.array(self.sim.traf.alt, dtype=np.float32, copy=True) data.tas = np.array(self.sim.traf.tas, dtype=np.float32, copy=True) data.iconf = np.array(self.sim.traf.iconf, copy=True) data.confcpalat = np.array(self.sim.traf.dbconf.latowncpa, copy=True) data.confcpalon = np.array(self.sim.traf.dbconf.lonowncpa, copy=True) data.trk = np.array(self.sim.traf.trk, dtype=np.float32, copy=True) qapp.postEvent(qapp.instance(), data) @pyqtSlot() def send_aman_data(self): data = AMANEvent() data.ids = list(self.sim.traf.AMAN.AllFlights.CallSign) data.iafs = [] data.rwys = [] for s in self.sim.traf.AMAN.AllFlights.Route_outside_TMA: data.iafs.append(s.whichIAF) data.rwys.append(s.whichRWY) data.eats = list(self.sim.traf.AMAN.CurrSchTime_at_IAF) data.stas = list(self.sim.traf.AMAN.CurrSchTime_at_RWY) data.etas = list(self.sim.traf.AMAN.CurrEstTime_at_RWY) data.delays = list(self.sim.traf.AMAN.CurrDelToBeAbs) data.sw_show = list(self.sim.traf.AMAN.AMANhor_sw) data.STAstatuses = list(self.sim.traf.AMAN.STAstatus) data.PopupLabels = list(self.sim.traf.AMAN.AllFlights.PopupLabel) qapp.postEvent(qapp.instance(), data) pass # ========================================================================= # Functions # ========================================================================= def __init__(self, sim): super(ScreenIO, self).__init__() # Keep track of the important parameters of the screen state # (We receive these through events from the gui) self.ctrlat = 0.0 self.ctrlon = 0.0 self.scrzoom = 1.0 # Keep reference to parent simulation object for access to simulation data self.sim = sim # Timing bookkeeping counters self.prevtime = 0.0 self.prevcount = 0 # Output event timers self.siminfo_timer = QTimer() self.siminfo_timer.timeout.connect(self.send_siminfo) self.siminfo_timer.timeout.connect(self.send_aman_data) self.siminfo_timer.start(1000/self.siminfo_rate) self.acupdate_timer = QTimer() self.acupdate_timer.timeout.connect(self.send_aircraft_data) self.acupdate_timer.start(1000/self.acupdate_rate) def moveToThread(self, target_thread): self.siminfo_timer.moveToThread(target_thread) self.acupdate_timer.moveToThread(target_thread) super(ScreenIO, self).moveToThread(target_thread) def echo(self, text): qapp.postEvent(qapp.instance(), StackTextEvent(text)) def getviewlatlon(self): lat0 = self.ctrlat - 1.0 / self.scrzoom lat1 = self.ctrlat + 1.0 / self.scrzoom lon0 = self.ctrlon - 1.0 / self.scrzoom lon1 = self.ctrlon + 1.0 / self.scrzoom return lat0, lat1, lon0, lon1 def zoom(self, zoomfac, absolute=False): if absolute: self.scrzoom = zoomfac else: self.scrzoom *= zoomfac qapp.postEvent(qapp.instance(), PanZoomEvent(zoom=zoomfac, absolute=absolute)) def symbol(self): qapp.postEvent(qapp.instance(), DisplayFlagEvent('SYM')) return def pan(self, pan, absolute=False): if absolute: self.ctrlat = pan[0] self.ctrlon = pan[1] else: self.ctrlat += pan[0] self.ctrlon += pan[1] qapp.postEvent(qapp.instance(), PanZoomEvent(pan=pan, absolute=absolute)) def showroute(self, acid): data = RouteDataEvent() data.acidx = self.sim.traf.id2idx(acid) if data.acidx >= 0: route = self.sim.traf.route[data.acidx] n_segments = len(route.wplat) + 1 data.lat = np.empty(n_segments, dtype=np.float32) data.lat[0] = self.sim.traf.lat[data.acidx] data.lat[1:] = route.wplat data.lon = np.empty(n_segments, dtype=np.float32) data.lon[0] = self.sim.traf.lon[data.acidx] data.lon[1:] = route.wplon wptlabels = [] for i in range(1, n_segments): wptlabels += '%-8s' % route.wpname[i-1] data.wptlabels = np.array(wptlabels) qapp.postEvent(qapp.instance(), data) def showssd(self, param): if param == 'ALL' or param == 'OFF': qapp.postEvent(qapp.instance(), DisplayFlagEvent('SSD', param)) else: idx = self.sim.traf.id2idx(param) if idx >= 0: qapp.postEvent(qapp.instance(), DisplayFlagEvent('SSD', idx)) def show_file_dialog(self): qapp.postEvent(qapp.instance(), ShowDialogEvent()) return '' def postQuit(self): qapp.postEvent(qapp.instance(), SimQuitEvent()) return '' def feature(self, switch, argument=''): qapp.postEvent(qapp.instance(), DisplayFlagEvent(switch, argument)) def objappend(self, objtype, objname, data_in): if data_in is None: # This is an object delete event data = None elif objtype == 1 or objtype == 4: # LINE(1) or POLY(4) data = np.array(data_in, dtype=np.float32) elif objtype == 2: # BOX data = np.array([data_in[0], data_in[1], data_in[0], data_in[3], data_in[2], data_in[3], data_in[2], data_in[1]], dtype=np.float32) elif objtype == 3: # CIRCLE pass qapp.postEvent(qapp.instance(), DisplayShapeEvent(objname, data)) def event(self, event): if event.type() == StackTextEventType: self.sim.stack.stack(event.text) elif event.type() == PanZoomEventType: self.ctrlat = event.pan[0] self.ctrlon = event.pan[1] self.scrzoom = event.zoom return True
class MessageLabel(FLabel): def __init__(self, app, parent=None): super().__init__(parent) self._app = app self.setObjectName('message_label') self._interval = 3 self.timer = QTimer() self.queue = [] self.hide() self.timer.timeout.connect(self.access_message_queue) @property def common_style(self): style_str = ''' #{0} {{ padding-left: 3px; padding-right: 5px; }} '''.format(self.objectName()) return style_str def _set_error_style(self): theme = self._app.theme_manager.current_theme style_str = ''' #{0} {{ background: {1}; color: {2}; }} '''.format(self.objectName(), theme.color1_light.name(), theme.color7_light.name()) self.setStyleSheet(style_str + self.common_style) def _set_normal_style(self): theme = self._app.theme_manager.current_theme style_str = ''' #{0} {{ background: {1}; color: {2}; }} '''.format(self.objectName(), theme.color6_light.name(), theme.color7.name()) self.setStyleSheet(style_str + self.common_style) def show_message(self, text, error=False): if self.isVisible(): self.queue.append({'error': error, 'message': text}) self._interval = 1.5 return if error: self._set_error_style() else: self._set_normal_style() self.setText(str(len(self.queue)) + ': ' + text) self.show() self.timer.moveToThread(QThread.currentThread()) self.timer.start(self._interval * 1000) def access_message_queue(self): self.hide() if self.queue: m = self.queue.pop(0) self.show_message(m['message'], m['error']) else: self._interval = 3