def __init__(self, master):# Constructor method self.txt = '0' # Global var to work with text box contents self.NL_flag = True #print('init=' + str(self.NL_flag)) self.turn_NumLock() master.title('NumPad Calculator') w = master.winfo_screenwidth() # width of display h = master.winfo_screenheight() # hight of display w = w//2 # center of display h = h//2 # center of display w = w - 300 # offset from center h = h - 200 # offset from center master.geometry('+{}+{}'.format(w, h)) master.configure(bg='gray94', padx=2, pady=4)#lavender, azure2 master.grid_columnconfigure(0, weight=1) master.grid_rowconfigure(0, weight=1) self.e = ttk.Entry(master, font=('Helvetica', 20, 'bold')) self.e.grid(sticky=EW,row=1, columnspan=5, padx=3, pady=3) self.e.focus_set() # Sets focus on the text box text area _set self.lb = Listbox(master, height=7, bg="gray94", fg='gray10', font=('Courier New', 12, 'bold'), relief='flat', selectmode='single', activestyle='none')#width=32,,Helvetica self.lb.grid(sticky="nsew",row=0, columnspan=5, padx=3, pady=3) scroll_lb = ttk.Scrollbar( orient=VERTICAL, command=self.lb.yview) scroll_lb.grid(sticky='nse',column=4, row=0) self.lb.config(yscrollcommand=scroll_lb.set) self.lb.bind("<Double-Button-1>", self.listboxclick) #ListboxSelect, <Double-Button-1> self.r_var = IntVar() self.r_var.set(0) self.degrees = Radiobutton(text='Degrees', variable=self.r_var, command= self.degreesorradians, value=0) self.radians = Radiobutton(text='Radians', variable=self.r_var, command=self.degreesorradians, value=1) self.degrees.grid(sticky="w",row=3, column=0, padx=3, pady=3) self.radians.grid(sticky="w",row=4, column=0, padx=3, pady=3) self.cb = ttk.Combobox(master, width=9, values=("Decimal", "Hex", "Binary", "Octal")) self.cb.set("Decimal") self.cb.grid(sticky="w",row=5, column=0) self.cb.bind('<<ComboboxSelected>>', self.onselect) # Generating Buttons ttk.Button(master, text="√", command=lambda: self.evaluation('sqroot')).grid(row=3, column=1, padx=2, pady=2) #, width=10 ttk.Button(master, text="x²", command=lambda: self.evaluation('square')).grid(row=3, column=2, padx=2, pady=2) ttk.Button(master, text="LOG10", command=lambda: self.evaluation('LOG10')).grid(row=3, column=3, padx=2, pady=2) ttk.Button(master, text="10ˣ", command=lambda: self.evaluation('10^x')).grid(row=3, column=4, padx=2, pady=2) ttk.Button(master, text="cos", command=lambda: self.evaluation('cos')).grid(row=4, column=1, padx=2, pady=2) ttk.Button(master, text="sin", command=lambda: self.evaluation('sin')).grid(row=4, column=2, padx=2, pady=2) ttk.Button(master, text="tan", command=lambda: self.evaluation('tan')).grid(row=4, column=3, padx=2, pady=2) ttk.Button(master, text="1/X", command=lambda: self.evaluation('1/X')).grid(row=4, column=4, padx=2, pady=2) ttk.Button(master, text="exp", command=lambda: self.evaluation('exp')).grid(row=5, column=1, padx=2, pady=2) ttk.Button(master, text="lnX", command=lambda: self.evaluation('lnX')).grid(row=5, column=2, padx=2, pady=2) ttk.Button(master, text="PI", command=lambda: self.evaluation('PI')).grid(row=5, column=3, padx=2, pady=2) ttk.Button(master, text="Help", command = self.about).grid(row=5, column=4, padx=2, pady=2) # bind key strokes self.e.bind('<Key>', lambda evt: self.keyaction(evt)) hk = SystemHotkey()# not supported by MacOS => to be commented out for MacOS #hk2 = SystemHotkey()# not supported by MacOS => to be commented out for MacOS hk.register(['kp_numlock'], overwrite=True, callback=lambda event: self.iconifyordeiconify())# not supported by MacOS => to be commented out for MacOS
def main(): global stay_looped hk = SystemHotkey() hk.register(('control', 'f8'), callback=lambda x: _capture_and_detect()) hk.register(('control', 'f12'), callback=lambda y: _stop_loop()) while stay_looped: time.sleep(1) sys.exit('exiting...')
class HotkeyManager(QtCore.QObject): triggered = QtCore.Signal(object) def __init__(self, parent=None): super().__init__(parent) self.keys = [] self.hk = SystemHotkey() def addKey(self, keyCombo): self.hk.register(keyCombo, callback=self.triggered.emit)
class GlobalHotkey(QObject): pressed = Signal() def __init__(self, parent: Optional[QObject]): super().__init__(parent) self._hk = SystemHotkey() def is_registered(self, key): key = set(key) return any(set(k) == key for k in self._hk.keybinds) def register(self, key_sequence: Optional[QKeySequence]): key = self.convert_key_sequence(key_sequence) if key and self.is_registered(key): logger.debug("Already registered: %s", key) return self.unregister() if key_sequence and not key_sequence.isEmpty(): logger.info("Registering hotkey: %s", key) # If this fails, we get a system_hotkey.SystemRegisterError # exception, but in a different thread - so we can neither catch it # here nor is it logged. self._hk.register(key, callback=self._callback) @staticmethod def convert_key_sequence(key_sequence: QKeySequence): if not key_sequence or key_sequence.isEmpty(): return None # Restrict to the first key key_sequence = QKeySequence(key_sequence[0]) # Convert to format for SystemHotkey - simple approach, may not be # sufficient. key = key_sequence.toString(QKeySequence.PortableText).split("+") key = [part.lower() for part in key] if "meta" in key: key.remove("meta") key = ["super"] + key return key def unregister(self): for key in self._hk.keybinds: logger.info("Unregistering hotkey: %s", (key, )) self._hk.unregister(key) def _callback(self, *_, **__): self.pressed.emit()
def main(): global note_map print("疯物之诗琴 by luern0313") print("世界线变动率:1.0.1.7546855") print("\n如果要使用快捷键演奏:") print("ctrl + shift + 数字键 :开始演奏对应的曲目") print("ctrl + shift + s : 停止演奏") read_configure() while True: try: global file_list file_list = os.listdir("midi/") print("选择要打开的文件(热键对应前十个):") print("\n".join( [str(i) + "、" + file_list[i] for i in range(len(file_list))])) hk = SystemHotkey(consumer=play_hot) for i in range(10): hk.register(('control', 'shift', str(i)), i) hk2 = SystemHotkey() hk2.register(('control', 'shift', 's'), callback=stop_hot) midi = mido.MidiFile("midi/" + file_list[int(input("请输入文件前数字序号:"))]) print_split_line() tracks = midi.tracks base_note = get_base_note(tracks) if configure[ "lowest_pitch_name"] == -1 else configure["lowest_pitch_name"] note_map = { note[i] + base_note * 12: key[i] for i in range(len(note)) } time.sleep(1) for msg in midi.play(): if msg.type == "note_on" or msg.type == "note_off": note_list = get_note(msg.note) for n in note_list: if n in note_map: if msg.type == "note_on": if vk[note_map[n]] in pressed_key: release_key(vk[note_map[n]]) press_key(vk[note_map[n]]) elif msg.type == "note_off": release_key(vk[note_map[n]]) except Exception as e: print("ERR:" + str(e))
class common_ipc(QMainWindow, Ui_main_form): # 定义一个热键信号 sig_keyhot = pyqtSignal(str) def __init__(self): # 1. 简单的绘制一个窗口 self.version = 'V1.0' super(common_ipc, self).__init__() self.setupUi(self) self.update_tbrow.setText("版本已更新,请去 https://gitee.com/Setless7/PathOfTrade/release_version 下载") self.price_lwidget = cc.price_lwidget() self.price_lwidget.addprice_lwidget(self) self.price_lwidget.add_item(('40 chaos', '100', '1小时前')) self.keyBorder = KeyBorder() # 2. 设置我们的自定义热键响应函数 self.sig_keyhot.connect(self.key_press_event) # 3. 初始化两个热键 self.hk_start, self.hk_stop = SystemHotkey(), SystemHotkey() # 4. 绑定快捷键和对应的信号发送函数 self.hk_start.register(('control', 'd'), callback=lambda x: self.send_key_event("start")) self.hk_stop.register(('control', '2'), callback=lambda x: self.send_key_event("stop")) # 热键处理函数 def key_press_event(self, i_str): time.sleep(0.05) self.keyBorder.key_up('d') time.sleep(0.05) self.keyBorder.key_up('ctrl') time.sleep(0.05) self.keyBorder.key_down_up_team('ctrl', 'c') self.showMinimized() self.showNormal() # 热键信号发送函数(将外部信号,转化成qt信号) def send_key_event(self, i_str): self.sig_keyhot.emit(i_str) def get_clipboard_text(self): clipboard.OpenClipboard() text = clipboard.GetClipboardData(win32con.CF_TEXT) clipboard.CloseClipboard() return text.decode('GBK')
class Translater(QMainWindow, Ui_MainWindow): # 定义一个热键信号 sig_keyhot = pyqtSignal(str) def __init__(self, parent=None): # 继承主窗口类 super(Translater, self).__init__(parent) # 设置应用图标 # self.setWindowIcon(QIcon('source/book.png')) # 获取屏幕对象 self.screen = QDesktopWidget().screenGeometry() self.setupUi(self) # 仅支持最小化以及关闭按钮 self.setWindowFlags(Qt.WindowMinimizeButtonHint | Qt.WindowMaximizeButtonHint | Qt.WindowCloseButtonHint) # 去掉 toolbar 右键菜单 self.setContextMenuPolicy(Qt.NoContextMenu) # self.textEdit.text() self.textEdit.setText("test value") self.translate.clicked.connect(self.translate_click) self.sig_keyhot.connect(self.translate_click) self.hk = SystemHotkey() self.hk.register(('control', 'shift', 'c'), callback=lambda x: self.send_key_event("start")) def translate_click(self): if self.checkBox.checkState() == Qt.Checked: rawtext = format_str(getCopyText()) else: rawtext = self.textEdit.toPlainText() content = bfs.translate1(rawtext, 'en', 'zh') content = content['trans_result'][0]['dst'] self.textEdit_2.setText(content) # 热键信号发送函数(将外部信号,转化成qt信号) def send_key_event(self, i_str): self.sig_keyhot.emit(i_str)
def test_errors_raised_in_main(): hk = SystemHotkey() key = ('5', ) cb = lambda e: print('hi') hk.register(key, callback=cb) try: hk.register(key, callback=cb) except SystemRegisterError: pass else: raise Exception('fail') hk.unregister(key) try: hk.unregister(key) except UnregisterError: pass else: raise Exception('fail') bad_key = ('badkey ..', ) try: hk.register(bad_key, callback=cb) except InvalidKeyError: pass else: raise Exception('fail') try: hk.unregister(bad_key) except: pass else: raise Exception('fail')
def test_errors_raised_in_main(): hk = SystemHotkey() key = ('5',) cb = lambda e: print('hi') hk.register(key, callback=cb) try: hk.register(key, callback=cb) except SystemRegisterError: pass else: raise Exception('fail') hk.unregister(key) try: hk.unregister(key) except UnregisterError: pass else: raise Exception('fail') bad_key = ('badkey ..',) try: hk.register(bad_key, callback=cb) except InvalidKeyError: pass else: raise Exception('fail') try: hk.unregister(bad_key) except: pass else: raise Exception('fail')
class UncrumpledWindow(KeyBinder, Screen, Style, Responses, Requests): supported_bind_handlers = ('on_key_down',) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.window = Window self.hk = SystemHotkey(consumer=self.sys_hotkey_handler, check_queue_interval=0.001) self.hk.register(['f7'], self.req_system_get) # JFT self.queue = queue.Queue() Clock.schedule_interval(lambda e: self.check_queue(), 0.01) def check_queue(self): try: func = self.queue.get(block=False) except queue.Empty: pass else: try: func() except Exception as err: # An error happend over on the backend :( import pdb;pdb.set_trace() def run_in_main(self, func): self.queue.put(func) # This is run in another thread, errors here do not get propogated due to async.. def sys_hotkey_handler(self, event, hotkey, args): self.active_profile = 'default' program, pid, = peasoup.process_exists() # TODO rename this func profile = self.active_profile # Mainly for testing, a hotkey has bound it's own callback if args[0]: self.run_in_main(args[0][0]) else: self.run_in_main(lambda: self.req_hotkey_pressed( profile, program, hotkey))
def main(): print("=================================================") print("|| QUIC SEARCH ||") print("|| Author: Jokin ||") print("|| Version: v1.3.1 ||") print("=================================================") # 写音效文件 if (os.path.exists('./0.mp3') == False): print('wir') with open('./0.mp3', 'wb') as f: f.write(base64.b64decode(S0)) f.close if (os.path.exists('./1.mp3') == False): with open('./1.mp3', 'wb') as f: f.write(base64.b64decode(S1)) f.close if (os.path.exists('./2.mp3') == False): with open('./2.mp3', 'wb') as f: f.write(base64.b64decode(S2)) f.close if (os.path.exists('./3.mp3') == False): with open('./3.mp3', 'wb') as f: f.write(base64.b64decode(S3)) f.close # 中心节点选择 改快捷键操作 select_node() print("-> 初始化中,请稍候...") # 注册热键 hotkey hk = SystemHotkey() hk.register(('control', 'shift', 'alt', 'z'), callback=changemode) hk.register(('control', 'shift', 'alt', 's'), callback=send_note) hk.register(('control', 'shift', 'alt', 'x'), callback=receive_note) # 获取白名单 get_whitelist() print("-> 初始化完成!") # 授权 login() # 模式选择 默认0模式 # select_mode() # 获取数据库列表 get_databaselist() # 选择数据库 database = select_database() # print(database) # 获取数据库 get_database(database) # 剪贴板监听 clipboard_listen()
class TaskBarIcon(wx.adv.TaskBarIcon): """Taskbar icon and menu class.""" def __init__(self, frame): self.g_settings = GeneralSettingsData() self.frame = frame super(TaskBarIcon, self).__init__() self.set_icon(TRAY_ICON) self.Bind(wx.adv.EVT_TASKBAR_LEFT_DOWN, self.on_left_down) # profile initialization self.job_lock = Lock() get_display_data() self.repeating_timer = None self.pause_item = None self.is_paused = False if sp_logging.DEBUG: sp_logging.G_LOGGER.info("START Listing profiles for menu.") self.list_of_profiles = list_profiles() if sp_logging.DEBUG: sp_logging.G_LOGGER.info("END Listing profiles for menu.") # Should now return an object if a previous profile was written or # None if no previous data was found self.active_profile = read_active_profile() self.start_prev_profile(self.active_profile) # if self.active_profile is None: # sp_logging.G_LOGGER.info("Starting up the first profile found.") # self.start_profile(wx.EVT_MENU, self.list_of_profiles[0]) # self.hk = None # self.hk2 = None if self.g_settings.use_hotkeys is True: try: # import keyboard # https://github.com/boppreh/keyboard # This import is here to have the module in the class scope from system_hotkey import SystemHotkey self.hk = SystemHotkey(check_queue_interval=0.05) self.hk2 = SystemHotkey(consumer=self.profile_consumer, check_queue_interval=0.05) self.seen_binding = set() self.register_hotkeys() except ImportError as excep: sp_logging.G_LOGGER.info( "WARNING: Could not import keyboard hotkey hook library, \ hotkeys will not work. Exception: %s", excep) if self.g_settings.show_help is True: config_frame = ConfigFrame(self) help_frame = HelpFrame() def register_hotkeys(self): """Registers system-wide hotkeys for profiles and application interaction.""" if self.g_settings.use_hotkeys is True: try: # import keyboard # https://github.com/boppreh/keyboard # This import allows access to the specific errors in this method. from system_hotkey import (SystemHotkey, SystemHotkeyError, SystemRegisterError, UnregisterError, InvalidKeyError) except ImportError as import_e: sp_logging.G_LOGGER.info( "WARNING: Could not import keyboard hotkey hook library, \ hotkeys will not work. Exception: %s", import_e) if "system_hotkey" in sys.modules: try: # Keyboard bindings: https://github.com/boppreh/keyboard # # Alternative KB bindings for X11 systems and Windows: # system_hotkey https://github.com/timeyyy/system_hotkey # seen_binding = set() # self.hk = SystemHotkey(check_queue_interval=0.05) # self.hk2 = SystemHotkey( # consumer=self.profile_consumer, # check_queue_interval=0.05) # Unregister previous hotkeys if self.seen_binding: for binding in self.seen_binding: try: self.hk.unregister(binding) if sp_logging.DEBUG: sp_logging.G_LOGGER.info( "Unreg hotkey %s", binding) except (SystemHotkeyError, UnregisterError, InvalidKeyError): try: self.hk2.unregister(binding) if sp_logging.DEBUG: sp_logging.G_LOGGER.info( "Unreg hotkey %s", binding) except (SystemHotkeyError, UnregisterError, InvalidKeyError): if sp_logging.DEBUG: sp_logging.G_LOGGER.info( "Could not unreg hotkey '%s'", binding) self.seen_binding = set() # register general bindings if self.g_settings.hk_binding_next not in self.seen_binding: try: self.hk.register(self.g_settings.hk_binding_next, callback=lambda x: self. next_wallpaper(wx.EVT_MENU), overwrite=False) self.seen_binding.add( self.g_settings.hk_binding_next) except (SystemHotkeyError, SystemRegisterError, InvalidKeyError): msg = "Error: could not register hotkey {}. \ Check that it is formatted properly and valid keys.".format( self.g_settings.hk_binding_next) sp_logging.G_LOGGER.info(msg) sp_logging.G_LOGGER.info(sys.exc_info()[0]) show_message_dialog(msg, "Error") if self.g_settings.hk_binding_pause not in self.seen_binding: try: self.hk.register(self.g_settings.hk_binding_pause, callback=lambda x: self. pause_timer(wx.EVT_MENU), overwrite=False) self.seen_binding.add( self.g_settings.hk_binding_pause) except (SystemHotkeyError, SystemRegisterError, InvalidKeyError): msg = "Error: could not register hotkey {}. \ Check that it is formatted properly and valid keys.".format( self.g_settings.hk_binding_pause) sp_logging.G_LOGGER.info(msg) sp_logging.G_LOGGER.info(sys.exc_info()[0]) show_message_dialog(msg, "Error") # try: # self.hk.register(('control', 'super', 'shift', 'q'), # callback=lambda x: self.on_exit(wx.EVT_MENU)) # except (SystemHotkeyError, SystemRegisterError, InvalidKeyError): # pass # register profile specific bindings self.list_of_profiles = list_profiles() for profile in self.list_of_profiles: if sp_logging.DEBUG: sp_logging.G_LOGGER.info( "Registering binding: \ %s for profile: %s", profile.hk_binding, profile.name) if (profile.hk_binding is not None and profile.hk_binding not in self.seen_binding): try: self.hk2.register(profile.hk_binding, profile, overwrite=False) self.seen_binding.add(profile.hk_binding) except (SystemHotkeyError, SystemRegisterError, InvalidKeyError): msg = "Error: could not register hotkey {}. \ Check that it is formatted properly and valid keys.".format(profile.hk_binding) sp_logging.G_LOGGER.info(msg) sp_logging.G_LOGGER.info(sys.exc_info()[0]) show_message_dialog(msg, "Error") elif profile.hk_binding in self.seen_binding: msg = "Could not register hotkey: '{}' for profile: '{}'.\n\ It is already registered for another action.".format(profile.hk_binding, profile.name) sp_logging.G_LOGGER.info(msg) show_message_dialog(msg, "Error") except (SystemHotkeyError, SystemRegisterError, UnregisterError, InvalidKeyError): if sp_logging.DEBUG: sp_logging.G_LOGGER.info( "Coulnd't register hotkeys, exception:") sp_logging.G_LOGGER.info(sys.exc_info()[0]) def profile_consumer(self, event, hotkey, profile): """Hotkey bindable method that starts up a profile.""" if sp_logging.DEBUG: sp_logging.G_LOGGER.info("Profile object is: %s", profile) self.start_profile(wx.EVT_MENU, profile[0][0]) def read_general_settings(self): """Refreshes general settings from file and applies hotkey bindings.""" self.g_settings = GeneralSettingsData() self.register_hotkeys() msg = "New settings are applied after an application restart. \ New hotkeys are registered." show_message_dialog(msg, "Info") def CreatePopupMenu(self): """Method called by WX library when user right clicks tray icon. Opens tray menu.""" menu = wx.Menu() create_menu_item(menu, "Open Config Folder", self.open_config) create_menu_item(menu, "Profile Configuration", self.configure_profiles) create_menu_item(menu, "Settings", self.configure_settings) create_menu_item(menu, "Reload Profiles", self.reload_profiles) menu.AppendSeparator() for item in self.list_of_profiles: create_menu_item(menu, item.name, self.start_profile, item) menu.AppendSeparator() create_menu_item(menu, "Next Wallpaper", self.next_wallpaper) self.pause_item = create_menu_item(menu, "Pause Timer", self.pause_timer, kind=wx.ITEM_CHECK) self.pause_item.Check(self.is_paused) menu.AppendSeparator() create_menu_item(menu, 'About', self.on_about) create_menu_item(menu, 'Exit', self.on_exit) return menu def set_icon(self, path): """Sets tray icon.""" icon = wx.Icon(path) self.SetIcon(icon, TRAY_TOOLTIP) def on_left_down(self, *event): """Allows binding left click event.""" sp_logging.G_LOGGER.info('Tray icon was left-clicked.') def open_config(self, event): """Opens Superpaper config folder, CONFIG_PATH.""" if platform.system() == "Windows": try: os.startfile(sp_paths.CONFIG_PATH) except BaseException: show_message_dialog( "There was an error trying to open the config folder.") elif platform.system() == "Darwin": try: subprocess.check_call(["open", sp_paths.CONFIG_PATH]) except subprocess.CalledProcessError: show_message_dialog( "There was an error trying to open the config folder.") else: try: subprocess.check_call(['xdg-open', sp_paths.CONFIG_PATH]) except subprocess.CalledProcessError: show_message_dialog( "There was an error trying to open the config folder.") def configure_profiles(self, event): """Opens profile configuration panel.""" config_frame = ConfigFrame(self) def configure_settings(self, event): """Opens general settings panel.""" setting_frame = SettingsFrame(self) def reload_profiles(self, event): """Reloads profiles from disk.""" self.list_of_profiles = list_profiles() def start_prev_profile(self, profile): """Checks if a previously running profile has been recorded and starts it.""" with self.job_lock: if profile is None: sp_logging.G_LOGGER.info("No previous profile was found.") else: self.repeating_timer = run_profile_job(profile) def start_profile(self, event, profile): """ Starts a profile job, i.e. runs a slideshow or a one time wallpaper change. If the input profile is the currently active profile, initiate a wallpaper change. """ if sp_logging.DEBUG: sp_logging.G_LOGGER.info("Start profile: %s", profile.name) if profile is None: sp_logging.G_LOGGER.info("start_profile: profile is None. \ Do you have any profiles in /profiles?") elif self.active_profile is not None: if sp_logging.DEBUG: sp_logging.G_LOGGER.info( "Check if the starting profile is already running: %s", profile.name) sp_logging.G_LOGGER.info("name check: %s, %s", profile.name, self.active_profile.name) if profile.name == self.active_profile.name: self.next_wallpaper(event) return 0 else: with self.job_lock: if (self.repeating_timer is not None and self.repeating_timer.is_running): self.repeating_timer.stop() if sp_logging.DEBUG: sp_logging.G_LOGGER.info( "Running quick profile job with profile: %s", profile.name) quick_profile_job(profile) if sp_logging.DEBUG: sp_logging.G_LOGGER.info( "Starting timed profile job with profile: %s", profile.name) self.repeating_timer = run_profile_job(profile) self.active_profile = profile write_active_profile(profile.name) if sp_logging.DEBUG: sp_logging.G_LOGGER.info("Wrote active profile: %s", profile.name) return 0 else: with self.job_lock: if (self.repeating_timer is not None and self.repeating_timer.is_running): self.repeating_timer.stop() if sp_logging.DEBUG: sp_logging.G_LOGGER.info( "Running quick profile job with profile: %s", profile.name) quick_profile_job(profile) if sp_logging.DEBUG: sp_logging.G_LOGGER.info( "Starting timed profile job with profile: %s", profile.name) self.repeating_timer = run_profile_job(profile) self.active_profile = profile write_active_profile(profile.name) if sp_logging.DEBUG: sp_logging.G_LOGGER.info("Wrote active profile: %s", profile.name) return 0 def next_wallpaper(self, event): """Calls the next wallpaper changer method of the running profile.""" with self.job_lock: if (self.repeating_timer is not None and self.repeating_timer.is_running): self.repeating_timer.stop() change_wallpaper_job(self.active_profile) self.repeating_timer.start() else: change_wallpaper_job(self.active_profile) def rt_stop(self): """Stops running slideshow timer if one is active.""" if (self.repeating_timer is not None and self.repeating_timer.is_running): self.repeating_timer.stop() def pause_timer(self, event): """Check if a slideshow timer is running and if it is, then try to stop/start.""" if (self.repeating_timer is not None and self.repeating_timer.is_running): self.repeating_timer.stop() self.is_paused = True if sp_logging.DEBUG: sp_logging.G_LOGGER.info("Paused timer") elif (self.repeating_timer is not None and not self.repeating_timer.is_running): self.repeating_timer.start() self.is_paused = False if sp_logging.DEBUG: sp_logging.G_LOGGER.info("Resumed timer") else: sp_logging.G_LOGGER.info("Current profile isn't using a timer.") def on_about(self, event): """Opens About dialog.""" # Credit for AboutDiaglog example to Jan Bodnar of # http://zetcode.com/wxpython/dialogs/ description = ( "Superpaper is an advanced multi monitor wallpaper\n" + "manager for Unix and Windows operating systems.\n" + "Features include setting a single or multiple image\n" + "wallpaper, pixel per inch and bezel corrections,\n" + "manual pixel offsets for tuning, slideshow with\n" + "configurable file order, multiple path support and more.") licence = ("Superpaper is free software; you can redistribute\n" + "it and/or modify it under the terms of the MIT" + " License.\n\n" + "Superpaper is distributed in the hope that it will" + " be useful,\n" + "but WITHOUT ANY WARRANTY; without even the implied" + " warranty of\n" + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" + "See the MIT License for more details.") artists = "Icons kindly provided by Icons8 https://icons8.com" info = wx.adv.AboutDialogInfo() info.SetIcon(wx.Icon(TRAY_ICON, wx.BITMAP_TYPE_PNG)) info.SetName('Superpaper') info.SetVersion(__version__) info.SetDescription(description) info.SetCopyright('(C) 2019 Henri Hänninen') info.SetWebSite('https://github.com/hhannine/Superpaper/') info.SetLicence(licence) info.AddDeveloper('Henri Hänninen') info.AddArtist(artists) # info.AddDocWriter('Doc Writer') # info.AddTranslator('Tran Slator') wx.adv.AboutBox(info) def on_exit(self, event): """Exits Superpaper.""" self.rt_stop() wx.CallAfter(self.Destroy) self.frame.Close()
import configparser from system_hotkey import SystemHotkey hk = SystemHotkey() hk.register(('control', 'alt', 'r'), callback=lambda x: OnHotkey()) import spotipy import spotipy.util as util import requests import time import sys import os def resource_path(relative_path): """ Get absolute path to resource, works for dev and for PyInstaller """ try: # PyInstaller creates a temp folder and stores path in _MEIPASS base_path = sys._MEIPASS except Exception: base_path = os.path.abspath(".") return os.path.join(base_path, relative_path) parser = configparser.ConfigParser() parser.read('config.ini') parser.read(resource_path('api.ini')) os.environ["SPOTIPY_CLIENT_ID"] = parser["api"]["SPOTIPY_CLIENT_ID"] os.environ["SPOTIPY_REDIRECT_URI"] = parser["api"]["SPOTIPY_REDIRECT_URI"] os.environ["SPOTIPY_CLIENT_SECRET"] = parser["api"]["SPOTIPY_CLIENT_SECRET"]
#!/usr/bin/env python # coding: utf-8 from system_hotkey import SystemHotkey import pyperclip as pyclip import time # 剪贴板字符串处理 def StringProcess(self): # 读取字符串(剪贴板) read_text = pyclip.paste() # 字符串处理 output_text = read_text.replace("\r\n", " ") output_text = output_text.replace("\n", " ") output_text = output_text.replace("\r", " ") # 输出字符串(剪贴板) pyclip.copy(output_text) hk = SystemHotkey() hk.register(('control', 'shift', 'm'), callback=StringProcess) while (1): time.sleep(1000)
class Game: position = Position.UNKNOWN path = None regex_loading = re.compile( r"LoadingScreen.OnSceneUnloaded\(\) - prevMode=.* nextMode=(.*) ") def __init__(self, log_path): self.thread = None self.path = log_path self.collector = BaseCollector(self) self.lock = Lock() self.p = None self.running = True self.hk = SystemHotkey() self.hk.register(('control', 'alt', 'z'), callback=self.delete_last_img) self.images = [] def delete_last_img(self, evnt): if self.images: os.remove(self.images[-1]) os.remove(self.images[-1].replace(".png", ".xml")) if self.p: self.p.terminate() self.p.wait() self.images.pop(-1) if self.images and self.images[-1]: self.p = subprocess.Popen( ["python3", "labelImg/labelImg.py", self.images[-1]]) def get_position(self, lines): """ set self.position and returns true if the position is new""" for line in reversed(lines): match = self.regex_loading.search(line) if (match and self.position != Position[match.group(1)]): self.position = Position[match.group(1)] return True ## new position true return False ## not a new position def set_collector(self): if (self.position is Position.ARENA): self.collector = ArenaCollector(self) elif (self.position is Position.GAMEPLAY): self.collector = BattlefieldCollector(self) elif (self.position is Position.COLLECTIONMANAGER): self.collector = CollectionCollertor(self) else: self.collector = BaseCollector(self) def show_img(self, path): self.images.append(path) if (len(self.images) >= 5): self.images.remove(self.images[0]) if (self.p): self.p.terminate() self.p.wait() self.p = subprocess.Popen(["python3", "labelImg/labelImg.py", path]) def run(self): ## get current position with open(path.join(self.path, "LoadingScreen.log")) as f: if self.get_position(f.readlines()): self.set_collector() start_new_thread(self.run_collector, ()) # watch file for line in tailer.follow( open(path.join(self.path, "LoadingScreen.log"))): if self.get_position([line]): self.lock.acquire() self.set_collector() self.lock.release() def terminate(self, signal, frame): self.lock.acquire() self.running = False self.p.terminate() self.p.wait() self.lock.release() if self.p: self.p.terminate() self.p.wait() exit() def run_collector(self): while (self.running): self.lock.acquire() self.collector.run() self.lock.release()
import configparser from system_hotkey import SystemHotkey hk = SystemHotkey() hk.register(('control', 'alt', 'r'), callback=lambda x:OnHotkey()) import spotipy import spotipy.util as util import requests import time import sys import os def resource_path(relative_path): """ Get absolute path to resource, works for dev and for PyInstaller """ try: # PyInstaller creates a temp folder and stores path in _MEIPASS base_path = sys._MEIPASS except Exception: base_path = os.path.abspath(".") return os.path.join(base_path, relative_path) parser = configparser.ConfigParser() parser.read('config.ini') parser.read(resource_path('api.ini')) os.environ["SPOTIPY_CLIENT_ID"] = parser["api"]["SPOTIPY_CLIENT_ID"] os.environ["SPOTIPY_REDIRECT_URI"] = parser["api"]["SPOTIPY_REDIRECT_URI"] os.environ["SPOTIPY_CLIENT_SECRET"] = parser["api"]["SPOTIPY_CLIENT_SECRET"]
class MyMainWindow(QMainWindow, Ui_MainWindow, QObject): # 定义一个热键信号 sig_keyhot = pyqtSignal(str) def __init__(self, parent=None): super(MyMainWindow, self).__init__(parent) #去掉边框|任务栏|窗口置顶 self.setWindowFlags(Qt.FramelessWindowHint | Qt.Tool | Qt.WindowStaysOnTopHint) self.setupUi(self) self.screenWidget = QtWidgets.QWidget() self.screenWidget.setObjectName("screenWidget") self.screenWidget.setWindowFlags(Qt.FramelessWindowHint) self.centralWidget = self.findChild(QtWidgets.QWidget, 'centralwidget') self.centralWidget.setWindowFlags(Qt.FramelessWindowHint) self.toolWidget = self.findChild(QtWidgets.QWidget, 'toolWidget') self.toolWidget.setWindowFlags(Qt.FramelessWindowHint) #设置按钮的槽函数 self.btn_i2u.clicked.connect(lambda: self.i2u()) btn_bdfy = self.findChild(QtWidgets.QToolButton, 'baidu') btn_i2t = self.findChild(QtWidgets.QToolButton, 'img2txt') btn_copy = self.findChild(QtWidgets.QToolButton, 'copy') #背景透明 self.setAttribute(QtCore.Qt.WA_TranslucentBackground) # 2. 设置我们的自定义热键响应函数 self.sig_keyhot.connect(self.MKey_pressEvent) # 3. 初始化两个热键 self.hk_start, self.hk_stop = SystemHotkey(), SystemHotkey() # 4. 绑定快捷键和对应的信号发送函数 self.hk_start.register(('control', '1'), callback=lambda x: self.send_key_event("0")) self.hk_stop.register(('control', '2'), callback=lambda x: self.send_key_event("1")) esc = QAction('', triggered=self.esc) esc.setShortcut('esc') self.addAction(esc) self.screenWidget.addAction(esc) # 系统托盘 self.systemtray = SystemTray(self) def i2u(self): print('start i2u') res_im, res_txt = trans_img.generate_trans_img(img=self.cap_im.copy(), method='local') print(res_txt) cv2.imshow('', res_im) cv2.waitKey(0) @pyqtSlot() def esc(self): self.screenWidget.hide() self.hide() import sip try: self.screenLabel.deleteLater() sip.delete(self.screenLabel) except Exception as e: print('error') pass try: self.imgLabel.deleteLater() sip.delete(self.imgLabel) except Exception as e: print('delete imgLabel error') #装饰器接受的数据类型必须和信号量的数据类型保持一致 @pyqtSlot(int, int, int, int) def capture(self, x0, y0, w, h): y1 = y0 + h x1 = x0 + w print(x0, y0, x1, y1) #必须用copy,否则在使用im.data的时候会报错 self.cap_im = self.im[y0:y1, x0:x1].copy() height, width, depth = self.cap_im.shape self.esc() self.imgLabel = QLabel(self.centralWidget) self.imgLabel.resize(width, height) qimg = QImage(self.cap_im.data, width, height, width * depth, QImage.Format_RGB888) pixmap = QtGui.QPixmap(qimg).scaled(self.imgLabel.width(), self.imgLabel.height()) self.imgLabel.setPixmap(pixmap) self.imgLabel.move(0, 0) self.toolWidget.move(0, height - 30) self.centralWidget.raise_() self.toolWidget.raise_() self.resize(width, height) self.move(x0, y0) self.show() # 热键处理函数 def MKey_pressEvent(self, i_str): if i_str == '0': im = capture.capture() height, width, depth = im.shape self.im = im self.screenLabel = MyLabel(self.screenWidget) self.screenLabel.resize(width, height) self.screenLabel.msg.connect(self.capture) print(self.screenLabel.width(), self.screenLabel.height()) qimg = QImage(im.data, width, height, width * depth, QImage.Format_RGB888) pixmap = QtGui.QPixmap(qimg).scaled(self.screenLabel.width(), self.screenLabel.height()) self.screenLabel.setPixmap(pixmap) self.screenWidget.move(0, 0) self.screenWidget.showFullScreen() # 热键信号发送函数(将外部信号,转化成qt信号) def send_key_event(self, i_str): self.sig_keyhot.emit(i_str) print(i_str) #设置无边框移动 def mousePressEvent(self, event): if event.button() == Qt.LeftButton: self.m_flag = True self.m_Position = event.globalPos() - self.pos() # 获取鼠标相对窗口的位置 event.accept() self.setCursor(QCursor(Qt.OpenHandCursor)) # 更改鼠标图标 def mouseMoveEvent(self, QMouseEvent): if Qt.LeftButton and self.m_flag: self.move(QMouseEvent.globalPos() - self.m_Position) # 更改窗口位置 QMouseEvent.accept() def mouseReleaseEvent(self, QMouseEvent): self.m_flag = False self.setCursor(QCursor(Qt.ArrowCursor))
palette3.setColor(PyQt5.QtGui.QPalette.WindowText, PyQt5.QtGui.QColor(0, 255, 0)) label1 = PyQt5.QtWidgets.QLabel(win) label1.setText("hello") label1.setFont(PyQt5.QtGui.QFont("Roman times", 13)) label1.setGeometry(0,0,200,18) label1.setPalette(palette1); label2 = PyQt5.QtWidgets.QLabel(win) label2.setText("hello") label2.setFont(PyQt5.QtGui.QFont("Roman times", 13)) label2.setGeometry(0,18,200,18) label2.setPalette(palette2); label3 = PyQt5.QtWidgets.QLabel(win) label3.setText("world") label3.setFont(PyQt5.QtGui.QFont("Roman times", 13)) label3.setGeometry(0,36,200,18) label3.setPalette(palette3); hk_stop = SystemHotkey() hk_stop.register(('control', '1'), callback=lambda x: CalDis()) win.show() def Refresh(): win.update() threading.Timer(YGlobal.inter, Refresh).start() threading.Timer(YGlobal.inter, Refresh).start() sys.exit(app.exec_())
class CMainApplication(Ui_MainWindow, QtWidgets.QMainWindow): def __init__(self): super(CMainApplication, self).__init__() self.setupUi(self) # Tray Menu self.tray = TrayIcon(self) self.tray.show() self.tray.switchTrigger.connect(self.__bSwitchTransactionOn) self.tray.quitTrigger.connect(self.__bQuit) # IS transaction on self.__switch = True # Hotkey listener self.__initHotkeys() # Attribute relates on transaction self.__descriptionSwitch = False self.__word = '' self.__transaction = '' # Transaction widget self.__transactionWidget = CTransaction() self.__transactionWidget.cancelSignal.connect(self.__bCancelTransaction) # Database widget showed? self.databaseShowed = True # Init the database self.__initDatabase() self.initUI() def __initHotkeys(self): # self.__globalHotKCListener = CGlobalHotKCListener() # self.__globalHotKCListener.start() # self.__globalHotKCListener.addTrigger.connect(self.__bStartDescription) # self.__globalHotKCListener.cancelTrigger.connect(self.__bCancelDescription) self.__GlobalHotkeyListener = SystemHotkey() self.__GlobalHotkeyListener.register(('control', 'd'), callback=self.__bStartDescription) self.__GlobalHotkeyListener.register(('control', 's'), callback=self.__bCancelDescription) def closeEvent(self, vEvent): vEvent.ignore() self.hide() def hideEvent(self, vEvent): self.tray.showMessage("title", "hide in tray icon") self.hide() vEvent.ignore() def initUI(self): # self.setGeometry(300, 300, 300, 220) self.setWindowTitle('Dict') # AX self.__transactionWidget.transactionAx.setControl(u"{8856F961-340A-11D0-A96B-00C04FD705A2}") # self.transactionAx.setFocusPolicy(Qt::StrongFocus);//设置控件接收键盘焦点的方式:鼠标单击、Tab键 self.__transactionWidget.transactionAx.setProperty("DisplayAlerts", False) # 不显示任何警告信息。 self.__transactionWidget.transactionAx.setProperty("DisplayScrollBars", True) # 显示滚动条 # self.setMouseTracking(True) self.addClipbordListener() self.show() # self.__transactionWidget.show() # self.hide() def addClipbordListener(self): self.clipboard = QApplication.clipboard() self.clipboard.dataChanged.connect(self.onClipboradChanged) def onClipboradChanged(self): # Add description of the word if self.__descriptionSwitch: try: self.__globalHotKCListener.quit() hld = win32gui.FindWindow("Qt5QWindowIcon", "Form") shell = win32com.client.Dispatch("WScript.Shell") shell.SendKeys('%') win32gui.SetForegroundWindow(hld) except Exception as MyException: print(MyException) reply = QMessageBox.information(self, "Tips", "Sure you want to add this words?", QMessageBox.Yes | QMessageBox.No) if reply == QMessageBox.No: return win32api.keybd_event(18, 0, 0, 0) # Alt win32api.keybd_event(27, 0, 0, 0) # F win32api.keybd_event(27, 0, win32con.KEYEVENTF_KEYUP, 0) # 释放按键 win32api.keybd_event(18, 0, win32con.KEYEVENTF_KEYUP, 0) clipboard = QApplication.clipboard() description = clipboard.text() # Save the word and description self.__saveData(self.__word, self.__transaction, description) # Tip to window self.tray.showMessage("Tips", "Insert Successful", self.tray.icon) self.incrementLine.setText(str(int(self.incrementLine.text()) + 1)) self.todayLine.setText(str(int(self.todayLine.text()) + 1)) self.totalLine.setText(str(int(self.totalLine.text()) + 1)) self.__bCancelDescription(None) self.__initDatabase() else: try: # Get the text in clipboard clipboard = QApplication.clipboard() text = clipboard.text() if len(text) < 2: return # text = re.search(r' ?[a-zA-Z ]+ ?', text).group() text = text.strip() text = str.lower(text) # Find the transaction Transaction = self.__transact(text) self.__transaction = Transaction self.__word = text File = codecs.open('resources/index.html', 'w', 'utf-8') if Transaction[0] != '<': File.write(HTMLSTATIC1 + Transaction + HTMLSTATIC2) else: File.write(Transaction) File.close() # Show the transaction window # self.__transactionWidget.transactionBrowser.setText(self.__transaction) self.__transactionWidget.transactionAx.dynamicCall("Navigate(str)", BASEDIR + "/resources/index.html") self.__transactionWidget.statusLabel.setText("Search Mode") CursurPoint = QCursor.pos() desktopWidget = QApplication.desktop(); DesktopPoint = desktopWidget.availableGeometry() if CursurPoint.x() + 620 > DesktopPoint.width(): CursurPoint.setX(DesktopPoint.width() - 620) if CursurPoint.y() + 400 > DesktopPoint.height(): CursurPoint.setY(DesktopPoint.height() - 400) self.__transactionWidget.move(CursurPoint) # self.__transactionWidget.setWindowFlags(self.__transactionWidget.windowFlags() |QtCore.Qt.WindowStaysOnTopHint) # self.__transactionWidget.show() # self.__transactionWidget.setWindowFlags(QtCore.Qt.Widget) self.__transactionWidget.activateWindow() self.__transactionWidget.show() except Exception as e: print(e) def incrementButtonPushed(self): cn = sqlite3.connect(WORDRECORD) cu = cn.cursor() cu.execute("SELECT word,wordTransaction,description " "FROM record WHERE alreadyOut='false'") with open(EXPORTPATH + "increment.txt", "w+", encoding='utf-8') as f: for res in cu.fetchall(): f.write(res[0]) f.write(",") f.write(res[1]) f.write('\n') f.write(res[2]) f.write('@\n') f.close() cu.execute("UPDATE record SET alreadyOut='true' WHERE alreadyOut='false'") cn.commit() cn.close() self.statusbar.showMessage("Successful!") def todayButtonPushed(self): NowTime = time.time() Midnight = NowTime - NowTime % 86400 cn = sqlite3.connect(WORDRECORD) cu = cn.cursor() cu.execute("SELECT word,wordTransaction,description " "FROM record WHERE insertTime>?", (Midnight,)) with open(EXPORTPATH + "today.txt", "w+", encoding='utf-8') as f: for res in cu.fetchall(): f.write(res[0]) f.write(",") f.write(res[1]) f.write('\n') f.write(res[2]) f.write('@\n') f.close() cu.execute("UPDATE record SET alreadyOut='true' WHERE insertTime>?", (Midnight,)) cn.commit() cn.close() self.statusbar.showMessage("Successful!") def totalButtonPushed(self): cn = sqlite3.connect(WORDRECORD) cu = cn.cursor() cu.execute("SELECT word,wordTransaction,description " "FROM record") with open(EXPORTPATH + "total.txt", "w+", encoding='utf-8') as f: for res in cu.fetchall(): f.write(res[0]) f.write(",") f.write(res[1]) f.write('\n') f.write(res[2]) f.write('@\n') f.close() cu.execute("UPDATE record SET alreadyOut='true'") cn.commit() cn.close() self.statusbar.showMessage("Successful!") def displayButtonPushed(self): if self.databaseShowed: self.databaseWidget.hide() self.databaseShowed = not self.databaseShowed self.displayButton.setText(">>") self.resize(500, 650) else: self.databaseWidget.show() self.databaseShowed = not self.databaseShowed self.displayButton.setText("<<") self.resize(1200, 650) def removeButtonPushed(self): if self.databaseWidget.currentRow() == -1: pass RemoveLists = [] for SelectedRange in self.databaseWidget.selectedRanges(): for SelectIndex in range(SelectedRange.rowCount()): Word = self.databaseWidget.item(SelectedRange.topRow() + SelectIndex, 2).text() try: requests.post(HOST + "/remove", data={'word': Word}) except: self.statusbar.showMessage("No network!") # Remove cn = sqlite3.connect(WORDRECORD) cu = cn.cursor() cu.execute('delete from record where word=?', (Word,)) cn.commit() cn.close() RemoveLists.append(SelectedRange.topRow() + SelectIndex) RemoveLists.sort(reverse=True) for RowIndex in RemoveLists: self.databaseWidget.removeRow(RowIndex) self.__initCounts() def addWordsButtonPushed(self): FileName = QFileDialog.getOpenFileName(self, "select your words file", "", "Txt files(*.txt)") Results = self.__parseImportWords(FileName[0]) # Add words to database cn = sqlite3.connect(WORDRECORD) cu = cn.cursor() for Result in Results: Word = Result.get('word') Transaction = Result.get('transaction') Description = "" # Find if it is exist cu.execute('select proficiency from record where word=?', (Word,)) res = cu.fetchone() if res is None: cu.execute("INSERT INTO record (word, wordTransaction, description, insertTime) " "VALUES (?,?,?,?)", (Word, Transaction, Description, time.time())) else: ProficiencyIncreament = 100 if res[0] + 25 > 100 else 100 cu.execute("update record set proficiency=? where word = ?", (ProficiencyIncreament, Word)) cn.commit() cn.close() self.__initDatabase() def synchronizeButtonPushed(self): self.__initDatabase() def __parseImportWords(self, vFileName): File = open(vFileName, 'r', encoding='UTF-16 LE', errors='ignore') lines = File.readlines() tempList = [] temp = "" flag = 0 final = [] word = "" transaction = "" for line in lines: line.encode("utf8") if flag == 0: pattern0 = re.compile(r'\ufeff(.*\n)') match0 = pattern0.match(line) temp += match0.group(1) else: pattern = re.compile(r'\d,') match = pattern.match(line) if match: tempList.append(temp) temp = "" temp += line else: temp += line flag += 1 tempList.append(temp) for temp in tempList: transaction = "" pattern = re.compile(r'\d, (.*?) (.*)\n') match = pattern.match(temp) word = match.group(1) transction0 = match.group(2) transaction += transction0 + "\n" end = match.end() translationLine = temp[end:] translations = translationLine.split("\n\n") length = len(translations) for i in range(length): tmp = translations[i].partition(".") transaction += str(i + 1) + ". [" + tmp[0] + "]" + tmp[2] + "\n" element = {"word": word, "transaction": transaction} final.append(element) return final def __transact(self, vWord): try: # Dict Parser builder = IndexBuilder('MDXData/Oxford.mdx') ResultWord = builder.mdx_lookup(vWord) # Internet Based Transaction if len(ResultWord) == 0: TransactionRequest = requests.post(HOST + "/transaction" , data={'word': vWord}) return json.loads(TransactionRequest.text) # Using local dictionary else: parser = MyHTMLParser(ResultWord[0]) return parser.getData() except Exception as e: print(e) def __synchronize(self): try: response = requests.get(HOST + "/sychronize", timeout=10, data={"LocalTime": os.stat(WORDRECORD).st_mtime}) if response.status_code == 200: with open(WORDRECORD, 'wb') as TargetFile: TargetFile.write(response.content) self.statusbar.showMessage("Download Successful") elif response.status_code == 302: with open(WORDRECORD, "rb") as File: data = File.read() if requests.post(HOST + "/sychronize", data=data).status_code == 200: self.statusbar.showMessage("Upload successful") else: self.statusbar.showMessage("Upload Error") else: QMessageBox.information(self, "Warning", "Can't synchronize with remote database, using local mode", QMessageBox.Yes) except: QMessageBox.information(self, "Warning", "Can't synchronize with remote database, using local mode", QMessageBox.Yes) self.__initCounts() def __initCounts(self): NowTime = time.time() Midnight = NowTime - NowTime % 86400 cn = sqlite3.connect(WORDRECORD) cu = cn.cursor() cu.execute('SELECT * FROM record') res = cu.fetchall() TotalCount = len(res) cu.execute('SELECT * FROM record WHERE insertTime>?', (Midnight,)) res = cu.fetchall() TodayCount = len(res) cu.execute("SELECT * FROM record WHERE alreadyOut='false' ") res = cu.fetchall() IncrementCount = len(res) cn.close() self.incrementLine.setText(str(IncrementCount)) self.todayLine.setText(str(TodayCount)) self.totalLine.setText(str(TotalCount)) def __initDatabase(self): self.databaseWidget.clear() self.databaseWidget.setEditTriggers(QAbstractItemView.NoEditTriggers) self.databaseWidget.setSelectionBehavior(QAbstractItemView.SelectRows) # Synchronize self.__synchronize() cn = sqlite3.connect(WORDRECORD) cu = cn.cursor() # Get the record cu.execute("select insertTime,proficiency,word,description,wordTransaction from record") reses = cu.fetchall() self.databaseWidget.setRowCount(len(reses)) self.databaseWidget.setColumnCount(5) self.databaseWidget.setHorizontalHeaderItem(0, QTableWidgetItem("Date")) self.databaseWidget.setHorizontalHeaderItem(1, QTableWidgetItem("P")) self.databaseWidget.setHorizontalHeaderItem(2, QTableWidgetItem("Word")) self.databaseWidget.setHorizontalHeaderItem(3, QTableWidgetItem("D")) self.databaseWidget.setHorizontalHeaderItem(4, QTableWidgetItem("Transaction")) Header = self.databaseWidget.horizontalHeader() Header.setSectionResizeMode(0, QtWidgets.QHeaderView.ResizeToContents) Header.setSectionResizeMode(1, QtWidgets.QHeaderView.ResizeToContents) Header.setSectionResizeMode(2, QtWidgets.QHeaderView.ResizeToContents) Header.setSectionResizeMode(4, QtWidgets.QHeaderView.ResizeToContents) index = 0 for res in reses: self.databaseWidget.setItem(index, 0, QTableWidgetItem( time.strftime("%m-%d", time.localtime(res[0])))) # Date self.databaseWidget.setItem(index, 1, QTableWidgetItem(str(res[1]))) # Proficiency self.databaseWidget.setItem(index, 2, QTableWidgetItem(res[2])) # Word self.databaseWidget.setItem(index, 3, QTableWidgetItem(res[3])) # wordTransaction self.databaseWidget.setItem(index, 4, QTableWidgetItem(res[4])) # description index += 1 cn.close() # Display details signals for x in range(self.databaseWidget.rowCount()): self.databaseWidget.item(x, 3).setToolTip(self.databaseWidget.item(x, 3).text()) self.databaseWidget.item(x, 4).setToolTip(self.databaseWidget.item(x, 4).text()) def __saveData(self, vWord, vTransaction, vDescription): try: cn = sqlite3.connect(WORDRECORD) cu = cn.cursor() # Find if it is exist cu.execute('select proficiency from record where word=?', (vWord,)) res = cu.fetchone() if res is None: cu.execute("INSERT INTO record (word, wordTransaction, description, insertTime) " "VALUES (?,?,?,?)", (vWord, vTransaction, vDescription, time.time())) else: ProficiencyIncreament = 100 if res[0] + 5 > 100 else 100 cu.execute("update record set proficiency=? where word = ?", (ProficiencyIncreament, vWord)) cn.commit() cn.close() return True except Exception as e: return False def __bCancelTransaction(self): self.__transactionWidget.close() def __bSwitchTransactionOn(self): if self.__switch: self.__descriptionSwitch = False # self.__globalHotKCListener.addTrigger.disconnect() # self.__globalHotKCListener.cancelTrigger.disconnect() # self.__globalHotKCListener.cancelHotKey() # self.__globalHotKCListener.quit() self.__GlobalHotkeyListener.unregister(('control', 'd')) self.__GlobalHotkeyListener.unregister(('control', 's')) self.__switch = not self.__switch self.clipboard.dataChanged.disconnect() else: self.__descriptionSwitch = False # self.__globalHotKCListener.start() # self.__globalHotKCListener.addTrigger.connect(self.__bStartDescription) # self.__globalHotKCListener.cancelTrigger.connect(self.__bCancelDescription) self.__GlobalHotkeyListener.register(('control', 'd'), callback=self.__bStartDescription) self.__GlobalHotkeyListener.register(('control', 's'), callback=self.__bCancelDescription) self.__switch = not self.__switch self.clipboard.dataChanged.connect(self.onClipboradChanged) def __bStartDescription(self, event): self.__descriptionSwitch = True self.__transactionWidget.statusLabel.setText("Insert Mode") return event def __bCancelDescription(self, event): self.__descriptionSwitch = False self.__transactionWidget.statusLabel.setText("Search Mode") return False def __bQuit(self): self.__transactionWidget.close() self.__initDatabase() # self.p.terminate() self.tray.setVisible(False) # self.tray.close() self.close() # qApp.__bQuit() sys.exit()
def register_hotkeys(): sys.excepthook = uncaught_exception_handler hk = SystemHotkey() hk.register(('control', 'alt', 'm'), callback=handle_m) hk.register(('control', 'alt', 'j'), callback=handle_j) hk.register(('control', 'alt', 'q'), callback=handle_q)
class MainWindow(QWidget): """ 主窗口 """ BORDER_WIDTH = 5 showSubPlayWindowSig = pyqtSignal() def __init__(self, parent=None): super().__init__(parent) # 实例化窗口特效 self.windowEffect = WindowEffect() # 实例化小部件 self.createWidgets() # 初始化标志位 self.isInSelectionMode = False # 初始化界面 self.__initWidget() def createWidgets(self): """ 创建小部件 """ self.totalStackWidget = OpacityAniStackedWidget(self) self.subMainWindow = QWidget(self) self.titleBar = TitleBar(self) # 实例化播放器和播放列表 self.player = QMediaPlayer(self) self.playlist = MediaPlaylist(self) # 实例化小部件 self.subStackWidget = PopUpAniStackedWidget(self.subMainWindow) self.settingInterface = SettingInterface(self.subMainWindow) # 从配置文件中的选择文件夹读取音频文件 t3 = time() self.myMusicInterface = MyMusicInterface( self.settingInterface.config.get('selected-folders', []), self.subMainWindow) t4 = time() print('创建整个我的音乐界面耗时:'.ljust(15), t4 - t3) # 将最后一首歌作为playBar初始化时用的songInfo self.lastSongInfo = self.settingInterface.config.get('last-song', {}) # 创建缩略图任务栏 self.thumbnailToolBar = ThumbnailToolBar(self) self.thumbnailToolBar.setWindow(self.windowHandle()) # 创建左上角播放窗口 self.subPlayWindow = SubPlayWindow(self, self.lastSongInfo) # 创建正在播放界面 self.playingInterface = PlayingInterface(self.playlist.playlist, self) # 创建专辑界面 self.albumInterface = AlbumInterface({}, self.subMainWindow) # 创建播放列表卡界面 self.readCustomPlaylists() # 读入所有播放列表 self.playlistCardInterface = PlaylistCardInterface( self.customPlaylists, self) # 创建导航界面 self.navigationInterface = NavigationInterface(self.subMainWindow) # 创建播放栏 self.playBar = PlayBar(self.lastSongInfo, self) # 创建快捷键 self.togglePlayPauseAct_1 = QAction(parent=self, shortcut=Qt.Key_Space, triggered=self.switchPlayState) self.showNormalAct = QAction(parent=self, shortcut=Qt.Key_Escape, triggered=self.exitFullScreen) self.lastSongAct = QAction(parent=self, shortcut=Qt.Key_MediaPrevious, triggered=self.playlist.previous) self.nextSongAct = QAction(parent=self, shortcut=Qt.Key_MediaNext, triggered=self.playlist.next) self.togglePlayPauseAct_2 = QAction(parent=self, shortcut=Qt.Key_MediaPlay, triggered=self.switchPlayState) self.addActions([ self.togglePlayPauseAct_1, self.showNormalAct, self.nextSongAct, self.lastSongAct, self.togglePlayPauseAct_2 ]) # 创建stackWidget字典 self.stackWidget_dict = { 'subStackWidget': self.subStackWidget, 'myMusicInterfaceStackWidget': self.myMusicInterface.stackedWidget } # 当前选中的专辑卡 self.currentAlbumCard = None def __initWidget(self): """ 初始化小部件 """ self.resize(1300, 1000) self.setMinimumSize(1030, 800) self.setWindowTitle('MyGroove音乐') self.setWindowFlags(Qt.FramelessWindowHint) self.setWindowIcon(QIcon('resource\\images\\透明icon.png')) self.setAttribute(Qt.WA_TranslucentBackground | Qt.WA_StyledBackground) # 在去除任务栏的显示区域居中显示 desktop = QApplication.desktop().availableGeometry() self.move(int(desktop.width() / 2 - self.width() / 2), int(desktop.height() / 2 - self.height() / 2)) # 标题栏置顶 self.titleBar.raise_() # 设置窗口特效 self.setWindowEffect() # todo:将窗口添加到StackWidget中 self.subStackWidget.addWidget(self.myMusicInterface, 0, 70, False) self.subStackWidget.addWidget(self.playlistCardInterface, 0, 160, False) self.subStackWidget.addWidget(self.settingInterface, 0, 160, False) self.subStackWidget.addWidget(self.albumInterface, 0, 70) self.totalStackWidget.addWidget(self.subMainWindow) self.totalStackWidget.addWidget(self.playingInterface) # 初始化标题栏的下标列表 self.titleBar.stackWidgetIndex_list.append( ('myMusicInterfaceStackWidget', 0)) # 设置右边子窗口的位置 self.adjustWidgetGeometry() # 引用小部件 self.referenceWidgets() # 设置层叠样式 self.setObjectName('mainWindow') self.subMainWindow.setObjectName('subMainWindow') self.subStackWidget.setObjectName('subStackWidget') self.playingInterface.setObjectName('playingInterface') self.setQss() # 初始化播放列表 self.initPlaylist() # todo:设置全局热键 # self.setHotKey() # 将信号连接到槽函数 self.connectSignalToSlot() # 初始化播放栏 self.initPlayBar() # 安装事件过滤器 self.navigationInterface.navigationMenu.installEventFilter(self) def setHotKey(self): """ 设置全局热键 """ self.nextSongHotKey = SystemHotkey() self.lastSongHotKey = SystemHotkey() self.playHotKey = SystemHotkey() # callback会返回一个event参数,所以需要用lambda self.nextSongHotKey.register( ('f6', ), callback=lambda x: self.hotKeySlot(self.playlist.next)) self.lastSongHotKey.register( ('f4', ), callback=lambda x: self.hotKeySlot(self.playlist.previous)) self.playHotKey.register( ('f5', ), callback=lambda x: self.hotKeySlot(self.switchPlayState)) def setWindowEffect(self): """ 设置窗口特效 """ self.hWnd = HWND(int(self.winId())) # 开启窗口动画 self.windowEffect.setWindowAnimation(int(self.winId())) # 开启亚克力效果和阴影效果 self.windowEffect.setAcrylicEffect(self.hWnd, 'F2F2F299', True) def adjustWidgetGeometry(self): """ 调整小部件的geometry """ self.subMainWindow.resize(self.size()) self.totalStackWidget.resize(self.size()) self.titleBar.resize(self.width(), 40) if hasattr(self, 'navigationInterface'): self.navigationInterface.setOverlay(self.width() < 1280) self.subStackWidget.move(self.navigationInterface.width(), 0) self.subStackWidget.resize( self.width() - self.navigationInterface.width(), self.height()) self.navigationInterface.resize(self.navigationInterface.width(), self.height()) if hasattr(self, 'albumInterface'): if not self.playingInterface.smallestModeInterface.isVisible(): self.albumInterface.resize(self.myMusicInterface.size()) if hasattr(self, 'playBar'): if not self.playingInterface.smallestModeInterface.isVisible(): self.playBar.resize(self.width(), self.playBar.height()) def eventFilter(self, obj, e: QEvent): """ 过滤事件 """ if obj == self.navigationInterface.navigationMenu: # 显示导航菜单是更改标题栏返回按钮和标题的父级为导航菜单 isVisible = self.titleBar.returnBt.isVisible() if e.type() == QEvent.Show: self.titleBar.returnBt.setParent(obj) # 显示标题 self.titleBar.title.setParent(obj) self.titleBar.title.move(15, 10) self.titleBar.title.show() # 如果播放栏课件就缩短导航菜单 isScaled = self.playBar.isVisible() height = self.height() - isScaled * self.playBar.height() self.navigationInterface.navigationMenu.setBottomSpacingVisible( not isScaled) self.navigationInterface.navigationMenu.resize( self.navigationInterface.navigationMenu.width(), height) elif e.type() == QEvent.Hide: # 隐藏标题 self.titleBar.title.hide() self.titleBar.title.setParent(self.titleBar) self.titleBar.returnBt.setParent(self.titleBar) # 根据情况显示/隐藏返回按钮和标题 self.titleBar.returnBt.setVisible(isVisible) return super().eventFilter(obj, e) def resizeEvent(self, e): """ 调整尺寸时同时调整子窗口的尺寸 """ super().resizeEvent(e) self.adjustWidgetGeometry() # 更新标题栏图标 if isMaximized(int(self.winId())): self.titleBar.maxBt.setMaxState(True) def moveEvent(self, e): if hasattr(self, 'playBar'): if not self.isMaximized(): self.playBar.move( self.x() - 8, self.y() + self.height() - self.playBar.height()) else: self.playBar.move( self.x() + 1, self.y() + self.height() - self.playBar.height() + 9) def closeEvent(self, e: QCloseEvent): """ 关闭窗口前更新json文件 """ if self.playlist.currentIndex() >= 0: self.settingInterface.config['last-song'] = self.playlist.playlist[ self.playlist.currentIndex()] else: self.settingInterface.config['last-song'] = {} self.settingInterface.config[ 'volume'] = self.playBar.volumeSlider.value() self.settingInterface.config[ 'playBar-acrylicColor'] = self.playBar.acrylicColor self.settingInterface.writeConfig() self.playBar.close() self.subPlayWindow.close() self.playlist.save() e.accept() def nativeEvent(self, eventType, message): """ 处理windows消息 """ msg = MSG.from_address(message.__int__()) if msg.message == win32con.WM_NCHITTEST: xPos = win32api.LOWORD(msg.lParam) - self.frameGeometry().x() yPos = win32api.HIWORD(msg.lParam) - self.frameGeometry().y() w, h = self.width(), self.height() lx = xPos < self.BORDER_WIDTH rx = xPos + 9 > w - self.BORDER_WIDTH ty = yPos < self.BORDER_WIDTH by = yPos > h - self.BORDER_WIDTH if (lx and ty): return True, win32con.HTTOPLEFT elif (rx and by): return True, win32con.HTBOTTOMRIGHT elif (rx and ty): return True, win32con.HTTOPRIGHT elif (lx and by): return True, win32con.HTBOTTOMLEFT elif ty: return True, win32con.HTTOP elif by: return True, win32con.HTBOTTOM elif lx: return True, win32con.HTLEFT elif rx: return True, win32con.HTRIGHT elif msg.message == win32con.WM_NCCALCSIZE: if isMaximized(msg.hWnd): self.windowEffect.adjustMaximizedClientRect( HWND(msg.hWnd), msg.lParam) return True, 0 if msg.message == win32con.WM_GETMINMAXINFO: if isMaximized(msg.hWnd): window_rect = win32gui.GetWindowRect(msg.hWnd) if not window_rect: return False, 0 # 获取显示器句柄 monitor = win32api.MonitorFromRect(window_rect) if not monitor: return False, 0 # 获取显示器信息 monitor_info = win32api.GetMonitorInfo(monitor) monitor_rect = monitor_info['Monitor'] work_area = monitor_info['Work'] # 将lParam转换为MINMAXINFO指针 info = cast(msg.lParam, POINTER(MINMAXINFO)).contents # 调整位置 info.ptMaxSize.x = work_area[2] - work_area[0] info.ptMaxSize.y = work_area[3] - work_area[1] info.ptMaxTrackSize.x = info.ptMaxSize.x info.ptMaxTrackSize.y = info.ptMaxSize.y # 修改放置点的x,y坐标 info.ptMaxPosition.x = abs(window_rect[0] - monitor_rect[0]) info.ptMaxPosition.y = abs(window_rect[1] - monitor_rect[1]) return True, 1 return QWidget.nativeEvent(self, eventType, message) def connectSignalToSlot(self): """ 将信号连接到槽 """ # todo:设置界面信号连接到槽函数 self.settingInterface.crawlComplete.connect(self.crawCompleteSlot) self.settingInterface.selectedFoldersChanged.connect( self.myMusicInterface.scanTargetPathSongInfo) # todo:标题栏返回按钮功能 self.titleBar.returnBt.clicked.connect(self.returnButtonSlot) # todo:导航界面信号连接到槽函数 self.navigationInterface.displayModeChanged.connect( self.navigationDisplayModeChangedSlot) self.navigationInterface.switchInterfaceSig.connect( self.stackWidgetIndexChangedSlot) self.navigationInterface.showPlayingInterfaceSig.connect( self.showPlayingInterface) self.navigationInterface.showCreatePlaylistPanelSig.connect( self.showCreatePlaylistPanel) self.navigationInterface.switchToSettingInterfaceSig.connect( self.switchToSettingInterface) self.navigationInterface.switchToMyMusicInterfaceSig.connect( self.switchToMyMusicInterface) self.navigationInterface.switchToPlaylistCardInterfaceSig.connect( self.switchToPlaylistCardInterface) # todo:缩略图任务栏各按钮的功能 self.thumbnailToolBar.playButton.clicked.connect(self.switchPlayState) self.thumbnailToolBar.lastSongButton.clicked.connect( self.playlist.previous) self.thumbnailToolBar.nextSongButton.clicked.connect( self.playlist.next) # todo:播放栏各部件功能 self.playBar.playButton.clicked.connect(self.switchPlayState) self.playBar.nextSongButton.clicked.connect(self.playlist.next) self.playBar.volumeButton.muteStateChanged.connect(self.setMute) self.playBar.randomPlayButton.clicked.connect(self.setRandomPlay) self.playBar.lastSongButton.clicked.connect(self.playlist.previous) self.playBar.songInfoCard.clicked.connect(self.showPlayingInterface) self.playBar.volumeSlider.valueChanged.connect(self.volumeChangedSlot) self.playBar.progressSlider.sliderMoved.connect( self.progressSliderMoveSlot) self.playBar.progressSlider.clicked.connect( self.progressSliderMoveSlot) self.playBar.loopModeButton.loopModeChanged.connect( self.switchLoopMode) self.playBar.moreActionsMenu.fillScreenAct.triggered.connect( self.setFullScreen) self.playBar.moreActionsMenu.showPlayListAct.triggered.connect( self.showPlaylist) self.playBar.moreActionsMenu.clearPlayListAct.triggered.connect( self.clearPlaylist) self.playBar.smallPlayModeButton.clicked.connect( self.showSmallestModeInterface) self.playBar.moreActionsMenu.savePlayListAct.triggered.connect( lambda: self.showCreatePlaylistPanel(self.playlist.playlist)) # todo:将播放器的信号连接到槽函数 self.player.positionChanged.connect(self.playerPositionChangeSlot) self.player.durationChanged.connect(self.playerDurationChangeSlot) # todo:将播放列表的信号连接到槽函数 self.playlist.switchSongSignal.connect(self.updateWindow) self.playlist.currentIndexChanged.connect( self.playingInterface.setCurrentIndex) # todo:将正在播放界面信号连接到槽函数 self.playingInterface.currentIndexChanged.connect( self.playingInterfaceCurrrentIndexChangedSlot) self.playingInterface.switchPlayStateSig.connect(self.switchPlayState) self.playingInterface.lastSongSig.connect(self.playlist.previous) self.playingInterface.nextSongSig.connect(self.playlist.next) self.playingInterface.playBar.randomPlayButton.clicked.connect( self.setRandomPlay) self.playingInterface.playBar.volumeSlider.muteStateChanged.connect( self.setMute) self.playingInterface.playBar.volumeSlider.volumeSlider.valueChanged.connect( self.volumeChangedSlot) self.playingInterface.playBar.progressSlider.sliderMoved.connect( self.progressSliderMoveSlot) self.playingInterface.playBar.progressSlider.clicked.connect( self.progressSliderMoveSlot) self.playingInterface.playBar.fillScreenButton.clicked.connect( self.setFullScreen) self.playingInterface.playBar.loopModeButton.loopModeChanged.connect( self.switchLoopMode) self.playingInterface.removeMediaSignal.connect( self.playlist.removeMedia) self.playingInterface.randomPlayAllSignal.connect(self.disorderPlayAll) self.playingInterface.switchToAlbumInterfaceSig.connect( self.switchToAlbumInterfaceByName) self.playingInterface.playBar.moreActionsMenu.clearPlayListAct.triggered.connect( self.clearPlaylist) self.playingInterface.playBar.moreActionsMenu.savePlayListAct.triggered.connect( lambda: self.showCreatePlaylistPanel(self.playlist.playlist)) self.playingInterface.smallestModeStateChanged.connect( self.smallestModeStateChanedSlot) self.playingInterface.exitFullScreenSig.connect(self.exitFullScreen) # todo:歌曲界面歌曲卡列表视图的信号连接到槽函数 self.songTabSongListWidget.playSignal.connect(self.songCardPlaySlot) self.songTabSongListWidget.playOneSongSig.connect(self.playOneSongCard) self.songTabSongListWidget.nextToPlayOneSongSig.connect( self.songCardNextPlaySlot) self.songTabSongListWidget.addSongToPlayingSignal.connect( self.addOneSongToPlayingPlaylist) self.songTabSongListWidget.switchToAlbumInterfaceSig.connect( self.switchToAlbumInterfaceByName) self.songTabSongListWidget.editSongCardSignal.connect( self.editSongCardSlot) # todo:将专辑卡的信号连接到槽函数 self.albumCardViewer.playSignal.connect(self.playAlbum) self.albumCardViewer.nextPlaySignal.connect( self.multiSongsNextPlaySlot) self.albumCardViewer.switchToAlbumInterfaceSig.connect( self.switchToAlbumInterfaceByAlbumInfo) self.albumCardViewer.saveAlbumInfoSig.connect(self.updateAlbumInfo) # todo:将子播放窗口的信号连接槽槽函数 self.subPlayWindow.nextSongButton.clicked.connect(self.playlist.next) self.subPlayWindow.lastSongButton.clicked.connect( self.playlist.previous) self.subPlayWindow.playButton.clicked.connect(self.switchPlayState) # todo:将我的音乐界面连接到槽函数 self.myMusicInterface.randomPlayAllSig.connect(self.disorderPlayAll) self.myMusicInterface.playCheckedCardsSig.connect( self.playCheckedCards) self.myMusicInterface.currentIndexChanged.connect( self.stackWidgetIndexChangedSlot) self.myMusicInterface.nextToPlayCheckedCardsSig.connect( self.multiSongsNextPlaySlot) self.myMusicInterface.selectionModeStateChanged.connect( self.selectionModeStateChangedSlot) self.myMusicInterface.addSongsToCustomPlaylistSig.connect( self.addSongsToCustomPlaylist) self.myMusicInterface.addSongsToNewCustomPlaylistSig.connect( lambda songInfo_list: self.showCreatePlaylistPanel(songInfo_list)) self.myMusicInterface.addSongsToPlayingPlaylistSig.connect( self.addSongsToPlayingPlaylist) # todo:将自己的信号连接到槽函数 self.showSubPlayWindowSig.connect(self.subPlayWindow.show) # todo:将专辑界面的信号连接到槽函数 self.albumInterface.playAlbumSignal.connect(self.playAlbum) self.albumInterface.songCardPlaySig.connect( self.albumInterfaceSongCardPlaySlot) self.albumInterface.playOneSongCardSig.connect(self.playOneSongCard) self.albumInterface.nextToPlayOneSongSig.connect( self.songCardNextPlaySlot) self.albumInterface.addOneSongToPlayingSig.connect( self.addOneSongToPlayingPlaylist) self.albumInterface.addSongsToPlayingPlaylistSig.connect( self.addSongsToPlayingPlaylist) self.albumInterface.songListWidget.editSongCardSignal.connect( self.editSongCardSlot) self.albumInterface.saveAlbumInfoSig.connect(self.updateAlbumInfo) self.albumInterface.selectionModeStateChanged.connect( self.selectionModeStateChangedSlot) self.albumInterface.playCheckedCardsSig.connect(self.playCheckedCards) self.albumInterface.nextToPlayCheckedCardsSig.connect( self.multiSongsNextPlaySlot) self.albumInterface.addSongsToCustomPlaylistSig.connect( self.addSongsToCustomPlaylist) self.albumInterface.addSongsToNewCustomPlaylistSig.connect( lambda songInfo_list: self.showCreatePlaylistPanel(songInfo_list)) # todo:将播放列表界面信号连接到槽函数 self.playlistCardInterface.selectionModeStateChanged.connect( self.selectionModeStateChangedSlot) self.playlistCardInterface.createPlaylistButton.clicked.connect( self.showCreatePlaylistPanel) self.playlistCardInterface.renamePlaylistSig.connect( self.renamePlaylistSlot) self.playlistCardInterface.deletePlaylistSig.connect( self.removePlaylistSlot) self.playlistCardInterface.playSig.connect(self.playCustomPlaylist) self.playlistCardInterface.nextToPlaySig.connect( self.multiSongsNextPlaySlot) def referenceWidgets(self): """ 引用小部件 """ self.songTabSongListWidget = self.myMusicInterface.songCardListWidget self.albumCardViewer = self.myMusicInterface.albumCardViewer def navigationDisplayModeChangedSlot(self, diaPlayMode: int): """ 导航界面显示模式改变对应的槽函数 """ self.titleBar.title.setVisible(self.navigationInterface.isExpanded) self.adjustWidgetGeometry() self.navigationInterface.navigationMenu.stackUnder(self.playBar) def initPlaylist(self): """ 初始化播放列表 """ self.player.setPlaylist(self.playlist) # 如果没有上一次的播放列表数据,就设置默认的播放列表 if not self.playlist.playlist: songInfo_list = self.songTabSongListWidget.songInfo_list self.playingInterface.setPlaylist(songInfo_list) self.playlist.setPlaylist(songInfo_list) self.playlist.playlistType = PlaylistType.ALL_SONG_PLAYLIST # 将当前歌曲设置为上次关闭前播放的歌曲 if self.lastSongInfo in self.playlist.playlist: index = self.playlist.playlist.index(self.lastSongInfo) self.playlist.setCurrentIndex(index) self.playingInterface.setCurrentIndex(index) def switchPlayState(self): """ 播放按钮按下时根据播放器的状态来决定是暂停还是播放 """ if self.player.state() == QMediaPlayer.PlayingState: self.player.pause() self.setPlayButtonState(False) self.thumbnailToolBar.setButtonsEnabled(True) else: self.play() def setPlayButtonState(self, isPlay: bool): """ 设置播放按钮状态 """ self.subPlayWindow.setPlay(isPlay) self.playBar.playButton.setPlay(isPlay) self.thumbnailToolBar.playButton.setPlay(isPlay) self.playingInterface.playBar.playButton.setPlay(isPlay) self.playingInterface.smallestModeInterface.playButton.setPlay(isPlay) def volumeChangedSlot(self, value): """ 音量滑动条数值改变时更换图标并设置音量 """ self.player.setVolume(value) self.playBar.volumeButton.setVolumeLevel(value) if self.sender() == self.playBar.volumeSlider: self.playingInterface.playBar.volumeSlider.setValue(value) elif self.sender( ) == self.playingInterface.playBar.volumeSlider.volumeSlider: self.playBar.volumeSlider.setValue(value) def playerPositionChangeSlot(self): """ 播放器的播放进度改变时更新当前播放进度标签和进度条的值 """ self.playBar.progressSlider.setValue(self.player.position()) self.playBar.setCurrentTime(self.player.position()) self.playingInterface.playBar.progressSlider.setValue( self.player.position()) self.playingInterface.playBar.setCurrentTime(self.player.position()) self.playingInterface.smallestModeInterface.progressBar.setValue( self.player.position()) def playerDurationChangeSlot(self): """ 播放器当前播放的歌曲变化时更新进度条的范围和总时长标签 """ # 刚切换时得到的时长为0,所以需要先判断一下 if self.player.duration() >= 1: self.playBar.setTotalTime(self.player.duration()) self.playBar.progressSlider.setRange(0, self.player.duration()) self.playingInterface.playBar.progressSlider.setRange( 0, self.player.duration()) self.playingInterface.playBar.setTotalTime(self.player.duration()) self.playingInterface.smallestModeInterface.progressBar.setRange( 0, self.player.duration()) def progressSliderMoveSlot(self): """ 手动拖动进度条时改变当前播放进度标签和播放器的值 """ if self.sender() == self.playBar.progressSlider: self.player.setPosition(self.playBar.progressSlider.value()) elif self.sender() == self.playingInterface.playBar.progressSlider: self.player.setPosition( self.playingInterface.playBar.progressSlider.value()) self.playBar.setCurrentTime(self.player.position()) self.playingInterface.playBar.setCurrentTime(self.player.position()) self.playingInterface.smallestModeInterface.progressBar.setValue( self.player.position()) def songCardNextPlaySlot(self, songInfo: dict): """ 下一首播放动作触发对应的槽函数 """ # 直接更新正在播放界面的播放列表 index = self.playlist.currentIndex() newPlaylist = self.playlist.playlist[:index + 1] + \ [songInfo] + self.playlist.playlist[index + 1:] self.playingInterface.setPlaylist(newPlaylist, False) self.playingInterface.setCurrentIndex(self.playlist.currentIndex()) self.playlist.insertMedia(self.playlist.currentIndex() + 1, songInfo) def songCardPlaySlot(self, songInfo: dict): """ 歌曲界面歌曲卡的播放按钮按下或者双击歌曲卡时播放这首歌 """ # 如果当前播放列表模式不是歌曲文件夹的所有歌曲或者指定的歌曲不在播放列表中就刷新播放列表 if self.playlist.playlistType != PlaylistType.ALL_SONG_PLAYLIST or songInfo not in self.playlist.playlist: self.playlist.playlistType = PlaylistType.ALL_SONG_PLAYLIST songInfo_list = self.songTabSongListWidget.songInfo_list index = songInfo_list.index(songInfo) newPlaylist = songInfo_list[index:] + songInfo_list[0:index] self.playlist.setPlaylist(newPlaylist) self.playingInterface.setPlaylist(newPlaylist) # 将播放列表的当前歌曲设置为指定的歌曲 self.playlist.setCurrentSong(songInfo) self.play() def playOneSongCard(self, songInfo: dict): """ 将播放列表重置为一首歌 """ self.playlist.playlistType = PlaylistType.SONG_CARD_PLAYLIST self.setPlaylist([songInfo]) def switchLoopMode(self, loopMode): """ 根据随机播放按钮的状态和循环模式的状态决定播放器的播放模式 """ # 记录按下随机播放前的循环模式 self.playlist.prePlayMode = loopMode # 更新按钮样式 if self.sender() == self.playBar.loopModeButton: self.playingInterface.playBar.loopModeButton.setLoopMode(loopMode) elif self.sender() == self.playingInterface.playBar.loopModeButton: self.playBar.loopModeButton.setLoopMode(loopMode) if not self.playlist.randPlayBtPressed: # 随机播放按钮没按下时,直接设置播放模式为循环模式按钮的状态 self.playlist.setPlaybackMode(loopMode) else: # 随机播放按钮按下时,如果选了单曲循环就直接设置为单曲循环,否则设置为随机播放 if self.playBar.loopModeButton.loopMode == QMediaPlaylist.CurrentItemInLoop: self.playlist.setPlaybackMode(QMediaPlaylist.CurrentItemInLoop) else: self.playlist.setPlaybackMode(QMediaPlaylist.Random) def setRandomPlay(self): """ 选择随机播放模式 """ isRandomPlay = self.sender().isSelected self.playlist.setRandomPlay(isRandomPlay) if self.sender() == self.playBar.randomPlayButton: self.playingInterface.playBar.randomPlayButton.setRandomPlay( isRandomPlay) elif self.sender() == self.playingInterface.playBar.randomPlayButton: self.playBar.randomPlayButton.setRandomPlay(isRandomPlay) def updateWindow(self, songInfo): """ 切换歌曲时更新歌曲卡、播放栏和子播放窗口 """ self.playBar.updateSongInfoCard(songInfo) index = self.songTabSongListWidget.songInfo_list.index(songInfo) self.songTabSongListWidget.setPlay(index) # 更新专辑界面的歌曲卡 if songInfo in self.albumInterface.songListWidget.songInfo_list: index = self.albumInterface.songListWidget.songInfo_list.index( songInfo) self.albumInterface.songListWidget.setPlay(index) self.subPlayWindow.updateWindow(songInfo) def hotKeySlot(self, funcObj): """ 热键按下时显示子播放窗口并执行对应操作 """ funcObj() self.showSubPlayWindowSig.emit() def playAlbum(self, playlist: list): """ 播放专辑中的歌曲 """ # 直接更新播放列表 self.playingInterface.setPlaylist(playlist) self.playlist.playAlbum(playlist) self.play() def multiSongsNextPlaySlot(self, songInfo_list: list): """ 多首歌下一首播放动作触发对应的槽函数 """ index = self.playlist.currentIndex() newPlaylist = self.playlist.playlist[:index + 1] + \ songInfo_list + self.playlist.playlist[index + 1:] self.playingInterface.setPlaylist(newPlaylist, isResetIndex=False) self.playingInterface.setCurrentIndex(self.playlist.currentIndex()) # insertMedia的时候自动更新playlist列表,所以不必手动更新列表 self.playlist.insertMedias(self.playlist.currentIndex() + 1, songInfo_list) def disorderPlayAll(self): """ 无序播放所有 """ self.playlist.playlistType = PlaylistType.ALL_SONG_PLAYLIST newPlaylist = deepcopy(self.songTabSongListWidget.songInfo_list) shuffle(newPlaylist) self.setPlaylist(newPlaylist) def play(self): """ 播放歌曲并改变按钮样式 """ self.player.play() self.setPlayButtonState(True) # 显示被隐藏的歌曲信息卡 if self.playlist.playlist: if not self.playBar.songInfoCard.isVisible( ) and self.playBar.isVisible(): self.playBar.songInfoCard.show() self.playBar.songInfoCard.updateSongInfoCard( self.playlist.playlist[0]) def initPlayBar(self): """ 从配置文件中读取配置数据来初始化播放栏 """ # 初始化音量 volume = self.settingInterface.config.get('volume', 20) self.playingInterface.playBar.volumeSlider.setValue(volume) # 初始化亚克力颜色 acrylicColor = self.settingInterface.config.get( 'playBar-acrylicColor', '225c7fCC') self.playBar.setAcrylicColor(acrylicColor) def showPlayingInterface(self): """ 显示正在播放界面 """ # 先退出选择模式 self.exitSelectionMode() self.playBar.hide() self.titleBar.title.hide() self.titleBar.returnBt.show() if not self.playingInterface.isPlaylistVisible: self.playingInterface.songInfoCardChute.move( 0, -self.playingInterface.playBar.height() + 68) self.playingInterface.playBar.show() self.totalStackWidget.setCurrentIndex(1) self.titleBar.setWhiteIcon(True) def hidePlayingInterface(self): """ 隐藏正在播放界面 """ self.playBar.show() self.totalStackWidget.setCurrentIndex(0) # 根据当前界面设置标题栏按钮颜色 if self.subStackWidget.currentWidget() == self.albumInterface: self.titleBar.returnBt.setWhiteIcon(False) else: self.titleBar.setWhiteIcon(False) # 隐藏返回按钮 if len( self.titleBar.stackWidgetIndex_list ) == 1 and self.subStackWidget.currentWidget() != self.albumInterface: self.titleBar.returnBt.hide() self.titleBar.title.setVisible(self.navigationInterface.isExpanded) def setQss(self): """ 设置层叠样式 """ with open(r'resource\css\mainWindow.qss', encoding='utf-8') as f: self.setStyleSheet(f.read()) def playingInterfaceCurrrentIndexChangedSlot(self, index): """ 正在播放界面下标变化槽函数 """ self.playlist.setCurrentIndex(index) self.play() def setMute(self, isMute): """ 设置静音 """ self.player.setMuted(isMute) if self.sender() == self.playBar.volumeButton: self.playingInterface.playBar.volumeButton.setMute(isMute) self.playingInterface.playBar.volumeSlider.volumeButton.setMute( isMute) elif self.sender() == self.playingInterface.playBar.volumeSlider: self.playBar.volumeButton.setMute(isMute) def setFullScreen(self): """ 设置全屏 """ if not self.isFullScreen(): # 更新标题栏 self.playBar.hide() self.titleBar.title.hide() self.titleBar.setWhiteIcon(True) self.titleBar.hide() # 切换到正在播放界面 self.totalStackWidget.setCurrentIndex(1) self.showFullScreen() self.playingInterface.playBar.fillScreenButton.setFillScreen(True) if self.playingInterface.isPlaylistVisible: self.playingInterface.songInfoCardChute.move( 0, 258 - self.height()) else: self.exitFullScreen() def exitFullScreen(self): """ 退出全屏 """ if not self.isFullScreen(): return self.showNormal() # 更新最大化按钮图标 self.titleBar.maxBt.setMaxState(False) self.titleBar.returnBt.show() self.titleBar.show() self.playingInterface.playBar.fillScreenButton.setFillScreen(False) if self.playingInterface.isPlaylistVisible: self.playingInterface.songInfoCardChute.move( 0, 258 - self.height()) def crawCompleteSlot(self): """ 爬虫完成信号槽函数 """ self.myMusicInterface.scanTargetPathSongInfo( self.settingInterface.config.get('selected-folders')) def showPlaylist(self): """ 显示正在播放界面的播放列表 """ self.playingInterface.showPlaylist() # 直接设置播放栏上拉箭头按钮箭头方向朝下 self.playingInterface.playBar.pullUpArrowButton.setArrowDirection( 'down') if self.playingInterface.isPlaylistVisible: self.showPlayingInterface() def clearPlaylist(self): """ 清空播放列表 """ self.playlist.playlistType = PlaylistType.NO_PLAYLIST self.playlist.clear() self.playingInterface.clearPlaylist() def addOneSongToPlayingPlaylist(self, songInfo: dict): """ 向正在播放列表尾部添加一首歌 """ self.playlist.addMedia(songInfo) self.playingInterface.setPlaylist(self.playlist.playlist, False) def addSongsToPlayingPlaylist(self, songInfo_list: list): """ 向正在播放列表尾部添加多首歌 """ self.playlist.addMedias(songInfo_list) self.playingInterface.setPlaylist(self.playlist.playlist, False) def switchToAlbumInterfaceByName(self, albumName: str, songerName: str): """ 由名字切换到专辑界面 """ # 处于选择模式下直接返回 if self.isInSelectionMode: return if self.albumInterface.albumInfo.get('album') != albumName or \ self.albumInterface.albumInfo.get('songer') != songerName or not self.currentAlbumCard: self.currentAlbumCard = self.albumCardViewer.findAlbumCardByName( albumName, songerName) if self.currentAlbumCard: self.__switchToAlbumInterface(self.currentAlbumCard.albumInfo) def switchToAlbumInterfaceByAlbumInfo(self, albumInfo: dict): """ 由专辑信息切换到专辑界面 """ # 处于选择模式下直接返回 if self.isInSelectionMode: return # 引用对应的专辑卡 if self.albumInterface.albumInfo != albumInfo or not self.currentAlbumCard: self.currentAlbumCard = self.albumCardViewer.findAlbumCardByAlbumInfo( albumInfo) self.__switchToAlbumInterface(albumInfo) def __switchToAlbumInterface(self, albumInfo: dict): """ 切换到专辑界面 """ # 退出全屏 if self.isFullScreen(): self.exitFullScreen() # 显示返回按钮 self.titleBar.returnBt.show() QApplication.processEvents() self.albumInterface.updateWindow(albumInfo) self.subStackWidget.setCurrentWidget(self.albumInterface, duration=300) self.totalStackWidget.setCurrentIndex(0) self.playBar.show() self.titleBar.setWhiteIcon(True) self.titleBar.returnBt.setWhiteIcon(False) # 根据当前播放的歌曲设置歌曲卡播放状态 songInfo = self.playlist.playlist[self.playlist.currentIndex()] if songInfo in self.albumInterface.songInfo_list: index = self.albumInterface.songInfo_list.index(songInfo) self.albumInterface.songListWidget.setPlay(index) else: self.albumInterface.songListWidget.songCard_list[ self.albumInterface.songListWidget.playingIndex].setPlay(False) def albumInterfaceSongCardPlaySlot(self, index): """ 专辑界面歌曲卡播放按钮按下时 """ albumSongList = self.albumInterface.songInfo_list # 播放模式不为专辑播放模式或者播放列表不同时直接刷新播放列表 cond = self.playlist.playlistType != PlaylistType.ALBUM_CARD_PLAYLIST \ or self.playlist.playlist != albumSongList if cond: self.playAlbum(albumSongList) self.playlist.setCurrentIndex(index) def returnButtonSlot(self): """ 标题栏返回按钮的槽函数 """ if self.isInSelectionMode: return # 隐藏音量条 self.playingInterface.playBar.volumeSlider.hide() if self.totalStackWidget.currentWidget() == self.playingInterface: self.hidePlayingInterface() else: # 当前界面不是albumInterface时弹出下标列表的最后一个下标 if self.titleBar.stackWidgetIndex_list and self.subStackWidget.currentWidget( ) != self.albumInterface: self.titleBar.stackWidgetIndex_list.pop() if self.titleBar.stackWidgetIndex_list: stackWidgetName, index = self.titleBar.stackWidgetIndex_list[ -1] if stackWidgetName == 'myMusicInterfaceStackWidget': self.myMusicInterface.stackedWidget.setCurrentIndex(index) if self.subStackWidget.currentWidget( ) != self.albumInterface: self.subStackWidget.setCurrentIndex( 0, True, False, duration=200, easingCurve=QEasingCurve.InCubic) else: self.subStackWidget.setCurrentIndex(0, True) self.navigationInterface.setCurrentIndex(0) self.myMusicInterface.setSelectedButton(index) elif stackWidgetName == 'subStackWidget': isShowNextWidgetDirectly = not ( self.subStackWidget.currentWidget() is self.settingInterface) self.subStackWidget.setCurrentIndex( index, True, isShowNextWidgetDirectly, 200, QEasingCurve.InCubic) self.navigationInterface.setCurrentIndex(index) if len(self.titleBar.stackWidgetIndex_list) == 1: # 没有上一个下标时隐藏返回按钮 self.titleBar.returnBt.hide() # 更新按钮颜色 self.titleBar.setWhiteIcon(False) def stackWidgetIndexChangedSlot(self, index): """ 堆叠窗口下标改变时的槽函数 """ if self.sender() is self.navigationInterface: if self.subStackWidget.currentIndex() == index: return self.titleBar.stackWidgetIndex_list.append( ('subStackWidget', index)) self.titleBar.setWhiteIcon(False) elif self.sender() is self.myMusicInterface: self.titleBar.stackWidgetIndex_list.append( ('myMusicInterfaceStackWidget', index)) self.titleBar.returnBt.show() def editSongCardSlot(self, oldSongInfo: dict, newSongInfo: dict): """ 编辑歌曲卡完成信号的槽函数 """ self.playlist.updateOneSongInfo(oldSongInfo, newSongInfo) self.playingInterface.updateOneSongCard(oldSongInfo, newSongInfo) if self.sender() == self.albumInterface.songListWidget: self.songTabSongListWidget.updateOneSongCard( oldSongInfo, newSongInfo) elif self.sender() == self.songTabSongListWidget: # 获取专辑信息并更新专辑界面和专辑信息 albumInfo = self.albumCardViewer.updateOneAlbumCardSongInfo( newSongInfo) if albumInfo: self.albumInterface.updateWindow(albumInfo) self.albumInterface.updateOneSongCard(oldSongInfo, newSongInfo) def updateAlbumInfo(self, oldAlbumInfo: dict, newAlbumInfo: dict): """ 更新专辑卡及其对应的歌曲卡信息 """ oldSongInfo_list = oldAlbumInfo['songInfo_list'] newSongInfo_list = newAlbumInfo['songInfo_list'] self.songTabSongListWidget.updateMultiSongCards( deepcopy(oldSongInfo_list), deepcopy(newSongInfo_list)) self.playlist.updateMultiSongInfo(deepcopy(oldSongInfo_list), deepcopy(newSongInfo_list)) self.playingInterface.updateMultiSongCards(deepcopy(oldSongInfo_list), deepcopy(newSongInfo_list)) # 更新专辑标签界面 with open('Data\\songInfo.json', encoding='utf-8') as f: songInfo_list = json.load(f) self.myMusicInterface.updateAlbumCardViewer(songInfo_list) def smallestModeStateChanedSlot(self, state: bool): """ 最小播放模式状态改变时更改标题栏按钮可见性和窗口是否置顶 """ self.titleBar.closeBt.show() self.titleBar.returnBt.setHidden(state) self.titleBar.minBt.setHidden(state) self.titleBar.maxBt.setHidden(state) self.windowEffect.setWindowStayOnTop(self.winId(), state) def showSmallestModeInterface(self): """ 切换到最小化播放模式 """ self.showPlayingInterface() self.playingInterface.showSmallestModeInterface() def selectionModeStateChangedSlot(self, isOpenSelectionMode: bool): """ 进入/退出选择模式信号的槽函数 """ self.isInSelectionMode = isOpenSelectionMode self.playBar.setHidden(isOpenSelectionMode) def playCheckedCards(self, songInfo_list: list): """ 重置播放列表为所有选中的歌曲卡中的歌曲 """ self.playlist.playlistType = PlaylistType.CUSTOM_PLAYLIST self.setPlaylist(songInfo_list) def setPlaylist(self, playlist: list): """ 设置播放列表 """ self.playingInterface.setPlaylist(playlist) self.playlist.setPlaylist(playlist) self.play() def switchToSettingInterface(self): """ 切换到设置界面 """ # 先退出选择模式再切换界面 self.exitSelectionMode() self.subStackWidget.setCurrentWidget(self.settingInterface, duration=300) def switchToMyMusicInterface(self): """ 切换到我的音乐界面 """ self.exitSelectionMode() self.subStackWidget.setCurrentWidget(self.myMusicInterface) def switchToPlaylistCardInterface(self): """ 切换到播放列表卡界面 """ self.exitSelectionMode() self.subStackWidget.setCurrentWidget(self.playlistCardInterface, duration=300) def exitSelectionMode(self): """ 退出选择模式 """ if not self.isInSelectionMode: return self.myMusicInterface.exitSelectionMode() self.albumInterface.exitSelectionMode() self.playlistCardInterface.exitSelectionMode() def readCustomPlaylists(self): """ 读取自定义播放列表 """ # 如果没有播放列表文件夹就创建一个 if not os.path.exists('Playlists'): os.mkdir('Playlists') # 获取播放列表 self.customPlaylists = [] playlistFile_list = os.listdir('Playlists') for playlistFile in playlistFile_list: with open(os.path.join('Playlists', playlistFile), encoding='utf-8') as f: self.customPlaylists.append(json.load(f)) def showCreatePlaylistPanel(self, songInfo_list: list = None): """ 显示创建播放列表面板 """ createPlaylistPanel = CreatePlaylistPanel(self, songInfo_list) createPlaylistPanel.createPlaylistSig.connect(self.createPlaylistSlot) createPlaylistPanel.exec_() def createPlaylistSlot(self, playlist: dict): """ 创建播放列表 """ self.customPlaylists.append(playlist) self.playlistCardInterface.addOnePlaylistCard(playlist) self.navigationInterface.updateWindow() def renamePlaylistSlot(self, oldPlaylist: dict, newPlaylist: dict): """ 重命名播放列表槽函数 """ index = self.customPlaylists.index(oldPlaylist) self.customPlaylists[index] = newPlaylist self.navigationInterface.updateWindow() def removePlaylistSlot(self, playlist: dict): """ 删除播放列表槽函数 """ self.customPlaylists.remove(playlist) self.navigationInterface.updateWindow() def playCustomPlaylist(self, songInfo_list: list): """ 播放自定义播放列表中的所有歌曲 """ self.playCheckedCards(songInfo_list) def addSongsToCustomPlaylist(self, playlistName: str, songInfo_list: list): """ 将歌曲添加到自定义播放列表中 """ playlist = self.playlistCardInterface.addSongsToPlaylist( playlistName, songInfo_list) index = self.getCustomPlaylistIndexByName(playlistName) self.customPlaylists[index] = deepcopy(playlist) def getCustomPlaylistIndexByName(self, playlistName: str) -> int: """ 通过播放列表名字得到播放列表的下标 """ for index, playlist in enumerate(self.customPlaylists): if playlist['playlistName'] == playlistName: return index raise Exception(f'指定的播放列表"{playlistName}"不存在')
class Keybindings(object): def __init__(self, settings: ApplicationSettings, mappings: Dict[str, Dict[str, Tuple[str, Callable]]]): """ Creates keybindings for shortcuts stores in GSettings. The list of settings cannot be changed after created. Pass a map of (setting_id -> callback) """ super().__init__() self._mappings = mappings self._settings = settings self._active_shortcuts = dict() # see https://github.com/timeyyy/system_hotkey from system_hotkey import SystemHotkey self._keybinder = SystemHotkey() self.rebind_all() def rebind_all(self): for category, shortcuts in self._mappings.items(): if not shortcuts: continue for title, info in shortcuts.items(): shortcut_id, callback = info shortcut = self._settings.get_keybinding(shortcut_id) parsed = parse_keystroke(shortcut) if not callback: logging.warning( f"Empty callback for shortcut '{shortcut_id}': ignored" ) continue if not shortcut: logging.warning( f"Empty shortcut for settings '{shortcut_id}': ignored" ) continue logging.info( f"Binding '{shortcut_id}' -> '{callback.__name__}'") if shortcut and shortcut in self._active_shortcuts and self._active_shortcuts[ shortcut] != callback: logging.debug(f"Removing current binding '{shortcut}'") try: self._keybinder.unregister(parsed) del self._active_shortcuts[shortcut] except Exception as e: logging.error(f"Could not unbind '{shortcut}': {e}") continue if shortcut and shortcut not in self._active_shortcuts: logging.info( f"Binding '{shortcut}' ({parsed}) to '{callback.__name__}'" ) try: self._keybinder.register(parsed, callback=callback) self._active_shortcuts[shortcut] = callback except Exception as e: logging.error( f"Could not bind {shortcut} to {callback.__name__}: {e}" ) continue self._settings.connect(f"changed::{shortcut_id}", lambda k, s: self.rebind_all())
class myapp(tk.Tk): def __init__(self, ScriptPath=None): super().__init__() self.Cfg = Configuration() self.attributes('-type', 'dock') self.geometry("0x0+0+0") self.hk = SystemHotkey() self.hk.register(('control', 'shift', 'h'), callback=self.showhide) self.doingInput = False self.allDirs = None self.readAllDirsFromFile() dirFindThread = threading.Thread(target=self.updateAllDirs) dirFindThread.daemon = True dirFindThread.start() def exitProgram(self, *args): self.quit() def showhide(self, *args): if self.allDirs is None: return if not self.doingInput: self.update_idletasks() self.doingInput = True self.hk.unregister(('control', 'shift', 'h')) inputResult = inputDialog(self, self.allDirs).result self.hk.register(('control', 'shift', 'h'), callback=self.showhide) self.doingInput = False if not inputResult: return if inputResult == "###I###WANT###YOU###TO###GO###KILL###YOURSELF###": self.exitProgram() return #subprocess.run("/usr/bin/konsole &", shell=True, cwd=inputResult) subprocess.run('xdg-open "%s" &' % (inputResult), shell=True) def writeAllDirsToFile(self): if not os.path.isdir(self.Cfg.get('csvdir')): os.mkdir(self.Cfg.get('csvdir')) self.allDirs.to_csv( os.path.join(self.Cfg.get('csvdir'), self.Cfg.get('csvname')), columns=['Name'], ) def readAllDirsFromFile(self): csvfile = os.path.join(self.Cfg.get('csvdir'), self.Cfg.get('csvname')) if os.path.isfile(csvfile): self.allDirs = pd.read_csv(csvfile) def updateAllDirs(self): dirl = [] for root, dirs, files in os.walk(self.Cfg.get('topdir')): dirs[:] = [d for d in dirs if not d.startswith('.')] dirl.extend([os.path.join(root, dir) for dir in dirs]) #dirl = [x for x, _, _ in os.walk()] self.allDirs = pd.DataFrame(columns=['Name'], data=dirl) self.writeAllDirsToFile()
class MainWindow(QMainWindow): iconPath = "image/send.png" def __init__(self, parent=None): super().__init__(parent) self.w = Win32Window.from_qwindow(self) self.mwidget = QMainWindow(self) self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint) self.setWindowTitle("MTwit") # window size self.setFixedSize(480, 120) self.center() # TrayIcon self.createActions() self.createTrayIcon() self.trayIcon.show() self.trayIcon.activated.connect(self.iconActivated) # Textwindow self.textWindow = QPlainTextEdit('', self) self.textWindow.resize(400, 100) self.textWindow.move(10, 10) self.textWindow.setStyleSheet("background-color: rgba(0,0,0,50);" "border: 1px solid gray;" "font: 14pt 'Meiryo UI' ;" "color: #FFFFFF;") self.textWindow.setPlaceholderText("What's Happening?") # Quit Button self.qbtn = QuitButton(self) self.qbtn.setButtonPosition(self.size()) # Tweet Button self.tbtn = HoverButton(self) self.tbtn.resize(48, 48) self.tbtn.move(420, 62) self.tbtn.setObjectName('tButton') self.tbtn.setIcon(QIcon("image/send.png")) self.tbtn.setIconSize(QSize(32, 32)) self.tbtn.setStyleSheet("background-color: rgba(200, 200, 200, 0);") self.tbtn.clicked.connect(self.tweetEvent) # tweet Shortcut self.tShortcut = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_Return), self) self.tShortcut.activated.connect(self.tweetEvent) # window show Shortcut self.hk = SystemHotkey(consumer=self.ShowOrHide) self.hk.register(('alt', 'shift', 'f1')) # label """self.lbl = QLabel(self) self.lbl.setText("") self.lbl.setStyleSheet("background-color: rgb(0,0,0);" "border: 0px solid red;" "color: rgb(255,255,255);" "font: bold italic 20pt 'Times New Roman';") self.lbl.setGeometry(5,5,60,40) """ self.oldPos = self.pos() self.Firstshow() def Firstshow(self): # check user data and init api pass # windowMove -- def center(self): qr = self.frameGeometry() cp = QDesktopWidget().availableGeometry().center() qr.moveCenter(cp) self.move(qr.topLeft()) def mousePressEvent(self, event): self.oldPos = event.globalPos() def mouseMoveEvent(self, event): delta = QPoint(event.globalPos() - self.oldPos) self.move(self.x() + delta.x(), self.y() + delta.y()) self.oldPos = event.globalPos() # windowMove End -- def tweetEvent(self): print("tweetActivated") self.hide() text = self.textWindow.document().toPlainText() self.textWindow.setPlainText("") try: print(self.api.update_status(text)) # print(self.api.mentions_timeline(count=200)) except tweepy.error.TweepError as e: tb = sys.exc_info()[2] print("message:{0}".format(e.with_traceback(tb))) pass def quitEvent(self): self.trayIcon.hide() self.hk.unregister(('alt', 'shift', 'f1')) QCoreApplication.instance().quit() pass def templateTweetEvent(self): pass def iconActivated(self, reason): if reason == 3: self.ShowOrHide() def ShowOrHide(self, *args): if self.isHidden(): self.showEvent_() else: self.hide() def createTrayIcon(self): self.trayIconMenu = QMenu(self) self.trayIconMenu.addAction(self.debugMakeWindowAction) self.trayIconMenu.addAction(self.debugMakeWindow2Action) self.trayIconMenu.addAction(self.debugMakeWindow3Action) self.trayIconMenu.addSeparator() self.trayIconMenu.addAction(self.minimizeAction) self.trayIconMenu.addAction(self.restoreAction) self.trayIconMenu.addSeparator() self.trayIconMenu.addAction(self.quitAction) self.trayIcon = QSystemTrayIcon(self) self.trayIcon.setContextMenu(self.trayIconMenu) self.trayIcon.setIcon(QIcon(self.iconPath)) def createActions(self): self.minimizeAction = QAction("Mi&nimize", self, triggered=self.hide) self.restoreAction = QAction("&Restore", self, triggered=self.showNormal) self.quitAction = QAction("&Quit", self, triggered=self.quitEvent) self.debugMakeWindowAction = QAction("&DebugMakeAuth", self, triggered=self.makeAuthWindow) self.debugMakeWindow2Action = QAction("&DebugMake2Auth", self, triggered=self.makeAuthWindow2) self.debugMakeWindow3Action = QAction("&DebugMake3(Notification)", self, triggered=self.makeDebugwindow) def showEvent_(self): self.textWindow.setPlainText("") self.show() self.w.focus() self.textWindow.setFocus() # Auth Window def makeAuthWindow(self): from mTwit.Authwindow_Ui import AuthWindow authWindow = AuthWindow(self) authWindow.show("TwitterPIN") # Debug def makeAuthWindow2(self): from mTwit.Authwindow_Ui import AuthWindow authWindow = AuthWindow(self) authWindow.show("Consumer") def makeNotificationWindow(self): pass def makeDebugwindow(self, *args): fav = NotificationWindow(self, message="Test Message.") fav.show(NotificationMode.ERROR) """ try: raise MTwitError except: pass """ def setParam(self, param): self.textWindow.setPlainText(param)
class panel(QWidget): sig_keyhot = pyqtSignal(str) def __init__(self, window): super().__init__(window) # 2. 设置我们的自定义热键响应函数 self.sig_keyhot.connect(self.MKey_pressEvent) # 3. 初始化两个热键 self.hk_start, self.hk_stop = SystemHotkey(), SystemHotkey() # 4. 绑定快捷键和对应的信号发送函数 self.hk_start.register( ('alt', 'c'), callback=lambda x: self.send_key_event("enText")) self.hk_stop.register(('alt', 'v'), callback=lambda x: self.send_key_event("deText")) # 热键处理函数 def MKey_pressEvent(self, i_str): print("按下的按键是%s" % (i_str)) if (i_str == 'enText'): key_up('alt') key_up('c') # keys_tap(['ctrl', 'a']) data = getClipboardData() # 获取剪切板内容 print(data) strEncrypted = encrypt(data) strEncrypted = str(strEncrypted, 'utf8') print(strEncrypted) setClipboardData(strEncrypted) keys_tap(['ctrl', 'v']) elif (i_str == 'deText'): key_up('alt') key_up('v') # keys_tap(['ctrl', 'a']) # keys_tap(['ctrl', 'x']) strDecrypted = getClipboardData() # 获取剪切板内容 try: strDecrypted = decrypt(strDecrypted) strDecrypted = str(strDecrypted, 'utf8') # b转字符串 except Exception as e: print(e) print(strDecrypted) setClipboardData(strDecrypted) keys_tap(['ctrl', 'v']) # 热键信号发送函数(将外部信号,转化成qt信号) def send_key_event(self, i_str): self.sig_keyhot.emit(i_str) def hideLoading(self): self.movie.stop() self.gifLabel.hide() def showLoading(self): self.movie.start() self.gifLabel.show() def handleEnBtn(self): strEncrypted = self.text.toPlainText() # 获取文本框中的东西 fPath = self.text.toPlainText() strEncrypted = encrypt(strEncrypted) strEncrypted = str(strEncrypted, encoding='utf8') print(strEncrypted) # 显示并重新更改框高 strlen = len(strEncrypted) # self.text.resize(500,28 * (int(strlen / 60) + 1)) self.text.setPlainText(strEncrypted) setClipboardData(strEncrypted) self.showLoading() # --分割-- 下方加密图片 try: self.showLoading() fPath = fPath.replace('file://', '') imgEncrypt(fPath, enToImgPath) image = QImage(enToImgPath) self.label.setPixmap(QPixmap.fromImage(image)) except Exception as e: print(e) self.lbTopTips.setText('加密失败或找不到图片') self.hideLoading() def handleDeBtn(self): strDecrypted = self.text.toPlainText() # 获取文本框中的东西 dPath = self.text.toPlainText() # 获取输入路径 try: strDecrypted = decrypt(strDecrypted) strDecrypted = str(strDecrypted, 'utf8') # b转字符串 except Exception as e: print(e) # self.text.resize(500,28 * (int(strlen / 60) + 1)) self.text.setPlainText(strDecrypted) setClipboardData(strDecrypted) self.showLoading() # ---下方是图像的解密--- try: dPath = dPath.replace('file://', '') print(dPath) imgDecrypt(dPath, deToImgPath) image = QImage(deToImgPath) self.label.setPixmap(QPixmap.fromImage(image)) except Exception as e: self.lbTopTips.setText('解密失败或找不到图片') self.hideLoading() def openImage(self): imgName = QFileDialog.getOpenFileName( window, "打开图片", "", "ALL(*.*);;Images(*.png *.jpg *.bmp);;") imgPath = imgName[0] print(imgPath) self.text.setPlainText(imgPath) def setUI(self, window): window.resize(winWidth, winHeigh) # 窗口标题 window.setWindowTitle("fp翻译机 " + version) window.setWindowIcon(QtGui.QIcon('src/logo.png')) # 新增一个 用于输出 标签控件 self.label = QtWidgets.QLabel(window) self.label.setAcceptDrops(True) self.label.setGeometry( QtCore.QRect(winWidth / 2 + 60, 0, winWidth / 2 - 100, winHeigh)) # 标签位置 坐标x,y 宽,高 self.label.setAlignment(Qt.AlignTop) # 自适应大小 self.label.setTextInteractionFlags(Qt.TextSelectableByMouse) # 鼠标可滑动选中 self.label.installEventFilter(window) self.label.setScaledContents(True) # 自适应 # 新增一个 loading 标签 self.gifLabel = QtWidgets.QLabel(window) self.gifLabel.setGeometry(winWidth / 6 * 5, winHeigh / 2, 50, 50) # 标签位置 坐标x,y 宽,高 self.movie = QMovie("./src/loading.gif") self.movie.setScaledSize(QSize(20, 20)) self.gifLabel.setMovie(self.movie) # self.movie.start() # self.gifLabel.hide() # # 新增一个提示标签控件 self.lbTopTips = QtWidgets.QLabel(window) self.lbTopTips.adjustSize() # 自适应大小 self.lbTopTips.setGeometry(QtCore.QRect(50, 0, 300, 28)) # 标签位置 坐标x,y 宽,高 self.lbTopTips.setText("图片或图片拖入下方输入框") # # 新增一个右边提示标签控件 self.lbRight = QtWidgets.QLabel(window) self.lbRight.setGeometry( QtCore.QRect(50, winHeigh / 2 - 50, winWidth / 2, winHeigh / 2)) # 标签位置 坐标x,y 宽,高 # self.lbRight.adjustSize() # 自适应大小 self.lbRight.setMaximumWidth(winWidth / 2) self.lbRight.setWordWrap(True) self.lbRight.setAlignment(Qt.AlignTop) self.lbRight.setText( "使用说明:\n\n1、alt + c 将剪贴板内容加密\n alt + v 将剪贴板内容解密\n\n" + "2、图像加解密--加密 点击“打开图片”选择图片-->点击加密,将会输出./cache/enOut.bmp,选择此文件可以发送到微信\n\n" + "3、图像加解密--解密 点击“打开图片”选择图片-->点击解密,图片将会输出在此应用中,亦可找到./cache/deOut.bmp查看\n\n" + "文字加解密一般用法:ctrl + a ,ctrl + x,alt + c/v \n\n" + "图像加解密一般用法:发送方--图片加密过后发送到微信;接收方--收到微信图片右键保存!!--放到本软件解密 ") # 新增一个文本框控件 self.text = QtWidgets.QTextEdit(window) self.text.setGeometry(QtCore.QRect(50, 30, winWidth / 2, winHeigh / 4)) # 调整文本框的位置大小 self.text.installEventFilter(window) # 添加加密按钮和单击事件 self.enBtn = QtWidgets.QPushButton(window) self.enBtn.move(50, winHeigh / 3) # 设置按钮的位置,x坐标,y坐标 self.enBtn.setText("打开图片") # 设置按钮的文字 self.enBtn.clicked.connect(self.openImage) # 为按钮添加单击事件 # 添加加密按钮和单击事件 self.enBtn = QtWidgets.QPushButton(window) self.enBtn.move(200, winHeigh / 3) # 设置按钮的位置,x坐标,y坐标 self.enBtn.setText("加密") # 设置按钮的文字 self.enBtn.clicked.connect(self.handleEnBtn) # 为按钮添加单击事件 # 添加解密按钮和单击事件 self.deBtn = QtWidgets.QPushButton(window) self.deBtn.move(350, winHeigh / 3) # 设置按钮的位置,x坐标,y坐标 self.deBtn.setText("解密") # 设置按钮的文字 self.deBtn.clicked.connect(self.handleDeBtn) # 为按钮添加单击事件 # 获取剪切板 # txt = getClipboardData() # txt=txt.strip().replace('\r\n',' ').replace('\r',' ').replace('\n',' ') # print(txt) # 初始化数据 # self.text.setPlainText(txt) # 注册退出按钮 self.shortcut = QShortcut(QKeySequence("ESC"), self) self.shortcut.activated.connect(appExit) # 注册退出按钮 MAC self.shortcut = QShortcut(QKeySequence("meta+w"), self) self.shortcut.activated.connect(appExit) window.show()
pickRandomShape() for r in range(5, 200, 20): drawShape(r) #Clear the canvas: select all -> delete def clear_Canvas(): moveToCenter() pyautogui.click() found = locate_Click('SelectMenu.png') if not found: locate_Click('SelectMenu2.png') pyautogui.press(['down', 'down', 'down']) pyautogui.press('enter') pyautogui.press('delete') hk = SystemHotkey() hk.register(('control', 'x'), callback=abort) hk.register(('control', 'f'), callback=loc_helper) #Playing around with looking up a function in a dict def totalRandomDrawing(): funcdict = {draw_Concentric(), drawRandWeb(), drawCircle(), drawShield()} random.choice(list(funcdict)) if __name__ == "__main__": totalRandomDrawing()
# [sg.Text("Sensitivity %")], # [sg.Slider(range = (0, 100),orientation="h",default_value=80,key="-SENSITIVTY-")], [sg.Text("Input")], [sg.Combo(b.get_io_devices()[0],readonly=True,default_value=b.get_io_devices()[0][0],key="-INPUT-")], [sg.Text("Output")], [sg.Combo(b.get_io_devices()[1],readonly=True,default_value=b.get_io_devices()[1][0],key="-OUTPUT-")], [sg.Text("Output 2")], [sg.Combo(["Disabled"] + b.get_io_devices()[1],readonly=True,default_value="Disabled",key="-OUTPUT2-")], [sg.Text("Say manually")], [sg.Input(key="-MANUAL-"),sg.Button("Say")], [sg.Button('Ok'), sg.Button('Quit')] ] # Create the window window = sg.Window('sttttts', layout,icon="logos\\icon.ico") hk = SystemHotkey() hk.register(('control', 'q'), callback=lambda x:b.main(None,None,None)) hk.register(('alt', 'q'), callback=lambda x:b.repeat(None,None)) # Display and interact with the Window using an Event Loop while True: event, values = window.read() # See if user wants to quit or window was closed if event == sg.WINDOW_CLOSED or event == 'Quit': break devices = b.get_io_devices() wanted_input = devices[0].index(values["-INPUT-"]) wanted_output = devices[1].index(values["-OUTPUT-"]) + len(devices[0]) if values["-OUTPUT2-"] == "Disabled": wanted_output2 = None else: wanted_output2 = devices[1].index(values["-OUTPUT2-"]) + len(devices[0])
class ShkAdapterMixin(QObject): ''' Minimal interface adapter for global hotkeys ''' # This class may seem confusing at first. The complexity is due to Qt. # Qt's system doesn't like it when qt functions are preformed on anything # other than the main thread. This is a problem for system hotkey, which # always invokes callbacks on a different thread. So, this class sets up # a Qt signal and slot, and uses this to marshal the SHK callback onto # the main Qt thread, which then invokes the command bound to the hotkey. # Key points: _hotkeyPressed receives callback from SHK. It emits # _commandInvoked with the name of the command. _invokeCommand is # connected to this signal. It receives the command name, looks up # the *actual* command callback in the dictionary and invokes it. # Signal that indicates when a command-invoking hotkey was pressed _commandInvoked = pyqtSignal(str) def __init__(self): super().__init__() self.hk = SystemHotkey(consumer=self._hotkeyPressed) self._commandInvoked.connect(self.invokeCommand) #enddef def _hotkeyPressed(self, event, hotkey, args): ''' Adapts the global callback from system hotkey into a signal ''' self._commandInvoked.emit(args[0][0]) #enddef def load(self): super().load() self.applyHotkeys() #enddef def _bind(self, seq, cmd): ''' Binds a hotkey to a command name. seq can either be a QKeySequence or a string parseable by QKeySequence eg "ctrl+shift+k" ''' try: seq = QKeySequence(seq) except: pass t = seqToTuple(seq) log.debug('Binding hotkey "{hotkey}" => "{command}"', hotkey=seq.toString(), command=cmd) try: self.hk.register(t, cmd) except SystemRegisterError: log.exception('Failed to bind hotkey "{hotkey}"', hotkey=seq.toString()) else: return True #endtry return False #enddef def _unbind(self, seq, quiet=False): ''' Removes a hotkey binding. If Quiet is true, will not warn if the binding doesn't exist ''' try: seq = QKeySequence(seq) except: pass t = seqToTuple(seq) log.debug('Unbinding hotkey "{hotkey}"', hotkey=seq.toString()) try: self.hk.unregister(t) except UnregisterError: if not quiet: log.warn('Tried to unbind nonexistent hotkey "{hotkey}"', hotkey=seq.toString()) else: return True #endtry return False #enddef # TODO: These should directly use QKeySequence in the config def commandHasHotkey(self, command): ''' Checks if the given command has a hotkey registered for it ''' return not self.hotkeyForCommand(command).isEmpty() #enddef def hotkeyForCommand(self, command): for seq, cmd in config.default.get('hotkeys', {}).items(): if cmd == command: return QKeySequence(seq) #endfor return QKeySequence() #enddef def hasHotkey(self, seq): try: seq = QKeySequence(seq) except: pass return seq.toString() in config.default.get('hotkeys', {}) #enddef def add(self, seq, command): ''' Add a new hotkey with with a command name intended to be saved to the config ''' try: seq = QKeySequence(seq) except: pass seq = seq.toString( ) # TODO: Removed this (use kyseq directly). UPDATE LOGS when you do (toString) hks = config.default.get('hotkeys', {}) if seq in hks: log.warning('Reassigning existing sequence "{hotkey}"', hotkey=seq) #endif hks[seq] = command config.default.set('hotkeys', hks) config.default.save() # TODO: Move this to settings UI? log.debug('Attempting to bind "{sequence}"', sequence=seq) if command not in self.commands: log.warning( 'Saved hotkey "{hotkey}" to unknown command "{command}"', hotkey=seq, command=command) #endif return True #enddef def remove(self, seq): ''' Remove a hotkey from the config ''' hks = config.default.get('hotkeys', {}) try: del hks[seq] except KeyError: pass else: return self._unbind(seq) return False #endtry #enddef def applyHotkeys(self): ''' Apply all hotkeys defined in the config ''' log.info('Applying hotkeys') toRemove = [] for hotkey, command in config.default.get('hotkeys', {}).items(): if command in self.commands: self._bind(hotkey, command) else: toRemove.append(hotkey) log.error( 'Tried to bind hotkey "{hotkey}" to unknown command "{command}"', hotkey=hotkey, command=command) #endif #endfor for hotkey in toRemove: self.remove(hotkey) #enddef def removeHotkeys(self): ''' Remove all hotkeys defined in the config ''' log.info('Removing all hotkeys') for hotkey, command in config.default.get('hotkeys', {}).items(): self._unbind(hotkey)
def gui_init(): def get_score(): global last new_game = player_names() if last: if new_game.not_empty(): update_heros(last) else: last = None else: if new_game.not_empty(): clear() g = results('DOTA') render_text(g) show() last = g window.after(1000*60*3, show_heros, g) else: pass def show_heros(g): def render(): if g.enough_heros(): render_img(g) show() key_press('f11') key_press('f11') window.after(4000, render) def raise_above(): window.attributes("-topmost", True) def clear(): for l in img_labels: l.configure(text='', image='') for l in text_labels: l.configure(text='', image='') def loop(): get_score() window.after(3000, loop) def align_right(width, height): screen_width = window.winfo_screenwidth() size = '{}x{}+{}+{}'.format(width, height, screen_width-width, 0) window.geometry(size) window.update() def show(): global is_show align_right(MAX_WIDTH, MAX_HEIGHT) raise_above() is_show = False def hide(): global is_show align_right(0, 0) is_show = True def change_status(event): if is_show: show() else: hide() def init_heros(): with open('dict.txt', 'r', encoding='utf-8') as f: table = list(map(lambda x: x[0:-1].split(' '), f.readlines())) dic = {'default': tk.PhotoImage(file='static\\placehold.png')} for names in table: file_name = names[0] game_name = names[-1] photo = tk.PhotoImage(file='static\\' + file_name + '.png') dic[game_name] = photo dic[file_name] = photo return dic def render_text(game): def render_sco(): img_labels[6].configure(text='天灾', fg=SCO_COLOR) start = 7 for i in range(0, len(game.sco)): text_labels[i + start].configure(text=str(game.sco[i]), fg=SCO_COLOR) def render_sen(): img_labels[0].configure(text='近卫', fg=SEN_COLOR) start = 1 for i in range(0, len(game.sen)): text_labels[i + start].configure(text=str(game.sen[i]), fg=SEN_COLOR) render_sen() render_sco() def render_img(game): def render_sen(): start = 1 for i in range(0, len(game.sen)): hero = game.sen[i].hero if hero: img_labels[i + start].configure(image=HEROS[hero]) else: img_labels[i + start].configure(image=HEROS['default']) def render_sco(): start = 7 for i in range(0, len(game.sco)): hero = game.sco[i].hero if hero: img_labels[i + start].configure(image=HEROS[hero]) else: img_labels[i + start].configure(image=HEROS['default']) render_sen() render_sco() window = tk.Tk() window.title('09小秘书') HEROS = init_heros() img_labels = [] text_labels = [] for i in range(12): img = tk.Label(window, bg='black') img.grid(row=i, column=0) img_labels.append(img) text = tk.Label(window, font=('Microsoft YaHei', 10), anchor=tk.W, bg='black') text.grid(row=i, column=1, sticky=tk.W) text_labels.append(text) hk = SystemHotkey() hk.register(['f3'], callback=change_status) window.config(bg='black') window.overrideredirect(True) window.bind('<Motion>', lambda e: hide()) align_right(MAX_WIDTH, MAX_HEIGHT) window.after(3000, loop) window.mainloop()
buffering=1) #sys.stderr = open(join(config.app_dir,'debug.err.log'), mode='a+', encoding='utf-8', errors='ignore', buffering=1) #not catching sys.stderr using debug.bat to catch just err def suppress_qt_warnings(): environ["QT_DEVICE_PIXEL_RATIO"] = "0" environ["QT_AUTO_SCREEN_SCALE_FACTOR"] = "1" environ["QT_SCREEN_SCALE_FACTORS"] = "1" environ["QT_SCALE_FACTOR"] = "1" suppress_qt_warnings() app = QApplication(sys.argv) vrcf.updatecheck() appWindow = AppWindow() appWindow.show() if (config.useGlobalKeybind): try: hk.register((config.getGlobalKeyBind), callback=lambda x: appWindow.btnCollectAvtr()) except SystemHotkey.InvalidKeyError: vrcl.log("Invalid key combo, using default ctrl+k") hk.register(('control', 'k'), callback=lambda x: appWindow.btnCollectAvtr()) except Exception as e: print(str(e)) sys.exit(app.exec_())
from system_hotkey import SystemHotkey hk = SystemHotkey() hk.register(('control', 'shift', 'h'), callback=lambda: print("Easy!"))
filename = 'temp.png' im = ImageGrab.grab() # im.close() # 显示全屏幕截图 w = MyCapture(im) # im.close() # print(w.myleft,w.mybottom) # 截图结束,恢复主窗口,并删除临时的全屏幕截图文件 # label.config(text='Hello') root.state('normal') # os.remove(filename) # The key combination to check # The currently active modifiers current = set() if __name__ == '__main__': root = Tk() label = Label(root, text="OCR识别中", cursor="plus", relief=RAISED, pady=5, wraplength=500) label.pack() hk = SystemHotkey() hk.register(('control', 'alt', 'w'), callback=capture) root.mainloop()