class Apscheduler(object): def __init__(self, scheduler): ''' https://apscheduler.readthedocs.io/en/latest/userguide.html?highlight=add_job Parameters ---------- scheduler: [str] 调度器,根据开发需求选择相应的调度器 'BlockingScheduler' 阻塞式调度器: 适用于只跑调度器的程序 'BackgroundScheduler' 后台调度器: 适用于非阻塞的情况,调度器会在后台独立运行 'AsyncIOScheduler' AsyncIO调度器: 适用于应用使用AsnycIO的情况 'GeventScheduler' Gevent调度器: 适用于应用通过Gevent的情况 'TornadoScheduler' Tornado调度器: 适用于构建Tornado应用 'TwistedScheduler' Twisted调度器: 适用于构建Twisted应用 'QtScheduler' Qt调度器: 适用于构建Qt应用 ''' import logging logging.basicConfig() scheduler = str(scheduler).lower() if ('blocking' in scheduler): from apscheduler.schedulers.blocking import BlockingScheduler self.scheduler = BlockingScheduler() elif ('background' in scheduler): from apscheduler.schedulers.background import BackgroundScheduler self.scheduler = BackgroundScheduler() elif ('asyncio' in scheduler): from apscheduler.schedulers.asyncio import AsyncIOScheduler self.scheduler = AsyncIOScheduler() elif ('gevent' in scheduler): from apscheduler.schedulers.gevent import GeventScheduler self.scheduler = GeventScheduler() elif ('tornado' in scheduler): from apscheduler.schedulers.tornado import TornadoScheduler self.scheduler = TornadoScheduler() elif ('twisted' in scheduler): from apscheduler.schedulers.twisted import TwistedScheduler self.scheduler = TwistedScheduler() elif ('qt' in scheduler): from apscheduler.schedulers.qt import QtScheduler self.scheduler = QtScheduler() def Add(self, trigger, func, args=(), kwargs={}, date=None, period=None, jobid=None, name=None, **add_kwargs): ''' Parameters ---------- trigger: [str] 'cron': 某一定时时刻执行 'interval': 每隔多长时间执行 'date': 只有某一该执行一次(一次性任务) date: [str] 'year/month/day hour:minute:second week' week: (1) trigger='cron': week=星期几 [str]: 'mon','tue','wed','thu','fri','sat','sun' (1.1) 每分钟的第5秒:date='// ::5' (1.2) 每小时的第5分钟:date='// :5:' (1.3) 每个星期五:date='// :: fri' (2) trigger='interval': week=每隔多少个星期[int] 注意,data中最多只允许有2个空格,第1个空格是年月日与时分秒之间,第2个空格是时分秒与星期之间,其他地方的空格会造成时间解释错误,从而运行错误 period: [str] period='start_date--end_date--timezone' start_date, end_date: [str] 'year/month/day' timezone: [str of int] (1) period='2019/5/21--2020/7/16--8' => 开始日期2019/5/21,结束日期2020/7/16,时区8 (2) period='2019/5/21--//--8' => 开始日期2019/5/21,没有结束日期,时区8 (3) period='//--2020/7/16--8' => 没有开始日期,结束日期2020/7/16,时区8 (4) period='2019/5/21--2020/7/16--' => 开始日期2019/5/21,结束日期2020/7/16,local电脑系统默认时区 ''' import numpy as np def toint(x): for i in range(len(x)): try: x[i] = int(x[i]) except: pass return x date = date.split(' ') year, month, day = toint(date[0].split('/')) hour, minute, second = toint(date[1].split(':')) week = '' if (len(date) == 2) else date[2] date_kwargs = {} #---------------------------------------- if (trigger == 'cron'): if (year != ''): date_kwargs['year'] = year if (month != ''): date_kwargs['month'] = month if (day != ''): date_kwargs['day'] = day if (hour != ''): date_kwargs['hour'] = hour if (minute != ''): date_kwargs['minute'] = minute if (second != ''): date_kwargs['second'] = second if (week != ''): date_kwargs['day_of_week'] = week #---------------------------------------- elif (trigger == 'interval'): if (week != ''): date_kwargs['weeks'] = int(week) if (day != ''): date_kwargs['days'] = day if (hour != ''): date_kwargs['hours'] = hour if (minute != ''): date_kwargs['minutes'] = minute if (second != ''): date_kwargs['seconds'] = second #---------------------------------------- elif (trigger == 'date'): run_date = '%i-%i-%i %i:%i:%i' % (year, month, day, hour, minute, second) date_kwargs['run_date'] = run_date #---------------------------------------- if (period is not None): period = period.split('--') if (period[0] != '//'): date_kwargs['start_date'] = '%s-%s-%s' % tuple( period[0].split('/')) if (period[1] != '//'): date_kwargs['end_date'] = '%s-%s-%s' % tuple( period[1].split('/')) if (len(period) == 3): date_kwargs['timezone'] = period[2] #---------------------------------------- add_kwargs.update(date_kwargs) self.scheduler.add_job(func=func, trigger=trigger, args=args, kwargs=kwargs, id=jobid, name=name, **add_kwargs) def Get(self, jobid): ''' Parameters ---------- jobid: (1) =None: return all jobs in a list (2) =[str]: return this job ''' if (jobid is None): return self.scheduler.get_jobs() else: return self.scheduler.get_job(jobid) def Remove(self, jobid): ''' ''' if (jobid is None): self.scheduler.remove() else: self.scheduler.remove_job(jobid) def Pause(self, jobid): ''' ''' if (jobid is None): self.scheduler.pause() else: self.scheduler.pause_job(jobid) def Resume(self, jobid): ''' ''' if (jobid is None): self.scheduler.resume() else: self.scheduler.resume_job(jobid) def Start(self, *args, **kwargs): ''' ''' self.scheduler.start(*args, **kwargs) def Shutdown(self, *args, **kwargs): ''' ''' self.scheduler.shutdown(*args, **kwargs)
class MainWindow(qtw.QMainWindow, Ui_MainWindow): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setupUi(self) self.setWindowFlags(qtc.Qt.WindowCloseButtonHint) self.setWindowIcon(qtg.QIcon('icon.png')) # self.setWindowIcon(qtg.QIcon('./src/ressource/icon.png')) self.setFixedSize(130, 60) self.offButton.setChecked(True) self.onButton.toggled.connect(self.on_off_toggle) self.timerSpinBox.setValue(10) self.scheduler = QtScheduler() self.tray = qtw.QSystemTrayIcon(self) self.tray.setIcon(qtg.QIcon('icon.png')) # self.tray.setIcon(qtg.QIcon('./src/ressource/icon.png')) # self.tray.setIcon(qtg.QIcon(':/ressource/icon.png')) self.tray.setToolTip('BT keep Alive') quit_action = qtw.QAction("Exit", self) quit_action.triggered.connect(qtw.qApp.quit) tray_menu = qtw.QMenu() tray_menu.addAction(quit_action) self.tray.setContextMenu(tray_menu) self.tray.setVisible(True) self.tray.show() self.tray.activated.connect(self.on_systray_activated) def on_systray_activated(self, reason): if self.isVisible() and reason != qtw.QSystemTrayIcon.Context: self.hide() elif not self.isVisible() and reason != qtw.QSystemTrayIcon.Context: self.show() self.activateWindow() def closeEvent(self, event): self.hide() event.ignore() def on_off_toggle(self): if self.offButton.isChecked(): self.timerSpinBox.setEnabled(True) self.scheduler.shutdown() else: self.timerSpinBox.setEnabled(False) self.scheduler.add_job(self.play_sound, 'interval', seconds=self.timerSpinBox.value() * 60) self.scheduler.start() def play_sound(self): p = pyaudio.PyAudio() WAVEDATA = ' ' stream = p.open(format=p.get_format_from_width(1), channels=1, rate=11000, output=True) stream.write(WAVEDATA) stream.stop_stream() stream.close() p.terminate()
class PsKiller(QtGui.QWidget): def __init__(self): """docstring for __init__""" super(PsKiller, self).__init__() self.init_ui() self.updateTableSignal = UpdateTableSignal() self.updateTableSignal.updateTable.connect(lambda: self.refresh_list(self.search_edit.text())) self.scheduler = QtScheduler() self.scheduler.add_job(self.update_table_emitter, "interval", seconds=2) self.scheduler.start() def init_ui(self): """docstring for init_ui""" self.pid_edit = QtGui.QLineEdit() kill_btn = QtGui.QPushButton("Kill Me", self) kill_btn.clicked.connect(self.kill_ps) self.header = ["PID", "Process Name", "Absolute Path", "Command Line"] self.table_view = ListTableView() self.table_view.setModel(PsInfoModel(self.get_ps_info(""), self.header, self)) self.table_view.clicked.connect(self.cell_click) self.table_view.setMouseTracking(True) self.table_view.entered.connect(self.show_cell_content) self.table_view.verticalHeader().setVisible(False) self.table_view.setColumnWidth(2, 300) self.table_view.setColumnWidth(3, 300) self.search_edit = SearchBox() self.search_edit.keyPressed.connect(self.search_by_keyword) self.status_bar = QtGui.QStatusBar() self.status_bar.showMessage("ready") grid = QtGui.QGridLayout() grid.setSpacing(10) grid.addWidget(self.pid_edit, 1, 0) grid.addWidget(kill_btn, 1, 1) grid.addWidget(self.search_edit, 2, 0) grid.addWidget(self.table_view, 3, 0, 5, 2) grid.addWidget(self.status_bar, 9, 0) self.setLayout(grid) self.setWindowTitle("PS Killer") self.setGeometry(300, 300, 300, 150) self.resize(800, 400) self.show() def update_table_emitter(self): self.updateTableSignal.updateTable.emit() def refresh_list(self, keyword=""): self.table_view.setModel(PsInfoModel(self.get_ps_info(keyword), self.header, self)) def get_ps_info(self, keyword): pinfo_arr = [] for proc in psutil.process_iter(): try: pinfo = proc.as_dict(attrs=["pid", "name", "exe", "cmdline"]) except psutil.NoSuchProcess: pass else: if keyword == "": pinfo_arr.append(pinfo) else: if ( re.search(str(keyword).lower(), pinfo["name"].lower()) != None or re.search(str(keyword).lower(), str(pinfo["exe"]).lower()) != None or ( pinfo["cmdline"] != None and re.search(str(keyword).lower(), " ".join(pinfo["cmdline"]).lower()) != None ) ): pinfo_arr.append(pinfo) return pinfo_arr def search_by_keyword(self): """docstring for search_by_keyword""" keyword = self.search_edit.text() if keyword != "": self.refresh_list(keyword) else: self.refresh_list() def kill_ps(self): """docstring for kill_ps""" pid = self.pid_edit.text() try: pid = int(pid) process = psutil.Process(pid) for child in process.children(recursive=True): child.kill() process.kill() self.status_bar.showMessage("Process " + str(pid) + " is killed") except psutil.NoSuchProcess: self.status_bar.showMessage("Process " + str(pid) + " is not exist") except psutil.AccessDenied: self.status_bar.showMessage("Unable kill process " + str(pid) + ".Must be a root user.") except ValueError: self.status_bar.showMessage("Process " + str(pid) + " is an invalidated pid.") def closeEvent(self, event): self.scheduler.shutdown() def cell_click(self, item): cell_content = item.data() selected_val = cell_content.toPyObject() if isinstance(selected_val, int): self.pid_edit.setText(str(selected_val)) else: self.status_bar.showMessage(selected_val + " is invalid!") def show_cell_content(self, item): """docstring for show_cell_content""" current_value = item.data().toPyObject() if current_value != None: self.status_bar.showMessage(str(current_value))