Best Python code snippet using slash
Controller.py
Source:Controller.py
1# import seatease.spectrometers as s # Emulator to test w/o spectrometer2import seabreeze.spectrometers as s3from datetime import datetime4from tkinter.messagebox import showerror5import matplotlib6import numpy as np7from LogPatient import *8from LoginPage import *9from ResetPW import *10from SignUp import *11from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg12from matplotlib.lines import Line2D13import matplotlib.pyplot as plt14import matplotlib.animation as animation15from matplotlib import style16from azure.storage.blob import BlobClient17import csv18matplotlib.use("TkAgg")19style.use("ggplot")20dev_list = s.list_devices()21spec = s.Spectrometer(dev_list[0]) # Assign detected spectrometer to variable spec22integration_time = 20000 # 20 ms, set default integration time to a reasonable value23spec.integration_time_micros(integration_time)24x = spec.wavelengths()25data = spec.intensities()26xmin = np.around(min(x), decimals=2)27xmax = np.around(max(x), decimals=2)28ymin = np.around(min(data), decimals=2)29ymax = np.around(max(data), decimals=2)30minIntTime = spec.minimum_integration_time_micros31class Controller(tk.Tk):32 def __init__(self, ax, *args, **kwargs):33 tk.Tk.__init__(self, *args, **kwargs)34 tk.Tk.wm_title(self, "Data Recording")35 self.geometry("1000x700")36 container = tk.Frame(self)37 container.pack(side="top", fill="both", expand=True)38 container.grid_rowconfigure(0, weight=1)39 container.grid_columnconfigure(0, weight=1)40 # Dictionary of class names, frames (Ex: HomePage, actual frame)41 self.frames = {"LoginPage": LoginPage(container, self),42 "LogPatient": LogPatient(container, self),43 "DataRecording": DataRecording(container, self, ax),44 "SignUp": SignUp(container, self),45 "ResetPW": ResetPW(container, self)}46 for frame in self.frames:47 self.frames[frame].grid(row=0, column=0, sticky="nsew")48 # Starting page49 self.show_login_frame()50 # When called, passes the frame or page to be showed on windows51 def show_login_frame(self):52 frame = self.frames["LoginPage"]53 frame.tkraise()54 def show_patientLog_frame(self):55 frame = self.frames["LogPatient"]56 frame.tkraise()57 def show_dataRecording_frame(self):58 frame = self.frames["DataRecording"]59 frame.tkraise()60 def show_signUp_frame(self):61 frame = self.frames["SignUp"]62 frame.tkraise()63 def show_resetPW_frame(self):64 frame = self.frames["ResetPW"]65 frame.tkraise()66class DataRecording(tk.Frame):67 body_part_option_selected = ""68 duration_value = 0.069 session_interrupt = -170 # stopwatch71 running = False72 current_ticking_value = 18000 # This depends on current timezone, may be different in other regions. Starts at 073 ticking_value_max = 0 # initialization, actual value assigned on create_stopwatch() function74 timer_label = ""75 AbMode = 0 # start in raw intensity mode76 def __init__(self, parent, controller, ax):77 global data, x78 global integration_time, spectra_average79 global xmin, xmax, ymin, ymax80 global monitor_wave, monitor_index, monitor81 self.ax = ax82 self.x = x83 self.xmin = xmin84 self.xmax = xmax85 self.ymin = ymin86 self.ymax = ymax87 self.data = data88 self.line = Line2D(self.x, self.data, color='red')89 self.ax.add_line(self.line)90 self.ax.set_ylim(ymin * 0.8, ymax * 1.1)91 self.ax.set_xlim(self.xmin, self.xmax)92 monitor_wave = np.median(x)93 tk.Frame.__init__(self, parent)94 label = ttk.Label(self, text=f"Session Recording", font=LARGE_FONT)95 label.pack(side='top', pady=20)96 # This frame1 packs all the labels on the first column on the UI97 self.frame1 = tk.Frame(self)98 self.frame1.pack(side='left', anchor=tk.N)99 # This frame1 packs all the labels on the second column on the UI100 self.frame2 = tk.Frame(self)101 self.frame2.pack(side='left', anchor=tk.N)102 # This frame1 packs all the labels on the third column on the UI103 self.frame3 = tk.Frame(self)104 self.frame3.pack(side='left', anchor=tk.N)105 # ID design106 id_label = tk.Label(self.frame1, text="Patient ID:", font=SMALL_FONT)107 id_label.pack(side='top', pady=4)108 id_val = tk.Label(self.frame2, text=LogPatient.patient_id, font=SMALL_FONT)109 id_val.pack(side='top', pady=4)110 filler_label = tk.Label(self.frame3, text="")111 filler_label.pack(side='top')112 # BMI design113 bmi_label = tk.Label(self.frame1, text="BMI:", font=SMALL_FONT)114 bmi_label.pack(side='top', pady=4)115 bmi_val = tk.Label(self.frame2, text="auto", font=SMALL_FONT)116 bmi_val.pack(side='top', pady=4)117 filler_label = tk.Label(self.frame3, text="")118 filler_label.pack(side='top', pady=6)119 # Integration time design120 duration_label = tk.Label(self.frame1, text="Integration Time", font=SMALL_FONT)121 duration_label.pack(side='top', pady=4)122 self.duration_entry = tk.Entry(self.frame2, width='7', justify='right')123 self.duration_entry.pack(side='top', pady=4, anchor=tk.N)124 seconds_label = tk.Label(self.frame3, text="Seconds", height='2', font=SMALL_FONT)125 seconds_label.pack(side='top', pady=4)126 self.duration_entry.bind('<Return>', self.validate_integration_time)127 # Number of spectra design128 num_spectra_label = tk.Label(self.frame1, text="Number of Spectra Returned", font=SMALL_FONT)129 num_spectra_label.pack(side='top', pady=4)130 num_spectra_entry = tk.Entry(self.frame2, width='7', justify='right')131 num_spectra_entry.pack(side='top', pady=10)132 # Amount of spectra to average design133 spec_avg_label = tk.Label(self.frame1, text='Amount of Spectra to Average ', width='20', wraplength='150',134 font=SMALL_FONT)135 spec_avg_label.pack(side='top', pady=4)136 self.spec_avg_entry = tk.Entry(self.frame2, width='7', justify='right')137 self.spec_avg_entry.pack(side='top', pady=20)138 self.spec_avg_entry.bind('<Return>', self.validate_spec_avg)139 # Minimum wavelength label and entry field140 xmin_label = tk.Label(self.frame1, text='Minimum wavelength', font=SMALL_FONT)141 xmin_label.pack(side='top', pady=2)142 self.xmin_entry = tk.Entry(self.frame2, width='7', justify='right')143 self.xmin_entry.pack(side='top', pady=15)144 self.xmin_entry.insert(0, xmin) # AUTO INPUTS VALUE145 self.xmin_entry.bind('<Return>', self.validate_xmin)146 # Maximum wavelength label and entry field147 xmax_label = tk.Label(self.frame1, text='Maximum wavelength', height='2', font=SMALL_FONT)148 xmax_label.pack(side='top', pady=2)149 self.entryxmax = tk.Entry(self.frame2, width='7', justify='right')150 self.entryxmax.pack(side='top', pady=5)151 self.entryxmax.insert(0, xmax) # AUTO INPUTS VALUE152 self.entryxmax.bind('<Return>', self.validate_xmax)153 body_part_label = tk.Label(self.frame1, text="Body Location:", height='2', font=SMALL_FONT)154 body_part_label.pack(side='top', pady=4)155 self.body_part_option_selected = tk.StringVar()156 self.body_part_option_selected.set(hm.BodyParts[0]) # Initial Value157 body_part_options = ttk.OptionMenu(self.frame2, self.body_part_option_selected, *hm.BodyParts)158 body_part_options.pack(side='top', pady=15)159 btn_start_stop = ttk.Button(self.frame1, text="Start", command=lambda: start_stop_process())160 btn_start_stop.pack(side='top', pady=10)161 btn_save = ttk.Button(self.frame2, text="Save", command=lambda: save_recording())162 btn_save.pack(side='top', pady=10)163 btn_pause_resume = ttk.Button(self.frame1, text="Pause", command=lambda: pause_resume_process())164 btn_pause_resume.pack(side='top', pady=10)165 diff_patient_button = ttk.Button(self.frame2, text="Next Patient",166 command=lambda: controller.show_patientLog_frame())167 diff_patient_button.pack(side='top', pady=10)168 quit_button = tk.Button(self.frame1, text="Quit")169 quit_button.pack(side='bottom', pady=10)170 quit_button.bind('<ButtonRelease-1>', self.quit_app)171 button_reset_y = tk.Button(self.frame1, text='Reset Y axis scale')172 button_reset_y.pack(side='bottom', pady=10)173 button_reset_y.bind('<ButtonRelease-1>', self.reset_y)174 log_out_button = tk.Button(self.frame1, text="Log out", command=lambda: controller.show_login_frame())175 log_out_button.pack(side='bottom', pady=10)176 check_box_label = tk.Checkbutton(self.frame1, text="Interrupted session", command=lambda: box_toggled())177 check_box_label.pack(side='bottom', pady=10)178 # Disable pause while the clock is not started179 hm.disable_fields(btn_pause_resume)180 # Labels for the graph181 ax.set_xlabel('Wavelength (nm)')182 ax.set_ylabel('Counts')183 # Creates the design for the graph184 canvas = FigureCanvasTkAgg(fig, self)185 canvas.get_tk_widget().pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True)186 monitor_index = np.searchsorted(x, monitor_wave, side='left')187 monitor = np.round(self.data[monitor_index], decimals=3)188 self.text = self.ax.text(0.9, 0.9, monitor, transform=ax.transAxes, fontsize=14)189 #self.ax.axvline(x=monitor_wave, lw=2, color='blue', alpha=0.5) # Blue line in on the graph190 # This method changes a value when checkBox is checked meaning a session was interrupted191 def box_toggled():192 self.session_interrupt *= -1193 def save_csv_to_cloud(file_path):194 """ Upload csv file to Azure """195 blob = BlobClient.from_connection_string(conn_str="Connection String Place Holder",196 container_name="Container Name Place Holder",197 blob_name=file_path)198 with open(file_path, "rb") as up:199 blob.upload_blob(up)200 def save_recording():201 if self.session_interrupt == -1:202 print("Normal session")203 file_name = str(LogPatient.patient_id) + "_" + str(self.body_part_option_selected.get()) + ".csv"204 print(file_name)205 save_csv_to_cloud(file_name)206 else:207 # TODO: Message box will probably have to be a customized pop-up. You can't add an entry text field here208 result = tk.messagebox.askyesno("Interrupted session", "You have marked this session as interrupted.\n"209 "Data will be saved in different database")210 if result: # If user confirmed session was interrupted and he/she agrees with message211 # TODO: Data in different database212 print("Result:")213 print(result)214 return215 def pause_resume_process():216 if hm.is_pause_button(btn_pause_resume):217 pause_process()218 else:219 # check if no errors when re-entering fields220 if check_fields():221 resume_process()222 return223 def resume_process():224 btn_pause_resume["text"] = "Pause"225 start_stopwatch(self.timer_label)226 hm.disable_fields(body_part_options, self.duration_entry)227 # TODO228 # Connect to save again values with different body part in DB229 print(self.duration_value)230 print(self.body_part_option_selected.get())231 return232 def pause_process():233 # TODO234 # Do we want to change the duration and body part once user pauses? *** BUG ***235 btn_pause_resume["text"] = "Resume"236 self.running = False237 hm.enable_fields(body_part_options, self.duration_entry)238 return239 def start_stop_process():240 if check_fields(): # no errors241 if hm.is_start_button(btn_start_stop):242 start_process()243 else:244 stop_process()245 return246 def start_process():247 hm.disable_fields(btn_save, log_out_button, diff_patient_button, body_part_options, self.duration_entry)248 hm.enable_fields(btn_pause_resume)249 btn_start_stop["text"] = "Stop"250 create_stopwatch()251 start_stopwatch(self.timer_label)252 return253 def stop_process():254 hm.disable_fields(btn_pause_resume)255 btn_pause_resume["text"] = "Pause" # if stop the recording, we need to reset this button (bug)256 btn_start_stop["text"] = "Start"257 hm.enable_fields(btn_save, log_out_button, diff_patient_button, body_part_options, self.duration_entry)258 self.running = False259 self.timer_label.destroy()260 return261 # checks for any errors, prints them and returns False, otherwise no errors and returns True262 def check_fields():263 if hm.check_fields_inputs(durationEntry=self.duration_entry,264 bodyPartOption=self.body_part_option_selected.get()):265 self.duration_value = float(self.duration_entry.get())266 return True267 else:268 return False269 # region Stopwatch270 def create_stopwatch():271 self.timer_label = tk.Label(self.frame1, text="Stopwatch!", fg="black", font="Verdana 15 bold")272 self.timer_label.pack(pady=10)273 self.current_ticking_value = 18000 # we need to reset the timer after 1st recording274 # Cannot assign ticking_value_max until we know the duration_value and after being checked275 self.ticking_value_max = self.current_ticking_value + self.duration_value276 return277 def start_stopwatch(timer_label):278 self.running = True279 counter_label(timer_label)280 return281 def counter_label(timer_label):282 def count():283 if self.running and self.current_ticking_value <= self.ticking_value_max: # if from 0 to limit284 # To manage the initial delay.285 if self.current_ticking_value == 18000:286 display = "Starting..."287 else:288 tt = datetime.fromtimestamp(self.current_ticking_value)289 string = tt.strftime("%H:%M:%S")290 display = string291 timer_label['text'] = display # Or label.config(text=display)292 timer_label.after(1000, count)293 self.current_ticking_value += 1294 elif not self.running and self.current_ticking_value <= self.ticking_value_max: # if paused295 timer_label['text'] = "Paused..."296 else:297 timer_label['text'] = "Finished!"298 hm.disable_fields(btn_pause_resume)299 btn_pause_resume["text"] = "Pause"300 # Triggering the start of the counter.301 count()302 def quit_app(root, event):303 """ Quits the program """304 root.destroy()305 exit()306 def reset_y(self, event):307 data = spec.intensities(correct_nonlinearity=False)308 ymin = min(data)309 ymax = max(data)310 ax.set_ylim(ymin * 0.9, ymax * 1.1)311 def set_entry_config(self):312 """ This function handles new inputs on the text fields and it send values to spectrometer """313 global integration_time # , spectra_average314 spec.integration_time_micros(integration_time)315 # spec.scans_to_average(spectra_average)316 # write new configuration to dialog317 self.duration_entry.delete(0, "end")318 self.duration_entry.insert(0, integration_time / 1000) # write ms, but integration_time is microseconds319 def validate_integration_time(self, event):320 """ Update integration time and validates from 4ms to 65000 """321 global integration_time322 # typically OO spectrometers cant read faster than 4 ms323 int_time_temp = self.duration_entry.get()324 if int_time_temp.isdigit():325 if int(int_time_temp) > 65000:326 msg = "The integration time must be 65000 ms or smaller. You set " + int_time_temp327 self.set_entry_config()328 elif int(int_time_temp) < 4:329 msg = "The integration time must be greater than 4 ms. You set " + int_time_temp330 self.set_entry_config()331 else:332 integration_time = int(int_time_temp) * 1000 # convert ms to microseconds333 self.set_entry_config()334 else:335 msg = "Integration time must be an integer between 4 and 65000 ms. You set " + str(int_time_temp)336 self.set_entry_config()337 def validate_spec_avg(self, event):338 # averaging needs to be implemented here in code339 global spectra_average340 spectra_average = self.spec_avg_entry.get()341 if spectra_average.isdigit():342 spec.scans_to_average(int(spectra_average))343 else:344 msg = "spectra_average must be an integer. You tried " + str(spectra_average) + ". Setting value to 1."345 spectra_average = 1346 self.spec_avg_entry.delete(0, "end")347 self.spec_avg_entry.insert(0, spectra_average)348 def validate_xmax(self, event):349 """ Validates max wavelength to show in graph """350 global xmax351 xmax_temp = self.entryxmax.get()352 try:353 float(xmax_temp)354 xmax_temp = float(self.entryxmax.get())355 if xmax_temp > xmin:356 xmax = xmax_temp357 self.entryxmax.delete(0, 'end')358 self.entryxmax.insert(0, xmax) # set text in box359 self.ax.set_xlim(xmin, xmax)360 else:361 msg = "Maximum wavelength must be larger than minimum wavelength. You entered " + str(362 xmax_temp) + " nm."363 self.entryxmax.delete(0, 'end')364 self.entryxmax.insert(0, xmax) # set text in box365 except:366 self.entryxmax.delete(0, 'end')367 self.entryxmax.insert(0, xmax) # set text in box to unchanged value368 def validate_xmin(self, event):369 """ Validates min wavelength to show in graph """370 global xmin371 xmin_temp = self.xmin_entry.get()372 try:373 float(xmin_temp)374 xmin_temp = float(self.xmin_entry.get())375 if xmin_temp < xmax:376 xmin = xmin_temp377 self.xmin_entry.delete(0, 'end')378 self.xmin_entry.insert(0, xmin) # set text in box379 self.ax.set_xlim(xmin, xmax)380 else:381 msg = "Minimum wavelength must be smaller than maximum wavelength. You entered " + str(382 xmin_temp) + " nm."383 self.xmin_entry.delete(0, 'end')384 self.xmin_entry.insert(0, xmin) # set text in box385 except:386 self.xmin_entry.delete(0, 'end')387 self.xmin_entry.insert(0, xmin) # set text in box to unchanged value388 def update(self, data):389 """ This function manages the update of the390 spectral data in the graph. It issues a read request to the spectrometer,391 then conditionally processes the received data """392 file_name = str(LogPatient.patient_id) + "_" + str(self.body_part_option_selected.get()) + ".csv"393 not2save = str(LogPatient.patient_id) + "_Select an option.csv"394 if file_name != not2save:395 with open(file_name, "w", newline='') as towrite:396 lineWriter = csv.writer(towrite, quotechar='|', delimiter='\n', quoting=csv.QUOTE_NONE)397 lineWriter.writerow(self.data)398 self.data = spec.intensities()399 self.data = np.array(self.data, dtype=float)400 self.line.set_data(self.x, self.data)401 monitor = np.round(self.data[monitor_index], decimals=3)402 self.text.set_text(monitor)403 return self.line,404 # endregion405fig, ax = plt.subplots()406app = Controller(ax)407ani = animation.FuncAnimation(fig, app.frames["DataRecording"].update, interval=10, blit=False)...
test_interruptions.py
Source:test_interruptions.py
...144 results = suite.run(expect_interruption=True)145 assert results.session.results.global_result.is_interrupted()146 assert checkpoint.called147@pytest.fixture148def session_interrupt():149 callback = Checkpoint()150 slash.hooks.session_interrupt.register(callback) # pylint: disable=no-member151 return callback152@pytest.fixture153def test_interrupt_callback():154 callback = Checkpoint()155 slash.hooks.test_interrupt.register(callback) # pylint: disable=no-member156 return callback157@pytest.fixture158def interrupted_suite(suite, interrupted_index):159 for index, test in enumerate(suite):160 if index == interrupted_index:161 test.append_line('raise KeyboardInterrupt()')162 test.expect_interruption()...
test_plugin.py
Source:test_plugin.py
1import subprocess2import pytest3from gi.repository import Gtk4from wiring import Graph5from tomate.pomodoro import Bus, Config, Events6from tomate.ui.testing import Q7SECTION_NAME = "exec_plugin"8@pytest.fixture9def check_output(mocker, monkeypatch):10 import exec_plugin11 check_output = mocker.Mock(spec=subprocess.check_output)12 monkeypatch.setattr(exec_plugin.subprocess, "check_output", check_output)13 return check_output14@pytest.fixture15def bus() -> Bus:16 return Bus()17@pytest.fixture18def graph() -> Graph:19 g = Graph()20 g.register_instance(Graph, g)21 return g22@pytest.fixture23def config(bus, tmpdir):24 instance = Config(bus)25 tmp_path = tmpdir.mkdir("tomate").join("tomate.config")26 instance.config_path = lambda: tmp_path.strpath27 return instance28@pytest.fixture29def plugin(bus, config, graph):30 graph.providers.clear()31 graph.register_instance("tomate.config", config)32 graph.register_instance("tomate.bus", bus)33 import exec_plugin34 instance = exec_plugin.ExecPlugin()35 instance.configure(bus, graph)36 return instance37@pytest.mark.parametrize(38 "event, option",39 [40 (Events.SESSION_START, "start_command"),41 (Events.SESSION_INTERRUPT, "stop_command"),42 (Events.SESSION_END, "finish_command"),43 ],44)45def test_execute_command_when_event_is_trigger(event, option, bus, check_output, config, plugin):46 plugin.activate()47 bus.send(event)48 command = config.get(SECTION_NAME, option)49 check_output.assert_called_once_with(command, shell=True, stderr=subprocess.STDOUT)50@pytest.mark.parametrize(51 "event, option",52 [53 (Events.SESSION_START, "start_command"),54 (Events.SESSION_INTERRUPT, "stop_command"),55 (Events.SESSION_END, "finish_command"),56 ],57)58def test_does_not_execute_commands_when_they_are_not_configured(event, option, bus, check_output, config, plugin):59 config.remove(SECTION_NAME, option)60 plugin.activate()61 assert bus.send(event) == [False]62 check_output.assert_not_called()63def test_execute_command_fail(bus, config, plugin):64 config.set(SECTION_NAME, "start_command", "fail")65 plugin.activate()66 assert bus.send(Events.SESSION_START) == [False]67class TestSettingsWindow:68 @pytest.mark.parametrize(69 "option,command",70 [71 ("start_command", "echo start"),72 ("stop_command", "echo stop"),73 ("finish_command", "echo finish"),74 ],75 )76 def test_with_custom_commands(self, option, command, plugin):77 dialog = plugin.settings_window(Gtk.Window())78 switch = Q.select(dialog.widget, Q.props("name", f"{option}_switch"))79 assert switch.props.active is True80 entry = Q.select(dialog.widget, Q.props("name", f"{option}_entry"))81 assert entry.props.text == command82 @pytest.mark.parametrize("option", ["start_command", "stop_command", "finish_command"])83 def test_without_custom_commands(self, option, config, plugin):84 config.remove_section(SECTION_NAME)85 config.save()86 assert config.has_section(SECTION_NAME) is False87 dialog = plugin.settings_window(Gtk.Window())88 switch = Q.select(dialog.widget, Q.props("name", f"{option}_switch"))89 assert switch.props.active is False90 entry = Q.select(dialog.widget, Q.props("name", f"{option}_entry"))91 assert entry.props.text == ""92 @pytest.mark.parametrize("option", ["start_command", "stop_command", "finish_command"])93 def test_disable_command(self, option, config, plugin):94 dialog = plugin.settings_window(Gtk.Window())95 switch = Q.select(dialog.widget, Q.props("name", f"{option}_switch"))96 switch.props.active = False97 entry = Q.select(dialog.widget, Q.props("name", f"{option}_entry"))98 assert entry.props.sensitive is False99 assert entry.props.text == ""100 dialog.widget.emit("response", 0)101 assert dialog.widget.props.window is None102 config.load()103 assert config.has_option(SECTION_NAME, option) is False104 @pytest.mark.parametrize("option", ["start_command", "stop_command", "finish_command"])105 def test_configure_command(self, option, config, plugin):106 config.remove(SECTION_NAME, option)107 dialog = plugin.settings_window(Gtk.Window())108 switch = Q.select(dialog.widget, Q.props("name", f"{option}_switch"))109 switch.props.active = True110 entry = Q.select(dialog.widget, Q.props("name", f"{option}_entry"))111 assert entry.props.sensitive is True112 entry.props.text = "echo changed"113 dialog.widget.emit("response", 0)114 assert dialog.widget.props.window is None115 config.load()...
indicator_plugin.py
Source:indicator_plugin.py
1import logging2import gi3gi.require_version("AppIndicator3", "0.1")4from wiring import Graph5from gi.repository import AppIndicator36import tomate.pomodoro.plugin as plugin7from tomate.pomodoro import Events, on, Bus, suppress_errors, TimerPayload8from tomate.ui import Systray9logger = logging.getLogger(__name__)10class IndicatorPlugin(plugin.Plugin):11 @suppress_errors12 def __init__(self):13 super().__init__()14 self.menu = None15 self.config = None16 self.session = None17 self.indicator = None18 def configure(self, bus: Bus, graph: Graph) -> None:19 super().configure(bus, graph)20 self.menu = graph.get("tomate.ui.systray.menu")21 self.config = graph.get("tomate.config")22 self.session = graph.get("tomate.session")23 self.indicator = self.create_widget()24 @suppress_errors25 def activate(self):26 logger.debug("action=active")27 super().activate()28 self.menu.connect(self.bus)29 self.graph.register_instance(Systray, self)30 if self.session.is_running():31 self.show()32 else:33 self.hide()34 @suppress_errors35 def deactivate(self):36 logger.debug("action=deactivate")37 super().deactivate()38 self.menu.disconnect(self.bus)39 self.graph.unregister_provider(Systray)40 self.hide()41 @suppress_errors42 @on(Events.TIMER_UPDATE)43 def update_icon(self, payload: TimerPayload):44 logger.debug("action=update-icon payload=%s", payload)45 icon_name = self.icon_name(payload.elapsed_percent)46 if icon_name != self.indicator.get_icon():47 self.indicator.set_icon(icon_name)48 @suppress_errors49 @on(Events.SESSION_START)50 def show(self, **__):51 logger.debug("action=show")52 self.indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)53 @suppress_errors54 @on(Events.SESSION_END, Events.SESSION_INTERRUPT)55 def hide(self, **__):56 logger.debug("action=hide")57 self.indicator.set_status(AppIndicator3.IndicatorStatus.PASSIVE)58 self.indicator.set_icon("tomate-idle")59 @staticmethod60 def icon_name(percent):61 return "tomate-{:02.0f}".format(percent)62 def create_widget(self):63 indicator = AppIndicator3.Indicator.new(64 "tomate", "tomate-idle", AppIndicator3.IndicatorCategory.APPLICATION_STATUS65 )66 indicator.set_icon_theme_path(self.first_icon_theme_path())67 indicator.set_menu(self.menu.widget)68 return indicator69 def first_icon_theme_path(self):...
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!