Esempio n. 1
0
class Systray(QObject):
    trayIconMenu = None

    def __init__(self, parent):
        super().__init__(parent)

        self.trayIconMenu = ContextMenu(None)

        icon = QIcon(":/image/thunder.ico")

        self.trayIcon = QSystemTrayIcon(self)
        self.trayIcon.setIcon(icon)
        self.trayIcon.setContextMenu(self.trayIconMenu)
        self.trayIcon.setVisible(True)

        self.trayIcon.activated.connect(self.slotSystrayActivated)

    @pyqtSlot(QSystemTrayIcon.ActivationReason)
    def slotSystrayActivated(self, reason):
        if reason == QSystemTrayIcon.Context:  # right
            pass
        elif reason == QSystemTrayIcon.MiddleClick:  # middle
            pass
        elif reason == QSystemTrayIcon.DoubleClick:  # double click
            pass
        elif reason == QSystemTrayIcon.Trigger:  # left
            if app.mainWin.isHidden() or app.mainWin.isMinimized():
                app.mainWin.restore()
            else:
                app.mainWin.minimize()
Esempio n. 2
0
File: GUI.py Progetto: L3nn0x/tags
class Icon(QWidget):
    def __init__(self, app, newEntry, listWin):
        super().__init__()
        self.newEntry = newEntry
        self.listWin = listWin
        self.app = app
        self.initUI()

    def initUI(self):
        
        menu = QMenu()
        Ajouter = QAction(QIcon(''), '&Ajouter un tag', menu)
        Ajouter.triggered.connect(self.newEntry.show)
        menu.addAction(Ajouter)

        ouvrir = QAction(QIcon(''), '&Ouvrir', menu)
        ouvrir.triggered.connect(self.listWin.show)
        menu.addAction(ouvrir)

        Quitter = QAction(QIcon(''), '&Quitter', menu)
        Quitter.triggered.connect(self.app.exit)
        menu.addAction(Quitter)

        self.icon = QSystemTrayIcon()
        self.icon.setIcon(QIcon('./icone.png'))
        self.icon.setContextMenu(menu)
        self.icon.show()
Esempio n. 3
0
def main(args=sys.argv):
    NAMESPACE = ' %(module)s.%(name)s.%(funcName)s'
    FORMAT = '%(asctime)s %(levelname)-8s ' + NAMESPACE + ': %(message)s'

    color_handler = create_color_handler(FORMAT)

    LOGFILENAME = os.path.join(os.getenv('HOME'), 'hue_gui.log')
    file_handler = logging.FileHandler(LOGFILENAME, encoding='utf-8')

    logging.basicConfig(level=logging.DEBUG,
                        format=FORMAT,
                        handlers=[color_handler, file_handler])
    log = logging.getLogger(__name__)

    app = QApplication(args)

    trayIcon = QSystemTrayIcon(QIcon(':/icons8-light-on-96.png'), app)

    hueControl = hue.HueControl()
    systray = SystrayApp(hueControl)

    menu = QMenu()
    toggleAction = menu.addAction('on/off')
    toggleAction.triggered.connect(systray.toggleAction)

    colorAction = menu.addAction('color')
    colorAction.triggered.connect(systray.colorAction)

    blueAction = menu.addAction('blue')
    blueAction.triggered.connect(systray.blueAction)

    redAction = menu.addAction('red')
    redAction.triggered.connect(systray.redAction)

    yellowAction = menu.addAction('yellow')
    yellowAction.triggered.connect(systray.yellowAction)

    randomAction = menu.addAction('random')
    randomAction.triggered.connect(systray.randomAction)

    aboutAction = menu.addAction('about')
    aboutAction.triggered.connect(systray.aboutAction)

    exitAction = menu.addAction('Exit')
    exitAction.triggered.connect(systray.exitAction)

    trayIcon.setContextMenu(menu)
    trayIcon.show()

    return_code = app.exec_()

    logging.shutdown()
    return return_code
Esempio n. 4
0
    def __init__(self):
        QtWidgets.QWidget.__init__(self)
        self.initPet()

        # setting menu group
        settings = QMenu("Settings", self)
        settings.setIcon(QIcon("resources/ico/poro.ico"))

        # setting -> draggable
        self.drag_action = QAction("Draggable", self)
        self.drag_action.setCheckable(True)
        self.drag_action.setChecked(DEFAULT_DRAGGABLE)
        self.drag_action.triggered.connect(self.freezeOrNot)

        # setting -> opacity slider
        self.opacity_action = self.initOpacitySlider(QWidgetAction(self))
        settings.addAction(self.drag_action)
        settings.addAction(self.opacity_action)

        # about and exit action
        about_action = QAction(QIcon("resources/ico/poro.ico"), "About", self)
        exit_action = QAction(QIcon("resources/ico/poro.ico"), '&Exit', self)
        about_action.triggered.connect(self.aboutInfo)
        exit_action.triggered.connect(qApp.quit)

        # init the tray_menu
        tray_menu = QMenu(self)
        tray_menu.addMenu(settings)
        tray_menu.addAction(about_action)
        tray_menu.addSeparator()
        tray_menu.addAction(exit_action)

        tray_icon = QSystemTrayIcon(self)
        tray_icon.setIcon(QIcon("resources/ico/poro.ico"))
        tray_icon.setContextMenu(tray_menu)
        tray_icon.show()

        ClientStatus.init()
        self.count_false = 0
        self.has_client_connected = False
        # init thread using to monitor lol client
        self.lol_client_heart_beat_thread = ClientHeartBeat(
            LOL_CLIENT_HEART_BEAT_RATE)
        # client 的监听信号 会发给 self.getClientInfo 这个函数
        self.lol_client_heart_beat_thread.keeper.connect(self.getClientInfo)
        self.thread = QThread()
        # QObject 转 Qthread
        self.lol_client_heart_beat_thread.moveToThread(self.thread)
        self.thread.started.connect(self.lol_client_heart_beat_thread.run)
        self.thread.start()

        # when the signal got new position, send to ImgCatcher
        self.client_info_sender.connect(statusChange)
Esempio n. 5
0
    def set_tray_icon(self):
        tray_icon = QSystemTrayIcon()
        menu = QMenu()

        open_action = menu.addAction('Open')
        exit_action = menu.addAction('Exit')
        open_action.triggered.connect(self._window.showNormal)
        exit_action.triggered.connect(sys.exit)

        tray_icon.setIcon(QIcon(':/resource/resources/icons/system_tray.ico'))
        tray_icon.setContextMenu(menu)
        tray_icon.show()
Esempio n. 6
0
class MainWindow(QMainWindow):
    tray_icon = None

    def __init__(self):
        QMainWindow.__init__(self)
        self.tray_icon = QSystemTrayIcon(self)
        self.tray_icon.setIcon(QIcon('icon.png'))
        self.hide()

        central_widget = QWidget(self)
        self.setCentralWidget(central_widget)

        quit_action = QAction("quit", self)
        quit_action.triggered.connect(qApp.quit)
        tray_menu = QMenu()
        tray_menu.addAction(quit_action)

        self.tray_icon.setContextMenu(tray_menu)
        self.tray_icon.show()

        self.pouple = Pouple()
        self.history = History()
        self.bind_keys()

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.tray_icon.hide()

    def command(self, cmd):
        def execute():
            print(cmd.__name__)
            self.history.add(cmd)
            cmd()

        return execute

    def bind_keys(self):
        cfg = configparser.RawConfigParser()
        cfg.read('settings.cfg')

        hot_keys = {
            'align_left': self.pouple.align_left,
            'align_right': self.pouple.align_right,
            'align_top': self.pouple.align_top,
            'align_bottom': self.pouple.align_bottom,
            'center': self.pouple.center,
            'screen': self.pouple.screen,
            'fullscreen': self.pouple.fullscreen,
            'undo': self.history.undo,
            'redo': self.history.redo,
        }
        for name in hot_keys:
            keyboard.add_hotkey(cfg.get('keys', name), self.command(hot_keys[name]))
    def __init__(self):
        super().__init__()
        loadUi(get_file_realpath("kdDesktopAssistant.ui"), self)
        icon = QIcon(get_file_realpath('data/image/logo.png'))
        self.setWindowIcon(icon)
        self.setWindowFlag(Qt.FramelessWindowHint)
        
#         self.setStyleSheet("#MainWindow{border-image:url("+get_file_realpath("data/image/S60922-232113.jpg").replace("\\","/") +");}")
        self.gl_apps.setAlignment(Qt.AlignTop)
        
#         右键菜单设置
        self.pop_menu = QMenu()
#         TODO 待实现的右键功能:QAction("导出配置"),QAction("导入配置")
        self.pop_menu_item = [QAction("新增启动项"),QAction("新增桌面"),QAction("设置背景图片"),QAction("修改桌面"),QAction("删除桌面"),QAction("设置为主桌面"),QAction("小程序模式"),QAction("退出")]
        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested[QPoint].connect(self.handle_pop_menu)
        
#         系统托盘
        sys_tray = QSystemTrayIcon(self)
        self.sys_tray = sys_tray
        sys_tray.setIcon(icon)
        sys_tray.activated.connect(self.sys_tray_handler)
        sys_tray_menu = QMenu()
        sys_tray_menu.menu_items   =[ QAction("退出",self,triggered=sys.exit)]
        sys_tray.setContextMenu(sys_tray_menu)
        sys_tray.show()

        self.session_bt_size_policy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.session_btn_size = QSize(100, 25)
#         初始化桌面
        print(QDesktopWidget().screenGeometry().height())
        print(self.gl_apps.geometry().height())
        self.vetical_widget_number = math.floor((QDesktopWidget().screenGeometry().height() - 150) / get_option_int("item_size"))
        self.home_session = get_option_value("home_session")
        self.init_session()
        
#         初始化对话框对象
        self.dl_launch_item_detail = dl_launch_item_detail()
        self.session = session()
        self.wg_catelog = QFrame()
        self.wg_catelog.setWindowFlags(Qt.Popup)
        self.gl_catelog = QGridLayout()
        self.wg_catelog.setLayout(self.gl_catelog)
#         self.gl_catelog.setWindowOpacity(0.5)
#         self.wg_catelog.setAttribute(Qt.WA_TranslucentBackground,True )
        self.wg_catelog.setWindowFlags(Qt.FramelessWindowHint | Qt.Tool)
        self.wg_catelog.setAutoFillBackground(True)
        
#         self.wg_catelog.setStyleSheet("background-image:url("+get_file_realpath("data/image/bg_catelog.gif") + ");background-size:cover;}")
        p = QPalette()
        p.setBrush(QPalette.Background, QBrush(QPixmap(get_file_realpath("data/image/bg_catelog.jpg"))))
        self.wg_catelog.setPalette(p)
 def _createTrayIcon(self):
     trayIcon = QSystemTrayIcon(self.mw)
     ankiLogo = QIcon()
     ankiLogo.addPixmap(QPixmap(":/icons/anki.png"), QIcon.Normal,
                        QIcon.Off)
     trayIcon.setIcon(QIcon.fromTheme("anki", ankiLogo))
     trayMenu = QMenu(self.mw)
     trayIcon.setContextMenu(trayMenu)
     showAction = trayMenu.addAction("Show all windows")
     showAction.triggered.connect(self.showAll)
     trayMenu.addAction(self.mw.form.actionExit)
     trayIcon.activated.connect(self.onActivated)
     return trayIcon
Esempio n. 9
0
 def init_tray(self):
     tray = QSystemTrayIcon()
     # 设置图标
     tray.setIcon(QIcon("E:\pypro\chat\client\res\icon\setting.png"))
     # 托盘菜单
     tray_menu = QMenu()
     # 增加动作
     tray_menu.addAction(QAction("还原", self, triggered=self.showNormal))
     tray_menu.addAction(QAction("退出", self, triggered=self.close))
     # 应用菜单
     tray.setContextMenu(tray_menu)
     # 显示托盘
     tray.show()
Esempio n. 10
0
class StayAwakeApp(QtWidgets.QMainWindow):
    def __init__(self):
        super(StayAwakeApp, self).__init__()
        self.ui = StayAwake.Ui_MainWindow()
        self.ui.setupUi(self)
        self.ui.label_2.setPixmap(QtGui.QPixmap(":icons/32x32.png"))    # set logo in app window (workaround for pyinstaller
        self.ui.toggle.clicked.connect(self.togglePressed)  # listener for when toggle button is pressed

        self.running = False  # flag to check if program is on or off
        self.preventSleep = None  # initializing to hold PreventSleep instance
        self.trayIcon = None  # initializing to hold tray icon instance

        self.setupTray()  # setup tray icon and menu


    # setup tray icon and menu
    def setupTray(self):
        self.trayIcon = QSystemTrayIcon(self)  # instance of QSystemTrayIcon
        self.trayIcon.setIcon(QIcon(":icons/StayAwakeOpaque.ico"))  # set tray icon image

        openAction = QAction("Open", self)  # "open" right click option in tray
        quitAction = QAction("Quit", self)  # "quit" right click option in tray
        openAction.triggered.connect(self.show)  # open app trigger
        quitAction.triggered.connect(qApp.quit)  # quit app trigger
        trayMenu = QMenu()  # QMenu class instance
        trayMenu.addAction(openAction)  # add open action
        trayMenu.addAction(quitAction)  # add quit action
        self.trayIcon.setContextMenu(trayMenu)  # sets menu actions
        self.trayIcon.show()  # makes tray icon visible

    # handle toggle button states and calling prevent sleep
    def togglePressed(self):
        if self.running:
            self.ui.toggle.setText("Off")  # set toggle button text to "Off"
            self.running = False  # update state
            self.preventSleep.terminate()  # terminate prevent sleep thread
        else:
            self.ui.toggle.setText("On")  # set toggle button text to "On"
            self.running = True  # update state
            self.preventSleep = PreventSleep()  # create instance of PreventSleep class
            self.preventSleep.start()  # start prevent sleep thread

    # making "minimize" button minimizes to tray instead of taskbar
    def changeEvent(self, event):
        if event.type() == QtCore.QEvent.WindowStateChange:
            if self.windowState() & QtCore.Qt.WindowMinimized:  # if minimize button is pressed
                event.ignore()  # ignore "minimize to taskbar" event
                self.hide()  # hide the window
                self.trayIcon.show()  # show tray icon
                self.trayIcon.showMessage("Stay Awake", "Stay Awake was minimized to tray.",
                                          QSystemTrayIcon.Information)  # show tray message popup
Esempio n. 11
0
def main():

    d = getDateTime()

    # Global app
    app = QApplication(sys.argv)

    QApplication.setQuitOnLastWindowClosed(False)
    qIcon = QIcon('icons/shotty.png')
    app.setWindowIcon(qIcon)

    shotty = ShottyFullscreen()

    showNotification('Shotty', 'Running in the background')

    tray = QSystemTrayIcon()
    if tray.isSystemTrayAvailable():
        tray.setIcon(QIcon('icons/shotty.png'))
        tray.setVisible(True)
        tray.show()

        # Add a menu
        trayMenu = QMenu()
        region_screenshot_action = QAction(QIcon("icons/screenshot.png"),
                                           'Take region screenshot')
        full_screenshot_action = QAction(QIcon("icons/screenshot.png"),
                                         'Take screenshot')
        settings_action = QAction(QIcon("icons/settings.png"), 'Settings')
        about_action = QAction(QIcon("icons/info.png"), 'About')
        exit_action = QAction(QIcon("icons/exit.png"), 'Exit Shoty')

        exit_action.triggered.connect(app.exit)
        about_action.triggered.connect(shotty.showShottyAboutWindow)
        region_screenshot_action.triggered.connect(shotty.initUI)
        # We need to pass checked because connect passes
        # a bool arg as first param
        full_screenshot_action.triggered.connect(
            lambda checked, date=getDateTime(
            ), x1=-1, y1=-1, x2=-1, y2=-1, im=screenshot(
            ): shotty.saveScreenShot(date, x1, y1, x2, y2, im=im[:, :, :3]))
        trayMenu.addAction(region_screenshot_action)
        trayMenu.addAction(full_screenshot_action)
        trayMenu.addAction(settings_action)
        trayMenu.addAction(about_action)
        trayMenu.addAction(exit_action)

        tray.setContextMenu(trayMenu)
    else:
        print("[ERROR] Can't instantiate tray icon")

    sys.exit(app.exec_())
Esempio n. 12
0
class ProgramTray(QtCore.QThread):
    def __init__(self, icon):
        QtCore.QThread.__init__(self)
        self.menu = QMenu()
        self.icon = QSystemTrayIcon(QtGui.QIcon(icon))
        self.flag_exit = True
        self.first = True

    def run(self):
        if chrome_cheker():
            p1 = Popen(
                '"{}" --remote-debugging-port=9222 & exit'.format(chrome_path),
                shell=True,
                stdout=PIPE)
            time.sleep(2)
            p1.kill()
            try:
                bot.delete_webhook()
                bot.polling(none_stop=True)
            except:
                bot.send_message(white_list[0], 'Программа выключенна. Сбой')
        else:
            if self.first:
                self.first = False
                bot.send_message(
                    white_list[0],
                    'Полностью закройте Chrome и запустите программу')
        print('Кажется я умираю')
        QApplication.quit()

    def stop(self):
        QApplication.quit()

    def setMenu(self, menu=None):
        if not menu:
            menu = []
        collection = OrderedDict(menu)
        items = collection.keys()
        functions = collection.values()

        for i, item in enumerate(items):
            function = functions[i]

            if isinstance(function, types.MethodType) \
                or isinstance(function, types.FunctionType):
                self.menu.addAction(QAction(item, self, triggered=function))

        self.quitAction = QAction("Exit", self, triggered=self.stop)
        self.menu.addAction(self.quitAction)

        self.icon.setContextMenu(self.menu)
Esempio n. 13
0
class TrayIcon(QApplication):
    """System tray icon, Qt version."""
    def __init__(self, icon, fallback_icon_path, **kwargs):
        """Create a TrayIcon instance."""
        QApplication.__init__(self, sys.argv)
        self._fallback_icon = QIcon(fallback_icon_path)
        self._icon = QIcon.fromTheme(icon, self._fallback_icon)
        self.tray_icon = QSystemTrayIcon()
        self.tray_icon.setIcon(self._icon)

        self.menu = SubMenu()
        self.tray_icon.setContextMenu(self.menu)
        self.tray_icon.show()

    def loop(self, tk_window):
        """Update Qt GUI inside tkinter mainloop."""
        self.processEvents()
        tk_window.loop_id = tk_window.after(10, self.loop, tk_window)

    def change_icon(self, icon, desc=''):
        """Change icon."""
        del self._icon
        self._icon = QIcon(icon)
        self.tray_icon.setIcon(self._icon)

    def bind_left_click(self, command):
        """Bind command to left click on the icon."""
        def action(reason):
            """Execute command only on left click (not when the menu is displayed)."""
            if reason == QSystemTrayIcon.Trigger:
                command()

        self.tray_icon.activated.connect(action)

    def bind_middle_click(self, command):
        """Bind command to middle click on the icon."""
        def action(reason):
            """Execute command only on middle click (not when the menu is displayed)."""
            if reason == QSystemTrayIcon.MiddleClick:
                command()

        self.tray_icon.activated.connect(action)

    def bind_double_click(self, command):
        """Bind command to double left click on the icon."""
        def action(reason):
            """Execute command only on double click (not when the menu is displayed)."""
            if reason == QSystemTrayIcon.DoubleClick:
                command()

        self.tray_icon.activated.connect(action)
Esempio n. 14
0
class App(QWidget):
    def __init__(self):
        super().__init__()
        self.move(180, 100)
        self.setFixedSize(400, 300)
        self.setWindowTitle('control')

        self.server = threading.Thread(target=server)

        self.toclose = False
        self.all_buttons = []

        self.start_button = QPushButton('start/stop', parent=self)
        self.start_button.setGeometry(100, 100, 200, 100)
        self.start_button.action = 'start'
        self.all_buttons.append(self.start_button)

        for i in self.all_buttons:
            i.clicked.connect(self.onClick)

        show_action = QAction("Show", self)
        quit_action = QAction("Exit", self)
        show_action.triggered.connect(self.show)
        quit_action.triggered.connect(qApp.quit)

        tray_menu = QMenu()
        tray_menu.addAction(show_action)
        tray_menu.addAction(quit_action)

        self.tray_icon = QSystemTrayIcon(self)
        self.tray_icon.setIcon(self.style().standardIcon(
            QStyle.SP_ComputerIcon))
        self.tray_icon.setContextMenu(tray_menu)
        self.tray_icon.show()

    def onClick(self):
        btn = self.sender().action
        print(btn, 'action released!')
        if btn == 'start':
            if not self.server.is_alive():
                self.server.start()
                self.start_button.setEnabled(0)
                self.start_button.setText('server running')

    def closeEvent(self, evnt):
        if self.toclose:
            super(App, self).closeEvent(evnt)
        else:
            evnt.ignore()
            self.hide()
Esempio n. 15
0
class TrayIcon(QApplication):
    def __init__(self, icon):
        QApplication.__init__(self, sys.argv)
        # Init QSystemTrayIcon
        self.icon = QIcon(icon)
        self.tray_icon = QSystemTrayIcon()
        self.tray_icon.setIcon(self.icon)

        self.menu = QMenu()
        self.menu_items = []
        self.tray_icon.setContextMenu(self.menu)
        self.tray_icon.show()

    def add_menu_separator(self):
        self.menu.addSeparator()

    def add_menu_item(self, label="", command=None):
        action = QAction(label, self.tray_icon)
        action.triggered.connect(lambda *args: command())
        self.menu.addAction(action)
        self.menu_items.append(action)

    def loop(self, tk_window):
        self.processEvents()
        tk_window.loop_id = tk_window.after(10, self.loop, tk_window)

    def change_icon(self, icon, desc):
        del self.icon
        self.icon = QIcon(icon)
        self.tray_icon.setIcon(self.icon)

    def get_item_label(self, item):
        return self.menu_items[item].text()

    def set_item_label(self, item, label):
        self.menu_items[item].setText(label)

    def disable_item(self, item):
        self.menu_items[item].setDisabled(True)

    def enable_item(self, item):
        self.menu_items[item].setDisabled(False)

    def bind_left_click(self, command):
        def action(reason):
            """Execute command only on click (not when the menu is displayed)."""
            if reason == QSystemTrayIcon.Trigger:
                command()

        self.tray_icon.activated.connect(action)
class Tray:  # create tray icon menu
    def __init__(self, ):
        # create systemtray UI
        self.icon = QIcon(ico)
        self.tray = QSystemTrayIcon()
        self.tray.setIcon(self.icon)
        self.tray.setToolTip("Now Playing ▶")
        self.tray.setVisible(True)
        self.menu = QMenu()

        # create systemtray options and actions
        self.actTitle = QAction("Now Playing v1.4")
        self.menu.addAction(self.actTitle)
        self.actTitle.setEnabled(False)

        self.actConfig = QAction("Settings")
        self.actConfig.triggered.connect(win.show)
        self.menu.addAction(self.actConfig)
        self.menu.addSeparator()

        self.actPause = QAction()
        self.actPause.triggered.connect(self.pause)
        self.menu.addAction(self.actPause)
        self.actPause.setEnabled(False)

        self.actExit = QAction("Exit")
        self.actExit.triggered.connect(self.cleanquit)
        self.menu.addAction(self.actExit)

        # add menu to the systemtray UI
        self.tray.setContextMenu(self.menu)

    def unpause(self):  # unpause polling
        global paused
        paused = 0
        self.actPause.setText('Pause')
        self.actPause.triggered.connect(self.pause)

    def pause(self):  # pause polling
        global paused
        paused = 1
        self.actPause.setText('Resume')
        self.actPause.triggered.connect(self.unpause)

    def cleanquit(self):  # quit app and cleanup
        self.tray.setVisible(False)
        file = ConfigFile(config, config_file).file
        if file:
            writetrack(file)
        sys.exit()
Esempio n. 17
0
class TrayWindow(QDialog):
    def __init__(self, main_window, *args, **kwargs):
        super(TrayWindow, self).__init__(*args, **kwargs)

        self.createActions()
        self.createTrayIcon()

        self.trayIcon.show()

        self.settingsWindow = main_window

    def createActions(self):
        self.settingsAction = QAction("Settings", self, triggered=self.showSettings)
        self.quitAction = QAction("Quit", self, triggered=QApplication.instance().quit)

    def createTrayIcon(self):
        self.trayIconMenu = QMenu(self)
        self.trayIconMenu.addAction(self.settingsAction)
        self.trayIconMenu.addSeparator()
        self.trayIconMenu.addAction(self.quitAction)

        self.trayIcon = QSystemTrayIcon(self)
        self.trayIcon.setContextMenu(self.trayIconMenu)

        self.trayIcon.activated.connect(self.iconActivated)

        icon = QIcon(getResource("speechOn.png"))
        self.trayIcon.setIcon(icon)
        self.setWindowIcon(icon)

        self.trayIcon.setToolTip("MicroCommander")

    def iconActivated(self, reason):
        self.showNotification("Micro commander", "Status: running")

    def showSettings(self):
        self.settingsWindow.show()

    @staticmethod
    def showNotification(title, body):
        trayIcon = QSystemTrayIcon()
        trayIcon.setIcon(QIcon(getResource("speech.png")))
        trayIcon.show()
        icon = QSystemTrayIcon.MessageIcon(QSystemTrayIcon.Information)
        trayIcon.showMessage(title, body, icon)

    @staticmethod
    def show_message(tray, title, body):
        icon = QSystemTrayIcon.MessageIcon(QSystemTrayIcon.Information)
        tray.showMessage(title, body, icon)
Esempio n. 18
0
class tray():
    
    def __init__(self):
        super().__init__()
        self.initUI()
    
    def turn_off(self,device):
        is_list = isinstance(device,list)
        if is_list == False:
            return device.turn_off()
        else:
            return [i.turn_off() for i in device]

    def turn_on(self,device):
        is_list = isinstance(device,list)
        if is_list == False:
            return device.turn_on()
        else:
            return[ i.turn_on() for i in device] 
    
    def initUI(self):
        self.app = QApplication(sys.argv)
        api.init('LOGIN','PASSWORD',"44","tuya")
        self.device_ids = api.get_all_devices()
        self.devices = dict((i.name(),i) for i in self.device_ids if i.obj_type == 'light' or i.obj_type == 'switch')
        self.lights = dict((i.name(),i) for i in self.device_ids if i.obj_type == 'light')
        self.devices['All Lights'] = list(self.lights.values())
        self.tray_icon = QSystemTrayIcon(QIcon('lightbulb.png'),parent=self.app)
        self.tray_icon.setToolTip('Tuya - Lights')
        self.menu = QMenu()
        self.menus = dict()
        self.buttons = dict()

        for j in self.devices.keys():
            self.menus[f"{j}_Action"] = self.menu.addMenu(j)
            self.menus[f"{j}_Action"].addAction('On')
            self.menus[f"{j}_Action"].addAction('Off')
            self.buttons = self.menus[f"{j}_Action"].actions()
            for i in self.buttons:
                if i.iconText() == 'On':
                    i.triggered.connect(partial(self.turn_on,self.devices[j]))
                elif i.iconText() == 'Off':
                    i.triggered.connect(partial(self.turn_off,self.devices[j]))

        self.exitaction = self.menu.addAction('Exit')
        self.exitaction.triggered.connect(self.app.quit)
        self.tray_icon.setContextMenu(self.menu)
        self.tray_icon.show()
        self.app.exec_()
        sys.exit(self.app.exec_())
Esempio n. 19
0
class Main(QDialog):
    def __init__(self):
        super().__init__()
        self.loadMenu()
        self.initUI()

    def loadMenu(self):
        menuItems = []  # 菜单列表
        menuItems.append({
            "text": "启动",
            "icon": "./icons/set.png",
            "event": self.show,
            "hot": "D"
        })
        menuItems.append({
            "text": "退出",
            "icon": "./icons/close.png",
            "event": self.close,
            "hot": "Q"
        })
        self.trayIconMenu = QMenu(self)  # 创建菜单
        #遍历绑定 显示的文字、图标、热键和点击事件
        #热键可能是无效的 我这里只是为了显示效果而已
        for i in menuItems:
            tmp = QAction(QIcon(i["icon"]),
                          i["text"],
                          self,
                          triggered=i["event"])
            tmp.setShortcut(self.tr(i["hot"]))
            self.trayIconMenu.addAction(tmp)

    def initUI(self):
        self.trayIcon = QSystemTrayIcon(self)  # <===创建通知栏托盘图标
        self.trayIcon.setIcon(QIcon("./joyrun/request/pic.ico"))  #<===设置托盘图标

        self.trayIcon.setContextMenu(self.trayIconMenu)  #<===创建右键连接菜单
        self.trayIcon.show()  #<====显示托盘

        self.setWindowIcon(QIcon("./joyrun/request/pic.ico"))  #<===设置窗体图标
        self.setGeometry(300, 300, 180, 300)  # <===设置窗体打开位置与宽高
        self.setWindowTitle('窗体标题')

        self.show()  #<====显示窗体
        # self.hide()#<====隐藏窗体
        # 默认不显示窗体

    # 重写窗体关闭事件,让其点击关闭时隐藏
    def closeEvent(self, event):
        if self.trayIcon.isVisible():
            self.trayIcon.hide()
Esempio n. 20
0
class systemTray(QObject):
    cs = check_service

    def start_tray(self, ns, ip):
        # Initialize QApplication
        self.app = QApplication([])
        self.app.setQuitOnLastWindowClosed(False)

        # Check service status
        ipc, state = self.cs(ns, ip)

        # Set icon
        icon = QIcon(srcdir + ipc)
        self.tray = QSystemTrayIcon()
        self.tray.setIcon(icon)
        self.tray.setVisible(True)
        self.tray.setToolTip(ns + " is " + state)

        # Set menu
        self.menu = QMenu()
        self.quit = QAction("Exit")
        self.quit.triggered.connect(self.app.quit)
        self.menu.addAction(self.quit)

        # Add menu to tray
        self.tray.setContextMenu(self.menu)

        # Create thread
        self.thread = QThread()
        # Create object which will be moved from main thread to worker thread
        self.worker = worker(ns, ip)
        # Move object to worker thread
        self.worker.moveToThread(self.thread)
        # Connect object to signal
        self.worker.newIcon.connect(self.updateIcon)
        self.worker.newToolTip.connect(self.updateToolTip)
        # Connect started signal to run method of object in worker thread
        self.thread.started.connect(self.worker.run)
        # Start thread
        self.thread.start()

        # Run tray
        self.app.exec_()

    def updateIcon(self, icon):
        self.tray.setIcon(icon)

    def updateToolTip(self, tooltip):
        self.tray.setToolTip(tooltip)
Esempio n. 21
0
class TrayIcon(QWidget): #child class name
    def __init__(self): #class constructor
        super().__init__(); #inheritance from parent attributes

        self.tray=QSystemTrayIcon(QtGui.QIcon('chidalu.jpg')); #create a systemtrayicon
        self.tray.setToolTip('Click Me'); #set tooltip of trayicon
        self.tray.show(); #show trayicon

        menu=QMenu(self); #create a menu object

        exitAction=QAction('Exit'); #create an exit action
        exitAction.triggered.connect(app.quit); #connect a signal to a slot
        menu.addAction(exitAction); #add action to menu

        self.tray.setContextMenu(menu); #set context menu of trayicon
Esempio n. 22
0
	def init_tray(self, app):
		actions = {
			self.open_action: self.show,
			self.hide_action: self.hide,
			self.close_action: self.quit_app
		}
		tray_menu = QMenu()
		for key, value in actions.items():

			# noinspection PyUnresolvedReferences
			key.triggered.connect(value)
			tray_menu.addAction(key)
		tray_icon = QSystemTrayIcon(self.settings.app_icon(), app)
		tray_icon.setContextMenu(tray_menu)
		return tray_icon
Esempio n. 23
0
def apiTray():
    app = QtWidgets.QApplication(sys.argv)
    scriptDir = os.path.dirname(os.path.realpath(__file__))
    trayIcon = QSystemTrayIcon(QtGui.QIcon(scriptDir + "/resources/logo.png"))
    trayIcon.setToolTip("AmazonWatch")
    trayIcon.show()
    menu = QMenu()
    openAction = menu.addAction("Open GUI")
    openAction.triggered.connect(startGuiProcess)
    menu.addSeparator()
    actionGithub = menu.addAction("Visit Github")
    actionGithub.triggered.connect(openBrowser)
    menu.addSeparator()
    exitAction = menu.addAction("Exit")
    exitAction.triggered.connect(app.quit)
    trayIcon.setContextMenu(menu)
    sys.exit(app.exec_())
Esempio n. 24
0
 def set_tray(self):
     tray_icon = QSystemTrayIcon(self)
     icon = QIcon("icon.png")
     tray_icon.setIcon(icon)
     show_action = QAction("Показать", self)
     quit_action = QAction("Выйти", self)
     hide_action = QAction("Спрятать", self)
     show_action.triggered.connect(self.show)
     hide_action.triggered.connect(self.hide)
     quit_action.triggered.connect(self.close)
     tray_menu = QMenu()
     tray_menu.addAction(show_action)
     tray_menu.addAction(hide_action)
     tray_menu.addAction(quit_action)
     tray_icon.setContextMenu(tray_menu)
     tray_icon.show()
     tray_icon.setToolTip('Address book')
Esempio n. 25
0
 def set_tray(self):
     tray_icon = QSystemTrayIcon(self)
     icon = QIcon("icon.png")
     tray_icon.setIcon(icon)
     show_action = QAction("Show", self)
     quit_action = QAction("Exit", self)
     hide_action = QAction("Hide", self)
     show_action.triggered.connect(self.show)
     hide_action.triggered.connect(self.hide)
     quit_action.triggered.connect(self.close)
     tray_menu = QMenu()
     tray_menu.addAction(show_action)
     tray_menu.addAction(hide_action)
     tray_menu.addAction(quit_action)
     tray_icon.setContextMenu(tray_menu)
     tray_icon.show()
     tray_icon.setToolTip('Solar combine')
Esempio n. 26
0
class SystemTray(QWidget):
    def __init__(self, parent=None):
        super(SystemTray, self).__init__(parent)
        self.tray_icon_menu = QMenu(self)
        self.tray_icon = QSystemTrayIcon(self)
        self.tray_icon.setContextMenu(self.tray_icon_menu)
        self.icon_management = IconManagement(self.tray_icon)
        self.connection_handler = ConnectionHandler(FREQUENCY_CHECK_MS,
                                                    TIME_OUT_CALL_S, self)
        self.connection_handler.value_changed.connect(self.internet_connection)
        self.connection_handler.start()

    def add_action(self, name, triggered_action):
        action = QAction(QCoreApplication.translate(trad_context, name),
                         self,
                         triggered=triggered_action)
        self.tray_icon_menu.addAction(action)

    def add_separator(self):
        self.tray_icon_menu.addSeparator()

    def show(self):
        super(SystemTray, self).show()
        self.tray_icon.show()

    @pyqtSlot()
    def event_started(self):
        self.icon_management.start()

    @pyqtSlot()
    def event_finished(self):
        self.icon_management.stop()

    @pyqtSlot(Exception)
    def conductor_problem(self, e):
        self.notify("Demerio", "There was a problem : %s" % (e, ))
        self.icon_management.conductor_problem()

    @pyqtSlot(bool)
    def internet_connection(self, internet_is_ok):
        if not internet_is_ok:
            self.notify("Demerio", "Internet connection is lost")
        self.icon_management.internet_is_ok(internet_is_ok)

    def notify(self, title, message):
        self.tray_icon.showMessage(title, message, BAR_NOTIFICATION_TIME)
Esempio n. 27
0
class main(UI):
    def __init__(self, parent=None):
        super(UI, self).__init__()
        self.setupUi(parent)
        self.parent = parent

        #print type(self).__name__
        print self.lUsername

        #self.minimizeAction = QAction("Mi&nimize", parent, triggered=parent.hide)
        self.createActions()
        self.createTrayIcon()
        self.setIcon(QIcon(':/images/heart.png'))
        self.trayIcon.show()

        # setup gui events
        self.events()

    def createActions(self):
        #self.minimizeAction = QAction("Mi&nimize", self.parent, triggered=self.parent.hide)
        #self.maximizeAction = QAction("Ma&ximize", self.parent, triggered=self.parent.showMaximized)
        #self.restoreAction = QAction("&Restore", self.parent, triggered=self.parent.showNormal)
        self.quitAction = QAction("&Quit",
                                  self.parent,
                                  triggered=QApplication.instance().quit)

    def createTrayIcon(self):
        self.trayIconMenu = QMenu(self.parent)
        #self.trayIconMenu.addAction(self.minimizeAction)
        #self.trayIconMenu.addAction(self.maximizeAction)
        #self.trayIconMenu.addAction(self.restoreAction)
        #self.trayIconMenu.addSeparator()
        self.trayIconMenu.addAction(self.quitAction)

        self.trayIcon = QSystemTrayIcon(self.parent)
        self.trayIcon.setContextMenu(self.trayIconMenu)

    def setIcon(self, icon):
        self.trayIcon.setIcon(icon)
        self.parent.setWindowIcon(icon)

    def events(self):
        self.bCancelOk.button(self.bCancelOk.Ok).clicked.connect(
            QApplication.instance().quit)
        self.bCancelOk.button(self.bCancelOk.Cancel).clicked.connect(
            QApplication.instance().quit)
Esempio n. 28
0
class AppWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.tray_icon = QSystemTrayIcon(self)
        self.tray_icon.setIcon(self.style().standardIcon(
            QStyle.SP_ComputerIcon))
        show_action = QAction("Show", self)
        quit_action = QAction("Exit", self)
        hide_action = QAction("Hide", self)
        show_action.triggered.connect(self.show)
        hide_action.triggered.connect(self.hide)
        quit_action.triggered.connect(self.close)
        tray_menu = QMenu()
        tray_menu.addAction(show_action)
        tray_menu.addAction(hide_action)
        tray_menu.addAction(quit_action)
        self.tray_icon.setContextMenu(tray_menu)
        self.tray_icon.show()
        self.tray_icon.activated.connect(self.hand_tray_activated)
        self.ui = Control_Panel()
        self.ui.setupUi(self)
        self.setWindowFlags(QtCore.Qt.WindowCloseButtonHint
                            | QtCore.Qt.WindowMinimizeButtonHint)
        self.show()
        self.ui.th.hide_signal.connect(self.minimize_to_tray)

    def hand_tray_activated(self, reason):
        # On double clicking the tray icon the windows is shown again
        if reason == QSystemTrayIcon.DoubleClick:
            self.show()

    def minimize_to_tray(self):
        # when go button is clicked the app is minimized to tray
        self.hide()
        self.tray_icon.showMessage("Hand of The King",
                                   "Application was minimized to tray",
                                   QSystemTrayIcon.Information, 2000)

    def closeEvent(self, event):
        # overriding the closeEvent function of the window to cleanup all open windows and release the camera
        self.tray_icon.hide()
        self.ui.application_on = False
        self.ui.gesture_detector.camera.release()
        self.ui.hand_window.close()
        event.accept()
Esempio n. 29
0
class SystemTray(object):
    # 程序托盘类
    def __init__(self, w):
        self.app = app
        self.w = w
        QApplication.setQuitOnLastWindowClosed(False)  # 禁止默认的closed方法,
        self.w.show()  # 不设置显示则为启动最小化到托盘
        self.tp = QSystemTrayIcon(self.w)
        self.initUI()
        self.run()

    def initUI(self):
        # 设置托盘图标
        self.tp.setIcon(QIcon('/etc/v2rayL/images/logo.ico'))

    def quitApp(self):
        # 退出程序
        self.w.show()  # w.hide() #设置退出时是否显示主窗口
        re = QMessageBox.question(self.w, "提示", "确认退出?",
                                  QMessageBox.Yes | QMessageBox.No,
                                  QMessageBox.No)
        if re == QMessageBox.Yes:
            self.tp.setVisible(False)  # 隐藏托盘控件
            qApp.quit()  # 退出程序
            self.w.v2rayL.disconnect()

    def act(self, reason):
        # 主界面显示方法
        if reason == 2 or reason == 3:
            self.w.show()

    def run(self):
        a1 = QAction('恢复(Show)', triggered=self.w.show)
        a3 = QAction('退出(Exit)', triggered=self.quitApp)
        tpMenu = QMenu()
        tpMenu.addAction(a1)
        tpMenu.addAction(a3)
        self.tp.setContextMenu(tpMenu)
        self.tp.show()  # 不调用show不会显示系统托盘消息,图标隐藏无法调用

        # 绑定提醒信息点击事件
        # self.tp.messageClicked.connect(self.message)
        # 绑定托盘菜单点击事件
        self.tp.activated.connect(self.act)
        sys.exit(self.app.exec_())  # 持续对app的连接
Esempio n. 30
0
    def _create_systemtray(self):
        ''' Create & add systemtray icon with controls. '''
        if self._systemtray:
            return
        systemtray = QSystemTrayIcon(self)
        systemtray.setToolTip(app_data.app_name())
        systemtray.setIcon(QIcon(app_data.app_logo_path()))
        systemtray.setVisible(True)

        menu = QMenu(self)
        about_action = menu.addAction(QIcon(app_data.about_logo_path()), "About")
        about_action.triggered.connect(self._about_clicked)
        exclusions_action = menu.addAction(QIcon(app_data.exclusions_logo_path()), "Exclusions")
        exclusions_action.triggered.connect(self._exclusions_clicked)
        quit_action = menu.addAction(QIcon(app_data.quit_logo_path()), "Quit")
        quit_action.triggered.connect(self._quit_clicked)
        systemtray.setContextMenu(menu)
        self._systemtray = systemtray
Esempio n. 31
0
class AppUi(QtCore.QObject):
    reload_data = QtCore.pyqtSignal()

    def __init__(self, parent, conf, build_icons):
        super(AppUi, self).__init__(parent)
        self.widget = QWidget()
        self.build_icons = build_icons
        self.tray = QSystemTrayIcon(self.build_icons.for_status(None), self.widget)
        self.tray.show()
        self.app_menu = AppMenu(self.widget, conf, self.build_icons)
        self.app_menu.reload_data.connect(self.reload_data)
        self.tray.setContextMenu(self.app_menu.menu)

    def update_projects(self, integration_status):
        count = len(integration_status.get_failing_builds())
        self.tray.setIcon(self.build_icons.for_aggregate_status(integration_status.get_build_status(), count))
        self.app_menu.update(integration_status.get_projects())
        self.tray.setToolTip("Last checked: " + strftime("%Y-%m-%d %H:%M:%S"))
Esempio n. 32
0
class main(QDialog):
	def __init__(self):
		super().__init__()
		self.trayIcon = QSystemTrayIcon(self)  # <===创建通知栏托盘图标
		self.trayIconMenu = QMenu(self)  # 创建菜单
		self.loadMenu()
		self.initUI()

	# self.setWindowFlags(QtCore.Qt.WindowMinimizeButtonHint)
	# self.tray.activated.connect(self.TuoPanEvent) #设置托盘点击事件处理函数
	def loadMenu(self):
		menuItems = [{"text": "启动", "icon": "icons/set.png", "event": self.show, "hot": "D"},
					 {"text": "退出", "icon": "icons/switch.png", "event": self.close, "hot": "Q"}]  # 菜单列表
		# 遍历绑定 显示的文字、图标、热键和点击事件
		# 热键可能是无效的 我这里只是为了显示效果而已
		for i in menuItems:
			tmp = QAction(QIcon(i["icon"]), i["text"], self, triggered=i["event"])
			tmp.setShortcut(self.tr(i["hot"]))
			self.trayIconMenu.addAction(tmp)

	def initUI(self):
		self.trayIcon.setIcon(QIcon("icons/alert.png"))  # <===设置托盘图标
		self.trayIcon.setContextMenu(self.trayIconMenu)  # <===创建右键连接菜单
		self.trayIcon.show()  # <====显示托盘
		# self.trayIcon.setToolTip('aa')
		self.setWindowIcon(QIcon("icons/alert.png"))  # <===设置窗体图标
		self.setGeometry(900, 300, 180, 300)  # <===设置窗体打开位置与宽高
		self.setWindowTitle('订单列表')

	# self.show()  # <====显示窗体

	# self.hide()#<====隐藏窗体
	# 默认不显示窗体

	def close(self):
		sys.exit(0)

	# 重写窗体关闭事件,让其点击关闭时隐藏
	def closeEvent(self, event):
		if self.trayIcon.isVisible():
			self.hide()
			event.ignore()
		else:
			event.accept()
Esempio n. 33
0
class SystemTray(QWidget):

    def __init__(self, parent=None):
        super(SystemTray, self).__init__(parent)
        self.tray_icon_menu = QMenu(self)
        self.tray_icon = QSystemTrayIcon(self)
        self.tray_icon.setContextMenu(self.tray_icon_menu)
        self.icon_management = IconManagement(self.tray_icon)
        self.connection_handler = ConnectionHandler(FREQUENCY_CHECK_MS, TIME_OUT_CALL_S, self)
        self.connection_handler.value_changed.connect(self.internet_connection)
        self.connection_handler.start()

    def add_action(self, name, triggered_action):
        action = QAction(QCoreApplication.translate(trad_context, name), self, triggered = triggered_action)
        self.tray_icon_menu.addAction(action)

    def add_separator(self):
        self.tray_icon_menu.addSeparator()

    def show(self):
        super(SystemTray, self).show()
        self.tray_icon.show()

    @pyqtSlot()
    def event_started(self):
        self.icon_management.start()

    @pyqtSlot()
    def event_finished(self):
        self.icon_management.stop()

    @pyqtSlot(Exception)
    def conductor_problem(self, e):
        self.notify("Demerio", "There was a problem : %s" % (e,))
        self.icon_management.conductor_problem()

    @pyqtSlot(bool)
    def internet_connection(self, internet_is_ok):
        if not internet_is_ok:
            self.notify("Demerio", "Internet connection is lost")
        self.icon_management.internet_is_ok(internet_is_ok)

    def notify(self, title, message):
        self.tray_icon.showMessage(title, message, BAR_NOTIFICATION_TIME)
Esempio n. 34
0
class Systray(QObject):
    app = None
    trayIconMenu = None

    def __init__(self, app):
        super().__init__()
        self.app = app
        self.mainWin = self.app.mainWin

        self.trayIconMenu = QMenu(None)

        icon = QIcon(":/image/thunder.ico")

        self.trayIcon = QSystemTrayIcon(None)
        self.trayIcon.setIcon(icon)
        self.trayIcon.setContextMenu(self.trayIconMenu)
        self.trayIcon.setVisible(True)

        self.trayIcon.activated.connect(self.slotSystrayActivated)
        self.app.lastWindowClosed.connect(self.slotTeardown)

        self.trayIconMenu.addAction(self.mainWin.action_exit)

    @pyqtSlot()
    def slotTeardown(self):
        print("teardown Systray")
        # On Ubuntu 13.10, systrayicon won't destroy itself gracefully, stops the whole program from exiting.
        del self.trayIcon

    @pyqtSlot(QSystemTrayIcon.ActivationReason)
    def slotSystrayActivated(self, reason):
        if reason == QSystemTrayIcon.Context: # right
            pass
        elif reason == QSystemTrayIcon.MiddleClick: # middle
            pass
        elif reason == QSystemTrayIcon.DoubleClick: # double click
            pass
        elif reason == QSystemTrayIcon.Trigger: # left
            if self.mainWin.isHidden() or self.mainWin.isMinimized():
                self.mainWin.restore()
            else:
                self.mainWin.minimize()
Esempio n. 35
0
class Window(QDialog):
    def __init__(self):
        super(Window, self).__init__()

        self.createIconGroupBox()
        self.createMessageGroupBox()

        self.iconLabel.setMinimumWidth(self.durationLabel.sizeHint().width())

        self.createActions()
        self.createTrayIcon()

        self.showMessageButton.clicked.connect(self.showMessage)
        self.showIconCheckBox.toggled.connect(self.trayIcon.setVisible)
        self.iconComboBox.currentIndexChanged.connect(self.setIcon)
        self.trayIcon.messageClicked.connect(self.messageClicked)
        self.trayIcon.activated.connect(self.iconActivated)

        mainLayout = QVBoxLayout()
        mainLayout.addWidget(self.iconGroupBox)
        mainLayout.addWidget(self.messageGroupBox)
        self.setLayout(mainLayout)

        self.iconComboBox.setCurrentIndex(1)
        self.trayIcon.show()

        self.setWindowTitle("Systray")
        self.resize(400, 300)

    def setVisible(self, visible):
        self.minimizeAction.setEnabled(visible)
        self.maximizeAction.setEnabled(not self.isMaximized())
        self.restoreAction.setEnabled(self.isMaximized() or not visible)
        super(Window, self).setVisible(visible)

    def closeEvent(self, event):
        if self.trayIcon.isVisible():
            QMessageBox.information(self, "Systray",
                    "The program will keep running in the system tray. To "
                    "terminate the program, choose <b>Quit</b> in the "
                    "context menu of the system tray entry.")
            self.hide()
            event.ignore()

    def setIcon(self, index):
        icon = self.iconComboBox.itemIcon(index)
        self.trayIcon.setIcon(icon)
        self.setWindowIcon(icon)

        self.trayIcon.setToolTip(self.iconComboBox.itemText(index))

    def iconActivated(self, reason):
        if reason in (QSystemTrayIcon.Trigger, QSystemTrayIcon.DoubleClick):
            self.iconComboBox.setCurrentIndex(
                    (self.iconComboBox.currentIndex() + 1)
                    % self.iconComboBox.count())
        elif reason == QSystemTrayIcon.MiddleClick:
            self.showMessage()

    def showMessage(self):
        icon = QSystemTrayIcon.MessageIcon(
                self.typeComboBox.itemData(self.typeComboBox.currentIndex()))
        self.trayIcon.showMessage(self.titleEdit.text(),
                self.bodyEdit.toPlainText(), icon,
                self.durationSpinBox.value() * 1000)

    def messageClicked(self):
        QMessageBox.information(None, "Systray",
                "Sorry, I already gave what help I could.\nMaybe you should "
                "try asking a human?")

    def createIconGroupBox(self):
        self.iconGroupBox = QGroupBox("Tray Icon")

        self.iconLabel = QLabel("Icon:")

        self.iconComboBox = QComboBox()
        self.iconComboBox.addItem(QIcon(':/images/bad.png'), "Bad")
        self.iconComboBox.addItem(QIcon(':/images/heart.png'), "Heart")
        self.iconComboBox.addItem(QIcon(':/images/trash.png'), "Trash")

        self.showIconCheckBox = QCheckBox("Show icon")
        self.showIconCheckBox.setChecked(True)

        iconLayout = QHBoxLayout()
        iconLayout.addWidget(self.iconLabel)
        iconLayout.addWidget(self.iconComboBox)
        iconLayout.addStretch()
        iconLayout.addWidget(self.showIconCheckBox)
        self.iconGroupBox.setLayout(iconLayout)

    def createMessageGroupBox(self):
        self.messageGroupBox = QGroupBox("Balloon Message")

        typeLabel = QLabel("Type:")

        self.typeComboBox = QComboBox()
        self.typeComboBox.addItem("None", QSystemTrayIcon.NoIcon)
        self.typeComboBox.addItem(self.style().standardIcon(
                QStyle.SP_MessageBoxInformation), "Information",
                QSystemTrayIcon.Information)
        self.typeComboBox.addItem(self.style().standardIcon(
                QStyle.SP_MessageBoxWarning), "Warning",
                QSystemTrayIcon.Warning)
        self.typeComboBox.addItem(self.style().standardIcon(
                QStyle.SP_MessageBoxCritical), "Critical",
                QSystemTrayIcon.Critical)
        self.typeComboBox.setCurrentIndex(1)

        self.durationLabel = QLabel("Duration:")

        self.durationSpinBox = QSpinBox()
        self.durationSpinBox.setRange(5, 60)
        self.durationSpinBox.setSuffix(" s")
        self.durationSpinBox.setValue(15)

        durationWarningLabel = QLabel("(some systems might ignore this hint)")
        durationWarningLabel.setIndent(10)

        titleLabel = QLabel("Title:")

        self.titleEdit = QLineEdit("Cannot connect to network")

        bodyLabel = QLabel("Body:")

        self.bodyEdit = QTextEdit()
        self.bodyEdit.setPlainText("Don't believe me. Honestly, I don't have "
                "a clue.\nClick this balloon for details.")

        self.showMessageButton = QPushButton("Show Message")
        self.showMessageButton.setDefault(True)

        messageLayout = QGridLayout()
        messageLayout.addWidget(typeLabel, 0, 0)
        messageLayout.addWidget(self.typeComboBox, 0, 1, 1, 2)
        messageLayout.addWidget(self.durationLabel, 1, 0)
        messageLayout.addWidget(self.durationSpinBox, 1, 1)
        messageLayout.addWidget(durationWarningLabel, 1, 2, 1, 3)
        messageLayout.addWidget(titleLabel, 2, 0)
        messageLayout.addWidget(self.titleEdit, 2, 1, 1, 4)
        messageLayout.addWidget(bodyLabel, 3, 0)
        messageLayout.addWidget(self.bodyEdit, 3, 1, 2, 4)
        messageLayout.addWidget(self.showMessageButton, 5, 4)
        messageLayout.setColumnStretch(3, 1)
        messageLayout.setRowStretch(4, 1)
        self.messageGroupBox.setLayout(messageLayout)

    def createActions(self):
        self.minimizeAction = QAction("Mi&nimize", self, triggered=self.hide)
        self.maximizeAction = QAction("Ma&ximize", self,
                triggered=self.showMaximized)
        self.restoreAction = QAction("&Restore", self,
                triggered=self.showNormal)
        self.quitAction = QAction("&Quit", self,
                triggered=QApplication.instance().quit)

    def createTrayIcon(self):
         self.trayIconMenu = QMenu(self)
         self.trayIconMenu.addAction(self.minimizeAction)
         self.trayIconMenu.addAction(self.maximizeAction)
         self.trayIconMenu.addAction(self.restoreAction)
         self.trayIconMenu.addSeparator()
         self.trayIconMenu.addAction(self.quitAction)

         self.trayIcon = QSystemTrayIcon(self)
         self.trayIcon.setContextMenu(self.trayIconMenu)
Esempio n. 36
0
class Coropata(QLabel):
    clicked = pyqtSignal()

    def __init__(self): # Really not meant to have a parent yet
        QLabel.__init__(self, None)

        self.quitAction = None
        self.trayIconMenu = None
        self.trayIcon = None
        self.createTrayIcon()

        self.setWindowFlags(Qt.FramelessWindowHint |
                            Qt.WindowStaysOnTopHint |
                            Qt.BypassWindowManagerHint)
        self.setAttribute(Qt.WA_TranslucentBackground)

        self.m_hoverbox = Hoverbox()
        self.m_hoverbox.show()

        self.m_animation_timer = QTimer(self)
        self.m_animation_timer.setInterval(100)

        self.m_physics_timer = QTimer(self)
        self.m_physics_timer.setInterval(30)
        self.m_physics_timer.timeout.connect(self.physicsTimerEvent)

        self.screen_width = QDesktopWidget().screenGeometry().width()
        self.screen_height = QDesktopWidget().screenGeometry().height()

        # Initialize properties
        self.m_velocity = QPoint(0, 0)
        self.m_pos = QPoint(self.screen_width / 2, (5.0 / 6.0) * self.screen_height)
        self.m_offset = QPoint(0, 0)
        self.m_size = QSize(0, 0)

        self._velocity = self.m_velocity
        self._pos = self.m_pos
        self._offset = self.m_offset
        self._size = self.m_size

        self.stateMachine = xmlToStateMachine(self, 'coropata.xml')
        self.stateMachine.start()

        self.m_animation_timer.start()
        self.m_physics_timer.start()

    # Properties ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    @pyqtProperty(QSize)
    def _size(self):
        return self.m_size

    @_size.write
    def _size(self, value):
        self.m_size = value
        self.setFixedSize(value)

    @pyqtProperty(QPoint)
    def _offset(self):
        return self.m_offset

    @_offset.write
    def _offset(self, value):
        self.m_offset = value
        self.move(self.m_pos + self.m_offset)

    @pyqtProperty(QPoint)
    def _pos(self):
        return self.m_pos

    @_pos.write
    def _pos(self, value):
        self.m_pos = value
        self.move(self.m_pos + self.m_offset)
        self.m_hoverbox.move(self.m_pos - QPoint(60, 70))

    @pyqtProperty(QPoint)
    def _velocity(self):
        return self.m_velocity

    @_velocity.write
    def _velocity(self, value):
        self.m_velocity = value
    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    def mousePressEvent(self, e):
        self.clicked.emit()

    def closeEvent(self, e):
        QApplication.instance().closeAllWindows()

    def keyPressEvent(self, e):
        if e.key() == Qt.Key_Q or e.key() == Qt.Key_Escape:
            QApplication.instance().closeAllWindows()

    def physicsTimerEvent(self):
        p = self.m_pos + self.m_velocity

        if p.x() < -self._size.width():
            p.setX(self.screen_width)
        elif p.x() > self.screen_width + 10:
            p.setX(-self._size.width())

        self._pos = p

    def createTrayIcon(self):
        self.quitAction = QAction('Quit', self)
        self.quitAction.triggered.connect(self.closeEvent)
        self.trayIconMenu = QMenu(self)
        self.trayIconMenu.addAction(self.quitAction)
        self.trayIcon = QSystemTrayIcon(self)
        self.trayIcon.setContextMenu(self.trayIconMenu)
        self.trayIcon.setIcon(QIcon(os.path.join('images', 'flower.png')))
        self.trayIcon.show()
Esempio n. 37
0
from PyQt5.QtGui import QIcon, QClipboard, QKeySequence
import cpf

def gerar_cpf():
    clip = QApplication.clipboard()
    clip.setText(cpf.gerar_cpf(False))

def gerar_cpf_formatado():
    clip = QApplication.clipboard()
    clip.setText(cpf.gerar_cpf(True))

def buscar_ip():
    clip = QApplication.clipboard()
    clip.setText(ipgetter.myip())

if __name__ == '__main__':
    app = QApplication([])
    icon = QSystemTrayIcon(QIcon("img/icon.png"))
    menu = QMenu()

    menu.addAction("Gerar cpf sem formatação", gerar_cpf)
    menu.addAction("Gerar cpf com formatação", gerar_cpf_formatado)
    menu.addSeparator()
    menu.addAction("Buscar id público", buscar_ip)
    menu.addSeparator()
    menu.addAction("Fechar", app.quit)
    icon.setContextMenu(menu)

    icon.show()
    app.exec_()
Esempio n. 38
0
class Sansimera(QMainWindow):
    def __init__(self, parent=None):
        super(Sansimera, self).__init__(parent)
        self.settings = QSettings()
        self.timer = QTimer(self)
        self.timer_reminder = QTimer(self)
        self.timer_reminder.timeout.connect(self.reminder_tray)
        interval = self.settings.value('Interval') or '1'
        if interval != '0':
            self.timer_reminder.start(int(interval) * 60 * 60 * 1000)
        self.tentatives = 0
        self.gui()
        self.lista = []
        self.lista_pos = 0
        self.eortazontes_shown = False
        self.eortazontes_names = ''

    def gui(self):
        self.systray = QSystemTrayIcon()
        self.icon = QIcon(':/sansimera.png')
        self.systray.setIcon(self.icon)
        self.systray.setToolTip('Σαν σήμερα...')
        self.menu = QMenu()
        self.exitAction = QAction('&Έξοδος', self)
        self.refreshAction = QAction('&Ανανέωση', self)
        self.aboutAction = QAction('&Σχετικά', self)
        self.notification_interval = QAction('Ει&δοποίηση εορταζόντων', self)
        self.menu.addAction(self.notification_interval)
        self.menu.addAction(self.refreshAction)
        self.menu.addAction(self.aboutAction)
        self.menu.addAction(self.exitAction)
        self.systray.setContextMenu(self.menu)
        self.notification_interval.triggered.connect(self.interval_namedays)
        self.exitAction.triggered.connect(exit)
        self.refreshAction.triggered.connect(self.refresh)
        self.aboutAction.triggered.connect(self.about)
        self.browser = QTextBrowser()
        self.browser.setOpenExternalLinks(True)
        self.setGeometry(600, 500, 400, 300)
        self.setWindowIcon(self.icon)
        self.setWindowTitle('Σαν σήμερα...')
        self.setCentralWidget(self.browser)
        self.systray.show()
        self.systray.activated.connect(self.activate)
        self.browser.append('Λήψη...')
        nicon = QIcon(':/next')
        picon = QIcon(':/previous')
        ricon = QIcon(':/refresh')
        iicon = QIcon(':/info')
        qicon = QIcon(':/exit')
        inicon = QIcon(':/notifications')
        self.nextAction = QAction('Επόμενο', self)
        self.nextAction.setIcon(nicon)
        self.previousAction = QAction('Προηγούμενο', self)
        self.refreshAction.triggered.connect(self.refresh)
        self.nextAction.triggered.connect(self.nextItem)
        self.previousAction.triggered.connect(self.previousItem)
        self.previousAction.setIcon(picon)
        self.refreshAction.setIcon(ricon)
        self.exitAction.setIcon(qicon)
        self.aboutAction.setIcon(iicon)
        self.notification_interval.setIcon(inicon)
        controls = QToolBar()
        self.addToolBar(Qt.BottomToolBarArea, controls)
        controls.setObjectName('Controls')
        controls.addAction(self.previousAction)
        controls.addAction(self.nextAction)
        controls.addAction(self.refreshAction)
        self.restoreState(self.settings.value("MainWindow/State", QByteArray()))
        self.refresh()

    def interval_namedays(self):
        dialog = sansimera_reminder.Reminder(self)
        dialog.applied_signal['QString'].connect(self.reminder)
        if dialog.exec_() == 1:
            print('Apply namedays reminder interval...')

    def reminder(self, time):
        self.settings.setValue('Interval', time)
        if time != '0':
            self.timer_reminder.start(int(time) * 60 * 60 * 1000)
            print('Reminder = ' + time + ' hour(s)')
        else:
            print('Reminder = None')

    def nextItem(self):
        if len(self.lista) >= 1:
            self.browser.clear()
            if self.lista_pos != len(self.lista)-1:
                self.lista_pos += 1
            else:
                self.lista_pos = 0
            self.browser.append(self.lista[self.lista_pos])
            self.browser.moveCursor(QTextCursor.Start)
        else:
            return

    def previousItem(self):
        if len(self.lista) >= 1:
            self.browser.clear()
            if self.lista_pos == 0:
                self.lista_pos = len(self.lista)-1
            else:
                self.lista_pos -= 1
            self.browser.append(self.lista[self.lista_pos])
            self.browser.moveCursor(QTextCursor.Start)
        else:
            return

    def refresh(self):
        try:
            if self.workThread.isRunning():
                return
        except AttributeError:
            pass
        self.menu.hide()
        self.browser.clear()
        self.lista = []
        self.systray.setToolTip('Σαν σήμερα...')
        self.browser.append('Λήψη...')
        self.tentatives = 0
        self.eortazontes_shown = False
        self.download()

    def activate(self, reason):
        self.menu.hide()
        state = self.isVisible()
        if reason == 3:
            if state:
                self.hide()
                return
            else:
                self.show()
                return
        if reason == 1:
            self.menu.hide()
            self.menu.popup(QCursor.pos())

    def download(self):
        self.workThread = WorkThread()
        self.workThread.online_signal[bool].connect(self.status)
        self.workThread.finished.connect(self.window)
        self.workThread.event['QString'].connect(self.addlist)
        self.workThread.names['QString'].connect(self.nameintooltip)
        self.workThread.start()

    def addlist(self, text):
        self.lista.append(text)

    def status(self, status):
        self.status_online = status

    def reminder_tray(self):
        text = self.eortazontes_names.replace('<br/>', '\n')
        urltexts = re.findall('(<a [\S]+php">)', text)
        urltexts.extend(['</a>', '<p>', '<div>'])
        show_notifier_text = text
        for i in urltexts:
            show_notifier_text = show_notifier_text.replace(i, '')
        show_notifier_text = show_notifier_text.replace('\n\n', '\n')
        show_notifier_text = show_notifier_text.replace('www.eortologio.gr)', 'www.eortologio.gr)\n')
        self.systray.showMessage('Εορτάζουν:\n', show_notifier_text)
        self.systray.setToolTip('Εορτάζουν:\n' + show_notifier_text)

    def nameintooltip(self, text):
        self.eortazontes_names = text
        for i in ['<br/>', '<div>']:
            text = text.replace(i, '')
        self.eortazontes_in_window = text
        if self.eortazontes_shown:
            return
        self.reminder_tray()
        self.eortazontes_shown = True

    def window(self):
        self.lista.append('<div class=""></div>' + self.eortazontes_in_window)
        if self.status_online:
            self.browser.clear()
            self.browser.append(self.lista[0])
            self.lista_pos = 0
            return
        else:
            if self.tentatives == 10:
                return
            self.timer.singleShot(5000, self.refresh)
            self.tentatives += 1

    def closeEvent(self, event):
        self.settings.setValue("MainWindow/State", self.saveState())

    def about(self):
        self.menu.hide()
        QMessageBox.about(self, "Εφαρμογή «Σαν σήμερα...»",
                        """<b>sansimera-qt</b> v{0}
                        <p>Δημήτριος Γλενταδάκης <a href="mailto:[email protected]">[email protected]</a>
                        <br/>Ιστοσελίδα: <a href="https://github.com/dglent/sansimera-qt">
                        github sansimera-qt</a>
                        <p>Εφαρμογή πλαισίου συστήματος για την προβολή
                        <br/>των γεγονότων από την ιστοσελίδα <a href="http://www.sansimera.gr">
                        www.sansimera.gr</a><br/>
                        Πηγή εορτολογίου: <a href="http://www.eortologio.gr">
                        www.eortologio.gr</a>, <a href="http://www.synaxari.gr">
                        www.synaxari.gr</a>
                        <p>Άδεια χρήσης: GPLv3 <br/>Python {1} - Qt {2} - PyQt {3} σε {4}""".format(
                        __version__, platform.python_version(),
                        QT_VERSION_STR, PYQT_VERSION_STR, platform.system()))
Esempio n. 39
0
class Parse99(QApplication):

    def __init__(self, *args):
        super(QApplication, self).__init__(*args)

        # Tray Icon
        self._system_tray = QSystemTrayIcon()
        self._system_tray.setIcon(QIcon('ui/icon.png'))
        self._system_tray.setToolTip("Parse99")
        self._system_tray.show()

        # Settings
        self.settings = settings.Settings("parse99")

        # Plugins
        self._plugins = {'maps': Maps(self.settings)}

        # Timer
        self._timer = QTimer()
        self._timer.timeout.connect(self._parse)

        # Thread
        self._thread = None

        # Menu
        self._system_tray.setContextMenu(self._get_menu())

        # File
        self._log_file = ""
        self._file_size = 0
        self._last_line_read = 0
        self._log_new_lines = []

        # Start
        self.toggle('on')

    def _settings_valid(self):
        valid = True
        if self.settings.get_value('general', 'first_run') is None:
            self._system_tray.showMessage(
                "Parse99",
                """It looks like this is the first time the program is being
                run. Please setup the application using the Settings option
                once you right click the system tray icon."""
            )
            self.edit_settings()
            self.settings.set_value('general', 'first_run', True)
            valid = False
        elif self.settings.get_value('general', 'eq_directory') is None:
            self._system_tray.showMessage(
                "Parse99",
                "Please enter the General settings and \
                choose the location of your Everquest Installation."
            )
            self.edit_settings()
            valid = False
        elif self.settings.get_value('characters', None) is None:
            self._system_tray.showMessage(
                "Parse99",
                "No characters have been made.  \
                Please create at least one character using settings."
            )
            self.edit_settings(tab="characters")
            valid = False
        elif self.settings.get_value('general', 'current_character') is None:
            self._system_tray.showMessage(
                "Parse99",
                "No character has been selected. \
                Please choose a character from the Character menu."
            )
            valid = False
        return valid

    def toggle(self, switch):
        if switch == 'off':
            if self._thread is not None:
                self._timer.stop()
                self._thread.stop()
                self._thread.join()
        elif switch == 'on':
            if self._settings_valid():
                characters = self.settings.get_value('characters', None)
                log_file = characters[
                    self.settings.get_value('general', 'current_character')
                ]['log_file']
                self._thread = FileReader(
                    log_file,
                    int(self.settings.get_value('general', 'parse_interval'))
                )
                self._thread.start()
                self._timer.start(
                    1000 *
                    int(self.settings.get_value('general', 'parse_interval'))
                )

    def _parse(self):
        for line in self._thread.get_new_lines():
            for plugin in self._plugins.keys():
                if self._plugins[plugin].is_active():
                    self._plugins[plugin].parse(line)

    def _get_menu(self):
        # main menu
        menu = QMenu()
        main_menu_action_group = QActionGroup(menu)
        main_menu_action_group.setObjectName("main")
        # character menu
        map_action = QAction(menu)
        map_action.setText("Toggle Map")
        main_menu_action_group.addAction(map_action)
        separator = QAction(menu)
        separator.setSeparator(True)
        main_menu_action_group.addAction(separator)
        characters_action = QAction(menu)
        characters_action.setText("Switch Characters")
        main_menu_action_group.addAction(characters_action)
        separator = QAction(menu)
        separator.setSeparator(True)
        main_menu_action_group.addAction(separator)
        settings_action = QAction(menu)
        settings_action.setText("Settings")
        main_menu_action_group.addAction(settings_action)
        quit_action = QAction(menu)
        quit_action.setText("Quit")
        main_menu_action_group.addAction(quit_action)
        menu.addActions(main_menu_action_group.actions())
        menu.triggered[QAction].connect(self._menu_actions)
        return menu

    def update_menu(self):
        self._system_tray.contextMenu().disconnect()
        self._system_tray.setContextMenu(self._get_menu())

    def _menu_actions(self, action):
        # ag = action group, at = action text
        ag = action.actionGroup().objectName()
        at = action.text().lower()
        if ag == "main":
            if at == "quit":
                try:
                    self.toggle('off')
                    self._system_tray.setVisible(False)
                    for plugin in self._plugins.keys():
                        self._plugins[plugin].close()
                    self.quit()
                except Exception as e:
                    print("menu actions, quit", e)
            elif at == "settings":
                self.edit_settings(tab="general")
            elif at == "switch characters":
                print("switch characters")
                self.edit_settings(tab="characters")
            elif at == "toggle map":
                self._plugins['maps'].toggle()

    def edit_settings(self, **kwargs):
        try:
            if not self.settings.gui.isVisible():
                self.toggle('off')
                self.settings.gui.set_show_tab(kwargs.get('tab', None))
                self.settings.gui.exec()
                self.toggle('on')
        except Exception as e:
            print("parse99.edit_settings():", e)
Esempio n. 40
0
class ZhaoChaFrame(QWidget):
    game_hwnd = 0  # 游戏的窗体句柄
    bgpixmap = None
    pixmap = None
    my_visible = False

    # GAME_CLASS = "#32770"
    # GAME_TITLE = "大家来找茬"
    GAME_CLASS = "MozillaWindowClass"
    GAME_TITLE = "游戏全屏 - Mozilla Firefox"

    WIDTH = 500  # 大图宽
    HEIGHT = 450  # 大图高
    ANCHOR_LEFT_X = 8  # 左图X起点
    ANCHOR_RIGHT_X = 517  # 右图X起点
    ANCHOR_Y = 190  # Y起点
    CLIP_WIDTH = 10
    CLIP_HEIGHT = 10
    DIFF_LIMIT = 2000  # 差异阀值,两片图形对比差异差异超过此值视为不一样

    # 查找区域
    # 大图版 1024 x 738
    BIG_WIDTH = 498  # 大图宽
    BIG_HEIGHT = 448  # 大图高
    BIG_ANCHOR_LEFT_X = 8  # 左图X起点
    BIG_ANCHOR_RIGHT_X = 517  # 右图X起点
    BIG_ANCHOR_Y = 190  # Y起点
    BIG_CLIP_WIDTH = 10
    BIG_CLIP_HEIGHT = 10
    BIG_DIFF_LIMIT = 2000  # 差异阀值,两片图形对比差异差异超过此值视为不一样

    # 小图版 800 x 600
    SMALL_WIDTH = 381  # 大图宽
    SMALL_HEIGHT = 286  # 大图高
    SMALL_ANCHOR_LEFT_X = 10  # 左图X起点
    SMALL_ANCHOR_RIGHT_X = 403  # 右图X起点
    SMALL_ANCHOR_Y = 184  # Y起点
    SMALL_CLIP_WIDTH = 10
    SMALL_CLIP_HEIGHT = 10
    SMALL_DIFF_LIMIT = 2000  # 差异阀值,两片图形对比差异差异超过此值视为不一样


    # 存储对比结果 二位数组,映射每一个基块
    result = []

    clock = 0

    def __init__(self, parent=None):
        QWidget.__init__(self)
        # QWidget.__init__(self, parent, flags=Qt.FramelessWindowHint | Qt.Window | Qt.WindowStaysOnTopHint)
        # 设置背景透明,这样按钮不会太难看
        # self.setAttribute(Qt.WA_TranslucentBackground, True)

        # 这些属性让程序不在任务栏出现标题
        # self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.Popup | Qt.Tool)

        # 托盘
        self.icon = QIcon(":\icon.png")

        self.trayIcon = QSystemTrayIcon(self)
        self.trayIcon.setIcon(self.icon)
        self.trayIcon.setToolTip(u"QQ找茬助手")
        self.trayIcon.show()
        self.trayIcon.showMessage(u"QQ找茬助手", u"QQ找茬助手已经待命,进入游戏即可激活")

        self.action = QAction(u"退出QQ找茬助手", self, triggered=sys.exit)
        self.menu = QMenu(self)
        self.menu.addAction(self.action)
        self.trayIcon.setContextMenu(self.menu)

        # 定时探测游戏
        self.stick_timer = QTimer()
        self.stick_timer.start(20)
        # self.connect(self.stick_timer, SIGNAL('timeout()'), self.StickTarget)

        # 这个QLabel其实就是中间绘图区的背景
        self.label = QLabel(self)

        self.pixmap = QPixmap(self.size())

        # 刷新按钮
        self.btn_compare = QPushButton(self)
        self.btn_compare.setText(u"对比")
        # self.connect(self.btn_compare, SIGNAL('clicked()'), self.Compare)

        # 开关
        self.btn_toggle = QPushButton(self)
        self.btn_toggle.setText(u"擦除")
        # self.connect(self.btn_toggle, SIGNAL('clicked()'), self.Clear)

        self.HideMe()


    def StickTarget(self):
        '''让本窗体粘附在目标窗体上'''
        # 找到目标窗口句柄
        game_hwnd = win32gui.FindWindow(self.GAME_CLASS, self.GAME_TITLE)
        if game_hwnd == 0:
            if self.my_visible:
                # 如果游戏窗体不可见,比如最小化、关闭了,隐藏自己
                self.HideMe()
            return
        else:
            self.game_hwnd = game_hwnd

        try:
            window_rect = win32gui.GetWindowRect(self.game_hwnd)
            if self.game_hwnd == win32gui.GetForegroundWindow() and window_rect[0] > 0:
                point = QPoint(window_rect[0], window_rect[1])
                size = QSize(window_rect[2] - window_rect[0], window_rect[3] - window_rect[1])

                if self.size() != size:
                    self.SyncSize(size)

                if self.pos() != point:
                    self.move(point)

                if not self.my_visible:
                    self.ShowMe()
                    # self.FindAndShow()
            elif win32gui.GetForegroundWindow() != int(self.winId()) and self.my_visible:
                # 游戏窗口隐藏时,同时隐藏找碴助手
                self.HideMe()
        except:
            if self.my_visible:
                self.HideMe()


    def paintEvent(self, event):
        if not self.my_visible:
            self.move(-2000, -2000)

        self.pixmap.fill()
        p = QPainter(self.pixmap)
        p.setPen(QPen(QBrush(QColor(0, 0, 0)), 2))

        for row in range(len(self.result)):
            for col in range(len(self.result[0])):
                if self.result[row][col] != 0:
                    # 定一个基点,避免算数太难看
                    base_l_x = self.ANCHOR_LEFT_X + self.CLIP_WIDTH * col
                    base_r_x = self.ANCHOR_RIGHT_X + self.CLIP_WIDTH * col
                    base_y = self.ANCHOR_Y + self.CLIP_HEIGHT * row

                    if row == 0 or self.result[row - 1][col] == 0:
                        # 如果是第一行,或者上面的格子为空,画一条上边
                        p.drawLine(base_l_x, base_y, base_l_x + self.CLIP_WIDTH, base_y)
                        p.drawLine(base_r_x, base_y, base_r_x + self.CLIP_WIDTH, base_y)
                    if row == len(self.result) - 1 or self.result[row + 1][col] == 0:
                        # 如果是最后一行,或者下面的格子为空,画一条下边
                        p.drawLine(base_l_x, base_y + self.CLIP_HEIGHT, base_l_x + self.CLIP_WIDTH,
                                   base_y + self.CLIP_HEIGHT)
                        p.drawLine(base_r_x, base_y + self.CLIP_HEIGHT, base_r_x + self.CLIP_WIDTH,
                                   base_y + self.CLIP_HEIGHT)
                    if col == 0 or self.result[row][col - 1] == 0:
                        # 如果是第一列,或者左边的格子为空,画一条左边
                        p.drawLine(base_l_x, base_y, base_l_x, base_y + self.CLIP_HEIGHT)
                        p.drawLine(base_r_x, base_y, base_r_x, base_y + self.CLIP_HEIGHT)
                    if col == len(self.result[0]) - 1 or self.result[row][col + 1] == 0:
                        # 如果是第一列,或者右边的格子为空,画一条右边
                        p.drawLine(base_l_x + self.CLIP_WIDTH, base_y, base_l_x + self.CLIP_WIDTH,
                                   base_y + self.CLIP_HEIGHT)
                        p.drawLine(base_r_x + self.CLIP_WIDTH, base_y, base_r_x + self.CLIP_WIDTH,
                                   base_y + self.CLIP_HEIGHT)
        p.fillRect(self.btn_compare.geometry(), QBrush(QColor(0, 0, 0)))
        p.fillRect(self.btn_toggle.geometry(), QBrush(QColor(0, 0, 0)))
        self.setMask(QBitmap(self.pixmap))


    def Clear(self):
        self.ResetResult()
        self.repaint()


    def ShowMe(self):
        self.my_visible = True
        self.repaint()


    def HideMe(self):
        self.my_visible = False
        self.repaint()


    def Compare(self):
        # 对比
        if self.stick_timer.isActive():
            self.FindAndShow()
        else:
            self.stick_timer.start()


    def ResetResult(self):
        # 清楚之前计算的结果
        self.result = [[0 for a in range(0, self.WIDTH / self.CLIP_WIDTH)] for b in
                       range(0, self.HEIGHT / self.CLIP_HEIGHT)]


    def SyncSize(self, size):
        self.resize(size)

        if self.width() == 1024 and self.height() == 738:
            self.WIDTH = self.BIG_WIDTH
            self.HEIGHT = self.BIG_HEIGHT
            self.ANCHOR_LEFT_X = self.BIG_ANCHOR_LEFT_X
            self.ANCHOR_RIGHT_X = self.BIG_ANCHOR_RIGHT_X
            self.ANCHOR_Y = self.BIG_ANCHOR_Y
            self.CLIP_WIDTH = self.BIG_CLIP_WIDTH
            self.CLIP_HEIGHT = self.BIG_CLIP_HEIGHT
            self.DIFF_LIMIT = self.BIG_DIFF_LIMIT
            self.btn_compare.setGeometry(611, 650, 100, 40)
            self.btn_toggle.setGeometry(715, 650, 100, 40)
        elif self.width() == 800 and self.height() == 600:
            self.WIDTH = self.SMALL_WIDTH
            self.HEIGHT = self.SMALL_HEIGHT
            self.ANCHOR_LEFT_X = self.SMALL_ANCHOR_LEFT_X
            self.ANCHOR_RIGHT_X = self.SMALL_ANCHOR_RIGHT_X
            self.ANCHOR_Y = self.SMALL_ANCHOR_Y
            self.CLIP_WIDTH = self.SMALL_CLIP_WIDTH
            self.CLIP_HEIGHT = self.SMALL_CLIP_HEIGHT
            self.DIFF_LIMIT = self.SMALL_DIFF_LIMIT
            self.btn_compare.setGeometry(472, 496, 100, 40)
            self.btn_toggle.setGeometry(576, 496, 100, 40)
        else:
            print("游戏窗体大小匹配错误")
            return

        self.pixmap = QPixmap(self.size())
        self.bgpixmap = QPixmap(self.width(), self.HEIGHT)
        self.bgpixmap.fill(QColor(0, 0, 255))
        self.label.setGeometry(0, self.ANCHOR_Y, self.width(), self.HEIGHT)
        self.label.setPixmap(self.bgpixmap)


    def FindAndShow(self):
        # 截取游戏窗口内容
        self.my_visible = True
        self.DebugTime("init")

        ## 裁剪得到左右的内容图片
        win32gui.ShowWindow(self.game_hwnd, win32con.SW_RESTORE)  # 强行显示界面后才好截图
        win32gui.SetForegroundWindow(self.game_hwnd)  # 将游戏窗口提到最前
        src_image = ImageGrab.grab((self.x(), self.y() + self.ANCHOR_Y, self.x() + self.ANCHOR_RIGHT_X + self.WIDTH,
                                    self.y() + self.ANCHOR_Y + self.HEIGHT))
        left_box = (self.ANCHOR_LEFT_X, 0, self.ANCHOR_LEFT_X + self.WIDTH, self.HEIGHT)
        right_box = (self.ANCHOR_RIGHT_X, 0, self.ANCHOR_RIGHT_X + self.WIDTH, self.HEIGHT)
        image_left = src_image.crop(left_box)
        image_right = src_image.crop(right_box)
        # image_left.show()
        # image_right.show()
        self.DebugTime("拆图完成")

        # 将左右大图裁剪成多个小图分别进行对比
        self.ResetResult()
        for col in range(0, self.WIDTH / self.CLIP_WIDTH):
            for row in range(0, self.HEIGHT / self.CLIP_HEIGHT):
                clip_box = (col * self.CLIP_WIDTH, row * self.CLIP_HEIGHT, (col + 1) * self.CLIP_WIDTH,
                            (row + 1) * self.CLIP_HEIGHT)
                clip_image_left = image_left.crop(clip_box)
                clip_image_right = image_right.crop(clip_box)
                clip_diff = self.compare(clip_image_left, clip_image_right)

                if sum(clip_diff) > self.DIFF_LIMIT:
                    self.result[row][col] = 1

        self.DebugTime("对比")
        self.repaint()
        self.DebugTime("绘制")
        # print "----------------------"
        # for i in range(len(self.result)):        # Y轴循环
        #for j in range(len(self.result[i])):    # X轴循环
        #print self.result[i][j],
        #print
        #print "----------------------"


    def compare(self, image_a, image_b):
        '''返回两图的差异值
        返回两图红绿蓝差值万分比之和'''
        histogram_a = image_a.histogram()
        histogram_b = image_b.histogram()
        if len(histogram_a) != 768 or len(histogram_b) != 768:
            return None

        red_a = 0
        red_b = 0
        for i in range(0, 256):
            red_a += histogram_a[i + 0] * i
            red_b += histogram_b[i + 0] * i
        diff_red = 0
        if red_a + red_b > 0:
            diff_red = abs(red_a - red_b) * 10000 / max(red_a, red_b)

        green_a = 0
        green_b = 0
        for i in range(0, 256):
            green_a += histogram_a[i + 256] * i
            green_b += histogram_b[i + 256] * i
        diff_green = 0
        if green_a + green_b > 0:
            diff_green = abs(green_a - green_b) * 10000 / max(green_a, green_b)

        blue_a = 0
        blue_b = 0
        for i in range(0, 256):
            blue_a += histogram_a[i + 512] * i
            blue_b += histogram_b[i + 512] * i
        diff_blue = 0
        if blue_a + blue_b > 0:
            diff_blue = abs(blue_a - blue_b) * 10000 / max(blue_a, blue_b)

        return diff_red, diff_green, diff_blue

    def DebugTime(self, text=""):
        return

        if self.clock > 0:
            print
            time.clock() - self.clock, text
        self.clock = time.clock()
Esempio n. 41
0
class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.running = False
        self.setWindowTitle('PySwicher v{}'.format(VERSION))

        # Logging config
        self.log_textbox = QPlainTextEditLogger(self)
        logging.getLogger().addHandler(self.log_textbox)
        self.log_textbox.setFormatter(logging.Formatter('[%(asctime)s][%(levelname)s]:    %(message)s'))
        self.log_textbox.setLevel(self.get_numeric_loglevel(options['log_level']))
        self.log_to_file = False

        # System tray configuration
        self.tray_menu = QMenu(self)
        self.systemTrayIcon = QSystemTrayIcon()
        self.systemTrayIcon.setVisible(False)
        self.systemTrayIcon.setIcon(QtGui.QIcon('C:\\Users\\Admin\\Pictures\\tray_stop.jpg'))
        self.systemTrayIcon.activated.connect(self.sys_tray)
        self.exit_action = self.tray_menu.addAction('Exit')
        self.exit_action.triggered.connect(self.exit_app)
        self.systemTrayIcon.setContextMenu(self.tray_menu)
        self.click_tray_timer = QtCore.QTimer(self)  # Fix for systemtray click trigger
        self.click_tray_timer.setSingleShot(True)
        self.click_tray_timer.timeout.connect(self.click_timeout)

        self.main_window_ui()
        self.starter()

    def set_log_to_file(self, state):
        logger = logging.getLogger(__name__)
        file = logging.FileHandler(HOME + '\\switcher.log')
        if state == QtCore.Qt.Checked:
            self.log_to_file = True
            file.setFormatter(
                logging.Formatter('%(filename)s[LINE:%(lineno)d]# %(levelname)-8s [%(asctime)s]  %(message)s'))
            file.setLevel(self.get_numeric_loglevel(options['log_level']))
            logger.addHandler(file)
        else:
            if 'file' in logger.handlers:
                logger.removeHandler(file)
            self.log_to_file = False

    def starter(self):
        if not self.running:
            self.running = True
            self.start_btn.setText('Stop switcher')
            self.systemTrayIcon.setIcon(QtGui.QIcon('C:\\Users\\Admin\\Pictures\\tray_stop.jpg'))
            start_app()
        elif self.running:
            self.running = False
            self.start_btn.setText('Start switcher')
            self.systemTrayIcon.setIcon(QtGui.QIcon('C:\\Users\\Admin\\Pictures\\tray_start.jpg'))
            stop_app()
        return

    def main_window_ui(self):
        grid = QGridLayout(self)
        self.setLayout(grid)
        grid.setSpacing(5)

        # Here goes options layout
        self.topleft = QFrame(self)
        self.topleft.setFrameShape(QFrame.StyledPanel)
        self.topleft_grid = QGridLayout(self)
        self.topleft.setLayout(self.topleft_grid)

        self.switch_comb_label = QLabel('Switch combination:')
        self.switch_comb_text = QLineEdit()
        self.switch_comb_text.setText(options['switch_combination'])

        self.hotkey_label = QLabel('Hotkey:')
        self.hotkey_comb_text = QLineEdit()
        self.hotkey_comb_text.setText(options['hotkey'])

        self.topleft_grid.addWidget(self.switch_comb_label, 0, 0)
        self.topleft_grid.addWidget(self.switch_comb_text, 1, 0)
        self.topleft_grid.addWidget(self.hotkey_label, 2, 0)
        self.topleft_grid.addWidget(self.hotkey_comb_text, 3, 0)

        grid.addWidget(self.topleft, 0, 0)

        self.topright = QFrame(self)
        self.topright.setFrameShape(QFrame.StyledPanel)
        self.topright_grid = QGridLayout(self)
        self.topright.setLayout(self.topright_grid)

        self.info_label = QLabel('===INFO===')
        self.info_label.setAlignment(QtCore.Qt.AlignHCenter)

        self.info_author = QLabel('Author: Kurashov Sergey')
        self.info_author.setAlignment(QtCore.Qt.AlignHCenter)

        self.info_contacts = QLabel('Contacts: [email protected]')
        self.info_contacts.setAlignment(QtCore.Qt.AlignHCenter)

        self.info_sourcecode = QLabel('<a href="https://github.com/shimielder/win_switcher">Sourcecode on GitHub</a>')
        self.info_sourcecode.setAlignment(QtCore.Qt.AlignHCenter)
        self.info_sourcecode.setOpenExternalLinks(True)

        self.topright_grid.addWidget(self.info_label, 0, 0)
        self.topright_grid.addWidget(self.info_author, 1, 0)
        self.topright_grid.addWidget(self.info_contacts, 2, 0)
        self.topright_grid.addWidget(self.info_sourcecode, 3, 0)

        grid.addWidget(self.topright, 0, 1)

        self.middle = QFrame(self)
        self.middle.setFrameShape(QFrame.StyledPanel)
        self.middle_grid = QGridLayout(self)
        self.middle.setLayout(self.middle_grid)

        self.dictionsries_label = QLabel('Dictionaries to switch:')
        self.dict_one = QPlainTextEdit()
        self.dict_one.clear()
        self.dict_one.appendPlainText(options['layouts'][0])
        self.dict_two = QPlainTextEdit()
        self.dict_two.clear()
        self.dict_two.appendPlainText(options['layouts'][1])

        self.middle_grid.addWidget(self.dictionsries_label, 0, 0, 1, 4)
        self.middle_grid.addWidget(self.dict_one, 1, 0, 1, 4)
        self.middle_grid.addWidget(self.dict_two, 2, 0, 1, 4)
        grid.addWidget(self.middle, 1, 0, 1, 2)

        self.bottom = QFrame(self)
        self.bottom.setFrameShape(QFrame.StyledPanel)
        self.bottom_grid = QGridLayout(self)
        self.bottom.setLayout(self.bottom_grid)

        self.loglevel_label = QLabel('Logging level:')
        self.loglevel_dropmenu = QComboBox(self)
        self.loglevel_dropmenu.addItems(LOGGING_LEVELS)
        self.loglevel_dropmenu.setCurrentIndex(LOGGING_LEVELS.index((options['log_level'].upper())))
        self.loglevel_dropmenu.activated[str].connect(self.set_logginglevel)

        # self.log_to_file_label = QLabel('Check to save logs to file')
        self.log_to_file_chk = QCheckBox('Check to save logs to file')
        self.log_to_file_chk.stateChanged.connect(self.set_log_to_file)

        self.logging_output_label = QLabel('Logging output:')
        self.logging_output_label.setAlignment(QtCore.Qt.AlignHCenter)

        self.bottom_grid.addWidget(self.loglevel_label, 0, 0)
        self.bottom_grid.addWidget(self.loglevel_dropmenu, 0, 1)
        self.bottom_grid.addWidget(self.log_to_file_chk, 0, 3, 1, 1)
        self.bottom_grid.addWidget(self.logging_output_label, 1, 0, 1, 4)
        self.bottom_grid.addWidget(self.log_textbox.widget, 2, 0, 2, 4)
        grid.addWidget(self.bottom, 2, 0, 1, 2)

        self.bottom_buttons = QFrame(self)
        # self.bottom_buttons.setFrameShape(QFrame.StyledPanel)
        self.bottom_buttons_grid = QGridLayout(self)
        self.bottom_buttons.setLayout(self.bottom_buttons_grid)

        self.start_btn = QPushButton('Start switcher')
        self.start_btn.clicked.connect(self.starter)
        self.apply_btn = QPushButton('Apply changes')
        self.apply_btn.clicked.connect(self.apply)
        self.exit_btn = QPushButton('Exit app')
        self.exit_btn.clicked.connect(self.exit_app)

        self.bottom_buttons_grid.addWidget(self.start_btn, 0, 0)
        self.bottom_buttons_grid.addWidget(self.apply_btn, 0, 1)
        self.bottom_buttons_grid.addWidget(self.exit_btn, 0, 2)
        grid.addWidget(self.bottom_buttons, 3, 0, 1, 2)

        self.resize(480, 320)
        self.show()

    def get_numeric_loglevel(self, loglevel):
        numeric_level = getattr(logging, loglevel.upper(), None)
        if not isinstance(numeric_level, int):
            numeric_level = 0
        return numeric_level

    def set_logginglevel(self, loglevel):
        return self.log_textbox.setLevel(self.get_numeric_loglevel(loglevel))

    @QtCore.pyqtSlot(QSystemTrayIcon.ActivationReason)
    def sys_tray(self, reason):
        """
        По-умолчанию, trigger срабатывает всегда. Для обхода этого
        я повесил таймер на событие.
        Взято отсюда:
        https://riverbankcomputing.com/pipermail/pyqt/2010-November/028394.html
        """
        if reason == QSystemTrayIcon.Trigger:
            self.click_tray_timer.start(QApplication.doubleClickInterval())
        elif reason == QSystemTrayIcon.DoubleClick:
            self.click_tray_timer.stop()
            if self.isHidden():
                self.showNormal()
                self.systemTrayIcon.setVisible(False)

    def click_timeout(self):
        self.starter()

    def apply(self):
        self.starter()
        options['layouts'] = []
        options['layouts'].append(self.dict_one.toPlainText())
        options['layouts'].append(self.dict_two.toPlainText())
        options['log_level'] = LOGGING_LEVELS[self.loglevel_dropmenu.currentIndex()]
        self.set_logginglevel(options['log_level'])
        options['switch_combination'] = self.switch_comb_text.text()
        options['hotkey'] = self.hotkey_comb_text.text()
        logging.debug('Options from GUI: {}'.format(options))
        save_to(options)
        self.starter()
        return options

    def exit_app(self):
        if self.running:
            self.starter()
        self.systemTrayIcon.setVisible(False)
        self.destroy()

    def closeEvent(self, event):
        self.exit_app()

    def changeEvent(self, event):
        if event.type() == QtCore.QEvent.WindowStateChange:
            if self.windowState() & QtCore.Qt.WindowMinimized:
                event.ignore()
                self.hide()
                self.systemTrayIcon.setVisible(True)
                self.systemTrayIcon.showMessage('', 'Running in the background.')
        super(MainWindow, self).changeEvent(event)
Esempio n. 42
0
class DemoImpl(QDialog):
	
	
    def __init__(self, *args):
        super(DemoImpl, self).__init__(*args)

        loadUi('dict2.ui',self)
		
        self.setLayout(self.verticalLayout)
        self.plainTextEdit.setReadOnly(True)
        self.setWindowFlags(self.windowFlags() |
                            Qt.WindowSystemMenuHint |
                            Qt.WindowMinMaxButtonsHint)
        self.trayicon = QSystemTrayIcon()
        self.traymenu = QMenu()

        self.quitAction = QAction('GQuit', self)
        self.quitAction.triggered.connect(self.close)
        self.quitAction.setShortcut(QKeySequence('Ctrl+q'))
        self.addAction(self.quitAction)

        self.traymenu.addAction('&Normal', self.showNormal, QKeySequence('Ctrl+n'))
        self.traymenu.addAction('Mi&nimize', self.showMinimized, QKeySequence('Ctrl+i'))
        self.traymenu.addAction('&Maximum', self.showMaximized, QKeySequence('Ctrl+m'))
        self.traymenu.addAction('&Quit',self.close, QKeySequence('Ctrl+q'))

        self.trayicon.setContextMenu(self.traymenu)

        self.ticon = QIcon('icon_dict2.ico')
        self.trayicon.setIcon(self.ticon)
        self.trayicon.setToolTip('YYDict')
        self.trayicon.activated.connect(self.on_systemTrayIcon_activated)
        self.traymsg_firstshow = True

        self.button1.clicked.connect(self.searchword)
        self.comboBox.activated.connect(self.searchword)

    def changeEvent(self, event):
        if event.type() == QEvent.WindowStateChange:
            if self.isMinimized():
                self.hide()
                self.trayicon.show()
                if self.traymsg_firstshow:
                    self.trayicon.showMessage('', 'YYDict is running', QSystemTrayIcon.Information, 2000)
                    self.traymsg_firstshow = False
            else:
                self.trayicon.hide()
				
    def closeEvent(self, event):
        self.trayicon.hide()

    @pyqtSlot(QSystemTrayIcon.ActivationReason)
    def on_systemTrayIcon_activated(self, reason):
        if reason == QSystemTrayIcon.DoubleClick:
            self.activateWindow()	
            self.showNormal()



    @pyqtSlot()
    def searchword(self):
        word = self.lineEdit.text().strip()
        if not len(word):
            self.plainTextEdit.setPlainText('')
            self.lineEdit.setFocus(Qt.MouseFocusReason)
        else:
            self.workThread = WorkThread(word, self.comboBox.currentIndex())
            self.workThread.received.connect(self.updateResult)
            self.workThread.start()
            self.workThread.wait()


    @pyqtSlot('QString')
    def updateResult(self, rt):
        self.plainTextEdit.setPlainText(rt)
        self.lineEdit.selectAll()
        self.lineEdit.setFocus(Qt.MouseFocusReason)
Esempio n. 43
0
File: main.py Progetto: MazeFX/pat
class MainApp(QMainWindow, Ui_MainWindow):

    _translate = QCoreApplication.translate
    tab_list = []
    # TODO - add dutch translation files

    def __init__(self, isolated, *args):
        super(MainApp, self).__init__(*args)
        Lumberjack.info('spawning the <<< MainApp >>> hey says: I am the Main man here see!')
        self.load_settings()
        self.setup_tray(isolated)
        self.dbhelper = DbHelper()

        self.setupUi(self)
        self.iconize_controls()
        self.load_styling()

        self.tabWidget = QTabWidget(self.centralwidget)
        self.tabWidget.setTabsClosable(True)
        self.tabWidget.setMovable(True)
        self.tabWidget.setTabBarAutoHide(True)
        self.tabWidget.setObjectName("tabWidget")
        self.verticalLayout.addWidget(self.tabWidget)

        builderLabel = QLabel('made by: MazeFX Solutions')
        self.statusbar.addPermanentWidget(builderLabel)

        self.menuPAT.triggered.connect(self.handle_menu_event)
        self.menuLists.triggered.connect(self.handle_menu_event)
        self.menuHelp.triggered.connect(self.handle_menu_event)
        self.tabWidget.tabCloseRequested.connect(self.close_tab)
        self.actionHome.trigger()

        self._retranslateUi(self)

    def iconize_controls(self):
        Lumberjack.info('< MainApp > - -> (iconize_controls)')

        homeIcon = qta.icon('fa.home', color='white')
        self.actionHome.setIcon(homeIcon)
        wrenchIcon = qta.icon('fa.wrench', color='white')
        self.actionSettings.setIcon(wrenchIcon)

        bankIcon = qta.icon('fa.bank', color='white')
        self.actionListBankAccounts.setIcon(bankIcon)

        contractIcon = QIcon(':/app_icons/rc/handshake_icon.svg')
        self.actionListContracts.setIcon(contractIcon)

        atIcon = qta.icon('fa.at', color='white')
        self.actionListEmailAddresses.setIcon(atIcon)

        envelopeIcon = qta.icon('fa.envelope', color='white')
        self.actionListLetters.setIcon(envelopeIcon)

        relationIcon = qta.icon('fa.group', color='white')
        self.actionListRelations.setIcon(relationIcon)

        transactionIcon = qta.icon('fa.money', color='white')
        self.actionListTransactions.setIcon(transactionIcon)

        userIcon = qta.icon('fa.user', color='white')
        self.actionListUsers.setIcon(userIcon)

        helpIcon = qta.icon('fa.question', color='white')
        self.actionHelp.setIcon(helpIcon)

        aboutIcon = qta.icon('fa.info', color='white')
        self.actionAbout.setIcon(aboutIcon)

    def setup_tray(self, isolated):
        Lumberjack.info('< MainApp > - -> (setup_tray)')
        self.trayIcon = QSystemTrayIcon(QIcon(':/app_icons/rc/PAT_icon.png'), self)
        self.trayMenu = QMenu(self)
        showAction = self.trayMenu.addAction("Open PAT")
        self.trayMenu.addSeparator()
        exitAction = self.trayMenu.addAction("Exit")
        self.trayIcon.setContextMenu(self.trayMenu)
        self.trayMenu.triggered.connect(self.handle_tray_event)
        self.trayIcon.activated.connect(self.handle_tray_event)
        self.trayIcon.show()
        if isolated:
            self.trayIcon.showMessage('PAT Service', 'PAT service is now running..')

    def handle_tray_event(self, *args):
        Lumberjack.info('< MainApp > - -> (handle_tray_event)')
        print(Fore.MAGENTA + '$! Received a tray action with args: ', args)
        if args[0] == 3:
            self.show()
            return
        elif hasattr(args[0], 'text'):
            print(Fore.MAGENTA + '$! Tray event has text!!')
            if args[0].text() == 'Open PAT':
                self.show()
            elif args[0].text() == 'Exit':
                self.close()

    def _retranslateUi(self, MainWindow):
        pass

    def handle_menu_event(self, *args):
        Lumberjack.info('< MainApp > - -> (handle_menu_event)')
        Lumberjack.debug('(handle_menu_event) - args = {}'.format(args))

        action_text = args[0].text()
        icon = args[0].icon()

        Lumberjack.debug('(handle_menu_event) - Action text selector = {}'.format(action_text))
        print(Fore.MAGENTA + '$! Action text received: ', action_text)

        if action_text == 'Home':
            Lumberjack.info('(handle_menu_event) >User action> :  Adding Home tab to self')
            self.add_tab(HomeTab, 'Home', icon)

        if action_text == 'Settings':
            Lumberjack.info('(handle_menu_event) >User action> :  Showing settings dialog')
            self.show_settings()

        elif action_text == 'Bank accounts':
            Lumberjack.info('(handle_menu_event) >User action> : Adding Bank account List tab to self')
            self.add_tab(BankAccountListTab, 'Bank accounts', icon)

        elif action_text == 'Contracts':
            Lumberjack.info('(handle_menu_event) >User action> : Adding Contracts List tab to self')
            self.add_tab(ContractListTab, 'Contracts', icon)

        elif action_text == 'Email addresses':
            Lumberjack.info('(handle_menu_event) >User action> : Adding EmailAddress List tab to self')
            self.add_tab(EmailAddressListTab, 'Email addresses', icon)

        elif action_text == 'Letters':
            Lumberjack.info('(handle_menu_event) >User action> :  Adding Letter List tab to self')
            self.add_tab(LetterListTab, 'Letters', icon)

        elif action_text == 'Users':
            Lumberjack.info('(handle_menu_event) >User action> :  Adding User List tab to self')
            self.add_tab(UserListTab, 'Users', icon)

        elif action_text == 'Relations':
            Lumberjack.info('(handle_menu_event) >User action> :  Adding Relation List tab to self')
            self.add_tab(RelationListTab, 'Relations', icon)

        elif action_text == 'Transactions':
            Lumberjack.info('(handle_menu_event) >User action> :  Adding Transaction List tab to self')
            self.add_tab(TransactionListTab, 'Transactions', icon)

        elif action_text == 'Help':
            Lumberjack.info('(handle_menu_event) >User action> :  Showing help dialog')
            # TODO - build help dialog and help files

        elif action_text == 'About':
            Lumberjack.info('(handle_menu_event) >User action> :  Showing about dialog')
            # TODO build About dialog.

    def show_settings(self):
        Lumberjack.info('< MainApp > - -> (show_settings)')
        settings_dialog = SettingsDialog()
        settings_dialog.exec_()

    def add_tab(self, tab_cls, tab_name, icon):
        Lumberjack.info('< MainApp > - -> (add_tab)')
        new_tab = tab_cls(self.dbhelper)
        print(Fore.MAGENTA + 'Adding a tab with class: ', str(tab_cls))
        new_tab.setObjectName(str(tab_cls))
        self.tabWidget.addTab(new_tab, icon, self._translate("MainWindow", tab_name))

        print(Fore.MAGENTA + 'New tab added to tab list.')
        self.tabWidget.setCurrentIndex(self.tabWidget.indexOf(new_tab))
        self.tab_list.append(new_tab)

    def close_tab(self, index):
        # TODO - Check if index stays correct when moving tabs around
        requesting_tab = self.tab_list[index]
        print(Fore.MAGENTA + 'requesting tab is: ', requesting_tab)
        if hasattr(requesting_tab, 'form'):
            if requesting_tab.form.edit_mode:
                print(Fore.MAGENTA + 'Tab is in edit mode.')
                requesting_tab.form.toggle_edit_mode(False, None, None)
            if requesting_tab.form.edit_mode is None:
                print(Fore.MAGENTA + 'Tab is now in equil.')
                self.tabWidget.removeTab(index)
                del self.tab_list[index]
        else:
            self.tabWidget.removeTab(index)
            del self.tab_list[index]

    def load_settings(self):
        self.settings = QSettings()

        db_path = self.settings.value('db_base_path')
        db_name = self.settings.value('db_name')

        if db_path is not None and db_name is not None:
            db_file = os.path.join(db_path, db_name)
            Lumberjack.debug('__init__ - db_file = {}'.format(db_file))
            if os.path.exists(db_file):
                return
        Lumberjack.warning('(load_settings) - database not found')
        settings_dialog = SettingsDialog()
        settings_dialog.exec_()
        int_value = self.settings.value('db_type', type=int)
        print(Fore.MAGENTA + "load choosen database setting: %s" % repr(int_value))

    def load_styling(self):
        style.set_window_style(self)

    def closeEvent(self, event):
        print(Fore.MAGENTA + "User has clicked the red x on the main window")
        for tab in self.tab_list:
            if hasattr(tab, 'form'):
                if tab.form.edit_mode:
                    print(Fore.MAGENTA + 'Tab is in edit mode.')
                    tab.form.toggle_edit_mode(False, None, None)

        close_dialog = CloseDialog()
        result = close_dialog.exec_()
        if result == close_dialog.Minimize:
            self.hide()
            event.ignore()
        elif result == close_dialog.Rejected:
            event.ignore()
        elif result == close_dialog.Exit:
            print(Fore.MAGENTA + "Exiting via save dialog, result = ", result)
            self.trayIcon.hide()
            event.accept()
Esempio n. 44
0
class MainWindow(QMainWindow):

    restartOdooMenuItem = QtCore.pyqtSignal()
    stopOdooMenuItem = QtCore.pyqtSignal()
    restartPostgreMenuItem = QtCore.pyqtSignal()
    stopPostgreMenuItem = QtCore.pyqtSignal()

    def __init__(self):
        super(MainWindow, self).__init__()

        if OdooInstallationFound == False:

            if not os.path.isdir(appfolder + '\\Temp'):
                os.makedirs(appfolder + '\\Temp')

            unzipToPath = appfolder + '\\Temp\\Unzip'
            destinationPath = appfolder + "\\Runtime\\Odoo"

            self.downloadFileWorker(mainSettings['github']['downloadPath'])

            if os.path.isfile(appfolder + '\\Temp\\GitHub-Odoo.zip'):
                if not os.path.isdir(appfolder + '\\Temp\\unzip'):
                    os.makedirs(appfolder + '\\Temp\\unzip')

                self.zipFileWorker(appfolder + '\\Temp\\GitHub-Odoo.zip', unzipToPath)
                self.zipWindow.close()

                #Check if the file is etxracted to subfolder - Files on github includes branch name -> Correct this
                countFolders = 0
                extractFolder = None
                for name  in os.listdir(unzipToPath):
                    extractFolder = name
                    countFolders += 1
                if countFolders == 1:
                    shutil.move(unzipToPath + "\\" + extractFolder + "\\", destinationPath)
                self.startCybeSystemsApplication()
        else:
            self.startCybeSystemsApplication()

        if os.path.isdir(appfolder + '\\Temp'):
            shutil.rmtree(appfolder + '\\Temp',ignore_errors=True)

    def zipFileWorker(self,file, destination_folder):
        self.zipWindow = ZipWindow(file, destination_folder)
        self.zipWindow.show()

    def downloadFileWorker(self,url):
        self.httpWin = HttpWindow(url)
        self.httpWin.exec()

    def startCybeSystemsApplication(self):

        #Set Loading TrayIcon
        self.setWindowIcon(QtGui.QIcon(appfolder + '/ressource/icons/icon.png'))

        img = QtGui.QImage()
        img.load(appfolder + '/ressource/icons/icon_loading.png')
        self.pixmap = QtGui.QPixmap.fromImage(img)
        self.icon = QtGui.QIcon()
        self.icon.addPixmap(self.pixmap)
        self.tray = QSystemTrayIcon(self.icon, self)
        self.tray.show()
        traymenu = QMenu()

        #Set Real Icon
        self.tray.hide()
        img = QtGui.QImage()
        img.load(appfolder + '/ressource/icons/icon.png')
        self.pixmap = QtGui.QPixmap.fromImage(img)
        self.icon = QtGui.QIcon()
        self.icon.addPixmap(self.pixmap)
        self.tray = QSystemTrayIcon(self.icon, self)
        self.tray.activated.connect(self.onTrayIconActivated)
        self.tray.setContextMenu(traymenu)
        self.tray.show()

        #Load Stylesheet
        if mainSettings['other']['theme'].lower() != 'default':
            if mainSettings['other']['theme'].lower() == 'steamlike':
                stylesheetFile = open(appfolder + '/ressource/ui/steamlike.stylesheet', "r")
            elif mainSettings['other']['theme'].lower() == 'darkorange':
                stylesheetFile = open(appfolder + '/ressource/ui/darkorange.stylesheet', "r")
            elif mainSettings['other']['theme'].lower() == 'maya':
                stylesheetFile = open(appfolder + '/ressource/ui/maya.stylesheet', "r")
            stylesheet = stylesheetFile.read()
            traymenu.setStyleSheet(stylesheet)
            stylesheetFile.close()

        trayoption_openBrowser_entry = QAction(QtGui.QIcon(self.icon), "Open Odoo", self)
        trayoption_openBrowser_entry.triggered.connect(lambda: webbrowser.open(mainSettings['odoo']['startpage']))
        traymenu.addAction(trayoption_openBrowser_entry)
        trayoption_openBrowser_entry.setIcon(QtGui.QIcon(appfolder + '/ressource/icons/world.png'))

        traymenu.addSeparator()

        tools = traymenu.addMenu('&Odoo')
        tools.setIcon(QtGui.QIcon(appfolder + '/ressource/icons/icon.png'))

        tools_odoo_restart = QAction(QtGui.QIcon(self.icon), "Restart Server", self)
        tools_odoo_restart.triggered.connect(lambda: (self.restartOdooMenuItem.emit()))
        tools.addAction(tools_odoo_restart)
        tools_odoo_restart.setIcon(QtGui.QIcon(appfolder + '/ressource/icons/start_server.png'))

        tools_odoo_stop = QAction(QtGui.QIcon(self.icon), "Stop Server", self)
        tools_odoo_stop.triggered.connect(lambda: (self.stopOdooMenuItem.emit()))
        tools.addAction(tools_odoo_stop)
        tools_odoo_stop.setIcon(QtGui.QIcon(appfolder + '/ressource/icons/stop_server.png'))

        #traymenu.addSeparator()

        tools = traymenu.addMenu('&PostgreSQL')
        tools.setIcon(QtGui.QIcon(appfolder + '/ressource/icons/postgresql.png'))

        tools_postgre_restart = QAction(QtGui.QIcon(self.icon), "Restart Server", self)
        tools_postgre_restart.triggered.connect(lambda: (self.restartPostgreMenuItem.emit()))
        tools.addAction(tools_postgre_restart)
        tools_postgre_restart.setIcon(QtGui.QIcon(appfolder + '/ressource/icons/start_server.png'))

        tools_postgre_stop = QAction(QtGui.QIcon(self.icon), "Stop Server", self)
        tools_postgre_stop.triggered.connect(lambda: (self.stopPostgreMenuItem.emit()))
        tools.addAction(tools_postgre_stop)
        tools_postgre_stop.setIcon(QtGui.QIcon(appfolder + '/ressource/icons/stop_server.png'))

        tools.addSeparator()

        tools_pgadmin = QAction(QtGui.QIcon(self.icon), "pgAdmin III", self)
        tools_pgadmin.triggered.connect(lambda: self.startpgadmin())
        tools.addAction(tools_pgadmin)
        tools_pgadmin.setIcon(QtGui.QIcon(appfolder + '/ressource/icons/cog.png'))

        traymenu.addSeparator()

        trayoption_quickconfig = QAction(QtGui.QIcon(self.icon), "Show Output/Config", self)
        trayoption_quickconfig.triggered.connect(lambda: self.showCommandLineWindowTryOption())
        traymenu.addAction(trayoption_quickconfig)
        trayoption_quickconfig.setIcon(QtGui.QIcon(appfolder + '/ressource/icons/application_osx_terminal.png'))

        traymenu.addSeparator()

        trayoption_exit_entry = QAction(QtGui.QIcon(self.icon), "Exit", self)
        trayoption_exit_entry.triggered.connect(lambda: self.trayOptionExit())
        traymenu.addAction(trayoption_exit_entry)
        trayoption_exit_entry.setIcon(QtGui.QIcon(appfolder + '/ressource/icons/cancel.png'))

        self.tray.showMessage('Odoo is Loading - Please wait','\nLeft click to open CommandWindow\nRight click to open Traymenu')

        self.showCommandLineWindow()

    def startpgadmin(self):
        os.startfile(appfolder + '/Runtime/PostgreSQL/bin/pgAdmin3.exe')

    def showCommandLineWindow(self):
        self.ShowCommandLineWindow=CommandLineWindow(self)
        self.ShowCommandLineWindow.setWindowIcon(QtGui.QIcon(appfolder + '/ressource/icons/icon.png'))
        self.ShowCommandLineWindow.show()
        if mainSettings['other']['minimizeToTray']:
            self.ShowCommandLineWindow.setVisible(False)
        else:
            self.ShowCommandLineWindow.setVisible(True)

    def toggleCommandLineWindow(self):
        if self.ShowCommandLineWindow.isMinimized():
            self.ShowCommandLineWindow.setVisible(True)
            self.ShowCommandLineWindow.showNormal()
            self.ShowCommandLineWindow.activateWindow()
        elif self.ShowCommandLineWindow.isVisible ():
            self.ShowCommandLineWindow.showNormal()
            self.ShowCommandLineWindow.setVisible(False)
        else:
            self.ShowCommandLineWindow.setVisible(True)
            self.ShowCommandLineWindow.showNormal()
            self.ShowCommandLineWindow.activateWindow()

    def showCommandLineWindowTryOption(self):
        self.ShowCommandLineWindow.setVisible(True)
        self.ShowCommandLineWindow.showNormal()
        self.ShowCommandLineWindow.activateWindow()

    def onTrayIconActivated(self,reason):
        if reason == QSystemTrayIcon.DoubleClick:
            pass

        if reason == QSystemTrayIcon.Trigger:
            self.toggleCommandLineWindow()

        if reason == QSystemTrayIcon.Context:
            pass

    def center(self):
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    def trayOptionExit(self,msgbox=True):
        if msgbox:
            quit_msg = "Stop all running Server ?"
            reply = QMessageBox.question(self.center(), 'Exit',
                quit_msg, QMessageBox.Yes, QMessageBox.No)
            if reply == QMessageBox.Yes:
                confirmed = True
            else:
                confirmed = False
        else:
            confirmed = True

        if confirmed:
            runtimeSettings["closeMainWindow"] = True
            self.ShowCommandLineWindow.setVisible(True)
            app = QApplication.instance()
            app.closeAllWindows()
            self.tray.hide()
            os._exit(1)
Esempio n. 45
0
class MyApp(QtWidgets.QMainWindow):
	mouseLeaveTimer=0

	def __init__(self):
		# Ui_MainWindow.__init__(self)
		#自己有__init__函数时,不会默认调用基类的__init__函数
		# 因为这里重写了__init__将基类的覆盖掉了,故需要主动调用之
		
		# QtWidgets.QMainWindow.__init__(self) 
		# super(MyApp,self).__init__()
		#上面两句的作用是相同的,下面这句是python3的新写法
		super().__init__()
		# 	Get the Screen size
		self.screenWidth=QDesktopWidget().availableGeometry().width()
		self.screenHeight=QDesktopWidget().availableGeometry().height()
		#初始化字体
		font=QFont('黑体')
		font.setPointSize(12)
		app.setFont(font)
		#  ColorSetting
		self.bgColor=QColor(66,66,77,88)

		#
		# self.setupUi(self)
		self.initUI()
		#用来控制半透明的bg面板自动消失
		self.timer=QTimer()
		self.timer.start(30)
		self.setGeometry(0,30,self.screenWidth,self.screenHeight//3)

		#Flagsq
		self.IsMouseHover=False
		self.MouseOver=False
		self.Locked=False
		self.Hidden=False
		self.isDrag=False
		self.isResize=False
		#变量初始化
		GLOBAL.WINDOWWIDTH=self.width()
		GLOBAL.WINDOWHEIGHT=self.height()
		self.bullets=[]
		self.dragPos=QPoint(22,22)
		self.savedName=''
		# self.screenBuffer=QBitmap(GLOBAL.WINDOWWIDTH,GLOBAL.WINDOWHEIGHT)
		# self.bufferPainter=QPainter(self.screenBuffer)
		# self.picture=QPicture()
		# 建立connection和slot的回调连接
		self.createConnections()
		# 连接到nodejs建立的服务器
		self.connect2Server()

	def initUI(self):
		#构建托盘
		self.trayIcon=QSystemTrayIcon(self)
		self.trayIcon.setIcon(QtGui.QIcon("tmpIcon.ico"))
		self.trayIcon.show()
		self.trayIcon.setToolTip('BulletGo')

		# 构建托盘菜单
		action_quit=QAction('退出',self)
		action_quit.triggered.connect(self.exitApp)
		action_switchLock=QAction('锁定/解锁(F6)',self)
		action_switchLock.triggered.connect(self.switchLock)
		action_showHide=QAction('显示/隐藏(F7)',self)
		action_showHide.triggered.connect(lambda:self.switchVisible(self))
		action_Settings=QAction('设置',self)
		action_Settings.triggered.connect(lambda:self.switchVisible(self.settingWindow))
		trayIconMenu=QtWidgets.QMenu(self)
		trayIconMenu.addAction(action_switchLock)
		trayIconMenu.addAction(action_showHide)
		trayIconMenu.addSeparator()
		trayIconMenu.addAction(action_Settings)
		trayIconMenu.addAction(action_quit)

		#设定快捷键
		QtWidgets.QShortcut(QtGui.QKeySequence(\
			QtCore.Qt.Key_F7),self,\
		(lambda:self.switchVisible(self.settingWindow)))
		QtWidgets.QShortcut(QtGui.QKeySequence(\
			QtCore.Qt.Key_F6),self,\
		(self.switchLock))

		self.trayIcon.setContextMenu(trayIconMenu)
		# 保障不按下鼠标也追踪mouseMove事件
		self.setMouseTracking(True)
		self.setMinimumSize(600,260)
		self.setWindowTitle("BulletGo")
		sizeGrip=QtWidgets.QSizeGrip(self)
		self.setWindowFlags(Qt.FramelessWindowHint\
			|Qt.WindowStaysOnTopHint|Qt.Window|\
			Qt.X11BypassWindowManagerHint)
		#Plan A
		self.setAttribute(Qt.WA_TranslucentBackground,True)
		#这一句是给Mac系统用的,防止它绘制(很黯淡的)背景
		self.setAutoFillBackground(False)
		QSizeGrip(self).setVisible(True)
		sizeGrip.setVisible(True)
		#Plan B  失败
		# palette=QPalette()
		# color=QColor(190, 230, 250)
		# color.setAlphaF(0.6)
		# palette.setBrush(self.backgroundRole(), color)
		# self.setPalette(palette)
		# self.setAutoFillBackground(True)
		# self.setBackgroundRole(QPalette.Window)

		#创建房间的Button和 输入框

		self.roomName=QPlainTextEdit()
		self.roomName.setPlaceholderText('请输入房间名')
		# self.roomName.resize(50,20)
		# self.roomName.move(0,0)
		# self.roomName.setBackgroundVisible(False)
		self.createBtn=QPushButton("创建/进入")
		self.hideBtn=QPushButton('隐藏本设置窗口')
		self.hideBtn.clicked.connect(self.joinRoom)
			# lambda:self.switchVisible(self.settingWindow))
		# self.createBtn.resize(50,20)
		# self.move(0,100)
		# self.d
		settingLayout=QVBoxLayout()
		hLayout=QHBoxLayout()
		settingLayout.addWidget(self.roomName)
		hLayout.addWidget(self.hideBtn)
		hLayout.addWidget(self.createBtn)
		self.settingWindow=QWidget()
		# self.hideBtn=setShortcut(QtGui.QKeySequence('Ctrl+B'))
		settingLayout.addLayout(hLayout)
		self.settingWindow.setLayout(settingLayout)
		# Qt.Tool的作用是  不在任务栏显示
		self.settingWindow.setWindowFlags(Qt.FramelessWindowHint|Qt.Tool\
			|Qt.X11BypassWindowManagerHint|Qt.Popup)
		self.roomName.show()
		self.createBtn.show()
		self.settingWindow.resize(160,26)
		self.settingWindow.show()


		# self.btnFire=QPushButton("Fire",self)
		# self.btnFire.resize(60,60)
		# self.btnFire.move(100,30)
		# self.btnFire.show()

		# self.btnLock=QPushButton("Lock",self)
		# self.btnLock.resize(40,40)
		# self.btnLock.move(self.screenWidth/2,30)
		# self.btnLock.setFlat(True)
		# self.btnLock.setIcon(QtGui.QIcon("tmpIcon.png"))
		# self.btnLock.show()



		# self.danmakuEditText=QPlainTextEdit(self)
		# self.danmakuEditText.resize(200,100)
		# self.danmakuEditText.move(100,100)
		# self.danmakuEditText.setBackgroundVisible(False)
		# self.danmakuEditText.show()

	def joinRoom(self):
		name=self.roomName.toPlainText()
		self.socketio.emit('join',name)

	def connect2Server(self):
		self.socketio=SocketIO('115.159.102.76/bulletgo_client',80,LoggingNamespace)
		self.registerEvents()
		# 开新线程监听服务器发来的消息,否则主线程被阻塞
		_thread.start_new_thread(self.socketio.wait,())

	def registerEvents(self):
		self.socketio.on('create_rsp',lambda rsp:self.handleIncomeBullet(rsp))
		self.socketio.on('bullet',lambda msg:self.handleIncomeBullet(msg))
		self.socketio.on('control_msg',lambda msg:print\
			('---control message---  : '+msg))
		self.socketio.on('sys_notification',lambda msg:print\
			('---system notification---  : '+msg))

	def handleIncomeBullet(self,bulletMsg):
		textsAndInfo=self.preProcessText(bulletMsg)
		if(len(textsAndInfo)>1):
			self.fireABullet(textsAndInfo[0],self.genQColorFromStr(textsAndInfo[1]))

	def createRoom_Nodejs(self,name):
		self.socketio.emit('create_room',name)

	def fireBtn(self):
		txt=self.danmakuEditText.toPlainText()
		tmpbullet=Bullet(txt,GLOBAL.ORANGE,random.randrange(9,16,2))
		self.bullets.append(tmpbullet)
		tmpbullet.prepare()
		# print(len(self.bullets))
		# testStr="line1\nline2\nline3"
		# textsAndInfo=self.preProcessText(testStr)
		# print(len(textsAndInfo))
		# print

	


	def fireABullet(self,txt,color=GLOBAL.ORANGE):
		tmpbullet=Bullet(txt,color,random.randrange(12,22,2))
		self.bullets.append(tmpbullet)
		tmpbullet.prepare()

	def createConnections(self):
		self.timer.timeout.connect(self.update)
		# self.btnFire.clicked.connect(self.fireBtn)
		self.createBtn.clicked.connect(\
			lambda:self.createRoom_Nodejs\
				(self.roomName.toPlainText()))
		# self.btnLock.clicked.connect(self.switchLock)
		# self.btnLock.clicked.connect(self.pullMsg)
		self.trayIcon.activated.connect(self.trayClick)

	def switchVisible(self,handle):
		if(handle.isHidden()):
			handle.activateWindow()
		handle.setHidden(not handle.isHidden())

	def trayClick(self,reason):
		#单击事件还没设计好
		# if(reason==QSystemTrayIcon.Trigger):
		# 	self.switchVisible(self)
		if(reason==QSystemTrayIcon.DoubleClick):
			self.switchVisible(self.settingWindow)


	def switchLock(self):
		self.Locked=not self.Locked

	'''这个神奇的用法, 在js中也可用'''
	'''博客搞好后, 这个要单独写个文章'''
	def genQColorFromStr(self,color):
		# print(color)
		return{
			'white':GLOBAL.WHITE,
			'green':GLOBAL.GREEN,
			'red':GLOBAL.RED,
			'pink':GLOBAL.PINK,
			'purple':GLOBAL.PURPLE,
			'darkblue':GLOBAL.DARKBLUE,
			'blue':GLOBAL.BLUE,
			'yellow':GLOBAL.YELLOW,
			'cyan':GLOBAL.CYAN,
			'orange':GLOBAL.ORANGE,
			'':GLOBAL.ORANGE
		}[color]

	def preProcessText(self,string):
		return string.split('`<')

	'''---[deprecated]---'''
	def realPullMsg(self):
		url='http://danmaku.applinzi.com/message.php'
		r =  requests.post(url,data=self.savedName)
		r.encoding='utf-8'
		#预处理收到的字符串  
		# print(r.text)
		# r.te
		textsAndInfo=self.preProcessText(r.text)
		i=0
		# print(textsAndInfo)
		# print(r.text)
		if(len(textsAndInfo)>1):
			while(i<len(textsAndInfo)-1):
				# print(len(textsAndInfo))
				# print('ddddd')
				# print(i)
				self.fireABullet(textsAndInfo[i],self.genQColorFromStr(textsAndInfo[i+1]))
				i+=2

	'''---[deprecated]---'''
	def pullMsg(self):
		_thread.start_new_thread(self.realPullMsg,())

	'''---[deprecated]---'''
	def createRoom(self):
		#编码问题实在天坑!!!
		self.savedName=self.roomName.toPlainText().encode('utf-8')#保存自己的房间号
		postData=self.roomName.toPlainText().encode('utf-8')
		r = requests.post('http://danmaku.applinzi.com/createroom.php',data=postData)
		r.encoding='utf-8'
		self.fireABullet(r.text)
		# print(r.encoding)
		if(len(r.text)==7):
			# 开始自动获取服务器上的消息内容
			self.pullTimer=QTimer()
			self.pullTimer.start(2000)
			self.pullTimer.timeout.connect(self.pullMsg)
		# print(r.content)
		# print(r.text)


	def closeEvent(self,e):
		e.accept()

	def mouseReleaseEvent(self,e):
		if(e.button()==Qt.LeftButton):
			self.isDrag=False
			self.isResize=False

	def mousePressEvent(self,e):
		if e.button()==Qt.LeftButton:
			self.LDown=True
			# self.dragPos=e.globalPos()-self.frameGeometry().topLeft()
			self.dragPos=e.pos()#效果同上,鼠标相对窗口左上角的位置
			
			if(GLOBAL.WINDOWWIDTH-e.pos().x()<16\
			and GLOBAL.WINDOWHEIGHT-e.pos().y()<16):
				self.topLeft=self.frameGeometry().topLeft()
				self.isResize=True
			else:
				if(not self.Locked):
					self.isDrag=True
		# else:
		# 	if e.button()==Qt.RightButton:
		# 		self.exitApp()
		e.accept()

	def mouseMoveEvent(self,e):
		if(GLOBAL.WINDOWWIDTH-e.pos().x()<16\
			and GLOBAL.WINDOWHEIGHT-e.pos().y()<16):
			#更改鼠标样式
			self.setCursor(Qt.SizeFDiagCursor)
		else:
			self.setCursor(Qt.ArrowCursor)
		#如果是Resize,改变窗口大小
		if(self.isResize):
			tmp=e.globalPos()-self.topLeft
			self.move(self.topLeft)
			self.resize(tmp.x(),tmp.y())
		if (self.isDrag):
			self.move(e.globalPos()-self.dragPos)
		e.accept();



	def enterEvent(self,e):
		self.MouseOver=True
		self.IsMouseHover=True
		return super(MyApp,self).enterEvent(e)

	def setMouseHoverFalse(self):
		# if(not self.MouseOver):
		self.IsMouseHover=self.MouseOver


	def leaveEvent(self,e):
		QTimer.singleShot(800,self.setMouseHoverFalse)
		self.MouseOver=False
		return super(MyApp,self).leaveEvent(e)

	def resizeEvent(self,e):
		GLOBAL.WINDOWWIDTH=self.width()
		GLOBAL.WINDOWHEIGHT=self.height()
		# self.screenBuffer=QBitmap(GLOBAL.WINDOWWIDTH,GLOBAL.WINDOWHEIGHT)
		# self.bufferPainter=QPainter(self.screenBuffer)
		# print('resized')
		# self.repaint()
		e.accept()

	def paintEvent(self,e):
		# Get the Painter
		painter=QPainter(self)
		font=QFont('黑体',GLOBAL.BULLETFONTSIZE,QFont.Bold)
		painter.setFont(font)
		#Draw a semi-Transparent rect whose size is the same with this window
		if(self.IsMouseHover and (not self.Locked)):
			painter.fillRect(0,0,GLOBAL.WINDOWWIDTH,GLOBAL.WINDOWHEIGHT\
				,self.bgColor)
		# painter.setBackground(QBrush(QColor(123,222,123,122)))
		#画所有bullet
		for b in self.bullets:
			b.draw(painter)
		for b in self.bullets:
			if(b.IsExpired):
				self.bullets.remove(b)
		# painter.drawPicture(0,0,self.picture)
		# painter.drawText(30,100,"Hello this is a PyQt5 App我也会说中文")
		return super(MyApp,self).paintEvent(e)

	def exitApp(self):
		self.trayIcon.hide()
		sys.exit()
Esempio n. 46
0
class Window(QWidget):
    w, h = 0, 0
    layoutmode = False
    movetile = None
    ismin = False
    tiles = []

    def __init__(self):
        super().__init__()
        if TRAY_ICON:
            self.inittray()
        self.setWindowTitle('Tilemenu')
        self.initgeometry()
        self.inittiles()
        self.mouseReleaseEvent = self.onClicked
        self.initstyle()
        self.show()

    def inittiles(self):
        for t in TILESET:
            newtile = t.tile(t.xy, parent=self, extra=t.extra)
            self.tiles.append(newtile)

    def testinittiles(self):
        for i in range(self.w):
            for j in range(self.h):
                self.tiles.append(RndColor((i, j), parent=self))
        self.tiles[0] = Close((-1, 0), parent=self)
        self.tiles[1] = DesktopEntry((1, 1), (2, "gedit --new-window", "icons/gedit.png"), self)

    def initgeometry(self):
        self.w = (QApplication.desktop().width() - XPOS - XOFF) // (SUNIT)
        self.h = (QApplication.desktop().height() - YPOS - YOFF) // (SUNIT)
        if ALIGN == 'LB':
            self.dw = 0
            self.dh = (QApplication.desktop().height() - YPOS - YOFF) % (SUNIT)
        elif ALIGN == 'RT':
            self.dw = (QApplication.desktop().width() - XPOS - XOFF) % (SUNIT)
            self.dh = 0
        elif ALIGN == 'RB':
            self.dw = (QApplication.desktop().width() - XPOS - XOFF) % (SUNIT)
            self.dh = (QApplication.desktop().height() - YPOS - YOFF) % (SUNIT)
        else:
            self.dw = 0
            self.dh = 0
        self.usegeometry()

    def usegeometry(self):
        self.move(XPOS + self.dw, YPOS + self.dh)
        self.setFixedSize(self.w * SUNIT + SPC, self.h * SUNIT + SPC)

    def hideAll(self):
        for i in range(1, len(self.tiles)):
            self.tiles[i].hide()

    def showAll(self):
        for i in range(1, len(self.tiles)):
            self.tiles[i].show()

    def initstyle(self):
        self.setWindowIcon(QIcon('icon.gif'))
        self.setcolort(BACKGROUND_COLOR)
        if not TESTMODE:
            self.setWindowFlags(Qt.FramelessWindowHint |
                                Qt.NoDropShadowWindowHint |
                                Qt.WindowStaysOnBottomHint)
        elif TESTMODE == 1:
            self.setWindowFlags(Qt.FramelessWindowHint |
                                Qt.NoDropShadowWindowHint)
        elif TESTMODE == 2:
            pass
        if BACKGROUND_TRANSPARENT:
            self.setAutoFillBackground(False)
            self.setAttribute(Qt.WA_TranslucentBackground)
        if FULSCREEN:
            self.showFullScreen()

    def setcolort(self, colort):
        self.colort = colort
        self.setStyleSheet("background-color:rgba" + self.colort + ";")

    def onClicked(self, event):
        if self.layoutmode and self.movetile != None:
            self.movetile.x = (self.cursor().pos().x() - self.x()) // SUNIT
            self.movetile.y = (self.cursor().pos().y() - self.y()) // SUNIT
            self.movetile.move(self.movetile.x * SUNIT + SPC, self.movetile.y * SUNIT + SPC)
            self.movetile.sethold(0, self.movetile.dragholdcolor)
            self.movetile.movemode = False
            self.movetile = None

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Delete and self.layoutmode:
            self.movetile.close()
            self.tiles.remove(self.movetile)
            self.movetile = None
            self.repaint()
        else:
            pass

    def genImports(self, filename):
        out = open(filename, 'w')
        out.write(IMPORTS_BEGIN)
        for tile in self.tiles:
            out.write(tile.getParamsStr())

    def inittray(self):
        menu = QMenu()
        menu.addAction("Add tile", self.mAddTile)
        menu.addAction("Add app", self.mAddDE)
        self.lmaction = menu.addAction("[ ] Layout mode", self.mLayoutMode)
        menu.addAction("Close", self.mClose)
        self.tray = QSystemTrayIcon(QIcon('icons/maintile.png'))
        self.tray.show()
        self.tray.setContextMenu(menu)
        self.tray.activated.connect(self.trayclicked)
        self.tray.show()

    def mClose(self):
        self.genImports('imports.py')
        self.close()

    def mLayoutMode(self):
        self.layoutmode = not self.layoutmode
        # if self.layoutmode:
        #     pass
        #     #self.lmaction.setText('[*] Layout mode')
        # else:
        #     pass
        #     #self.lmaction.setText('[ ] Layout mode')

    def mAddTile(self):
        d = addTileDialog()
        if d.exec() == QDialog.Accepted:
            tile = d.output[0]
            xy = (d.output[1][0], d.output[1][1])
            ext = d.output[1][2]
            newtile = tile(xy, parent=self, extra=ext)
            self.tiles.append(newtile)
            self.tiles[-1].show()
            self.repaint()
        else:
            pass

    def mAddDE(self):
        d = addDEDialog()
        if d.exec() == QDialog.Accepted:
            tile = DesktopEntry
            xy = (-2, -2)
            ext = d.output
            newtile = tile(xy, parent=self, extra=ext)
            self.tiles.append(newtile)
            self.tiles[-1].show()
            self.repaint()
        else:
            pass

    def trayclicked(self, reason):
        if reason == QSystemTrayIcon.Context:
            if self.layoutmode:
                self.lmaction.setText('[*] Layout mode')
            else:
                self.lmaction.setText('[ ] Layout mode')
        if reason == QSystemTrayIcon.Trigger:
            if self.ismin:
                self.ismin = False
                if FULSCREEN:
                    self.showFullScreen()
                else:
                    self.show()
            else:
                self.ismin = True
                self.hide()
Esempio n. 47
0
class SystemTrayIcon(QMainWindow):
    def __init__(self, parent=None):
        super(SystemTrayIcon, self).__init__(parent)
        self.setAttribute(Qt.WA_DeleteOnClose)
        self.settings = QSettings()
        self.language = self.settings.value('Language') or ''
        self.temp_decimal_bool = self.settings.value('Decimal') or False
        # initialize the tray icon type in case of first run: issue#42
        self.tray_type = self.settings.value('TrayType') or 'icon&temp'
        cond = conditions.WeatherConditions()
        self.temporary_city_status = False
        self.conditions = cond.trans
        self.clouds = cond.clouds
        self.wind = cond.wind
        self.wind_dir = cond.wind_direction
        self.wind_codes = cond.wind_codes
        self.inerror = False
        self.tentatives = 0
        self.baseurl = 'http://api.openweathermap.org/data/2.5/weather?id='
        self.accurate_url = 'http://api.openweathermap.org/data/2.5/find?q='
        self.forecast_url = ('http://api.openweathermap.org/data/2.5/forecast/'
                             'daily?id=')
        self.day_forecast_url = ('http://api.openweathermap.org/data/2.5/'
                                 'forecast?id=')
        self.wIconUrl = 'http://openweathermap.org/img/w/'
        apikey = self.settings.value('APPID') or ''
        self.appid = '&APPID=' + apikey
        self.forecast_icon_url = self.wIconUrl
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.refresh)
        self.menu = QMenu()
        self.citiesMenu = QMenu(self.tr('Cities'))
        self.tempCityAction = QAction(self.tr('&Temporary city'), self)
        self.refreshAction = QAction(self.tr('&Update'), self)
        self.settingsAction = QAction(self.tr('&Settings'), self)
        self.aboutAction = QAction(self.tr('&About'), self)
        self.exitAction = QAction(self.tr('Exit'), self)
        self.exitAction.setIcon(QIcon(':/exit'))
        self.aboutAction.setIcon(QIcon(':/info'))
        self.refreshAction.setIcon(QIcon(':/refresh'))
        self.settingsAction.setIcon(QIcon(':/configure'))
        self.tempCityAction.setIcon(QIcon(':/tempcity'))
        self.citiesMenu.setIcon(QIcon(':/bookmarks'))
        self.menu.addAction(self.settingsAction)
        self.menu.addAction(self.refreshAction)
        self.menu.addMenu(self.citiesMenu)
        self.menu.addAction(self.tempCityAction)
        self.menu.addAction(self.aboutAction)
        self.menu.addAction(self.exitAction)
        self.settingsAction.triggered.connect(self.config)
        self.exitAction.triggered.connect(qApp.quit)
        self.refreshAction.triggered.connect(self.manual_refresh)
        self.aboutAction.triggered.connect(self.about)
        self.tempCityAction.triggered.connect(self.tempcity)
        self.systray = QSystemTrayIcon()
        self.systray.setContextMenu(self.menu)
        self.systray.activated.connect(self.activate)
        self.systray.setIcon(QIcon(':/noicon'))
        self.systray.setToolTip(self.tr('Searching weather data...'))
        self.notification = ''
        self.notification_temp = 0
        self.notifications_id = ''
        self.systray.show()
        # The dictionnary has to be intialized here. If there is an error
        # the program couldn't become functionnal if the dictionnary is
        # reinitialized in the weatherdata method
        self.weatherDataDico = {}
        # The traycolor has to be initialized here for the case when we cannot
        # reach the tray method (case: set the color at first time usage)
        self.traycolor = ''
        self.refresh()

    def icon_loading(self):
        self.gif_loading = QMovie(":/loading")
        self.gif_loading.frameChanged.connect(self.update_gif)
        self.gif_loading.start()

    def update_gif(self):
        gif_frame = self.gif_loading.currentPixmap()
        self.systray.setIcon(QIcon(gif_frame))

    def manual_refresh(self):
        self.tentatives = 0
        self.refresh()

    def cities_menu(self):
        # Don't add the temporary city in the list
        if self.temporary_city_status:
            return
        self.citiesMenu.clear()
        cities = self.settings.value('CityList') or []
        if type(cities) is str:
            cities = eval(cities)
        try:
            current_city = (self.settings.value('City') + '_' +
                        self.settings.value('Country') + '_' +
                        self.settings.value('ID'))
        except:
            # firsttime run,if clic cancel in setings without any city configured
            pass
        # Prevent duplicate entries
        try:
            city_toadd = cities.pop(cities.index(current_city))
        except:
            city_toadd = current_city
        finally:
            cities.insert(0, city_toadd)
        # If we delete all cities it results to a '__'
        if (cities is not None and cities != '' and cities != '[]' and
                cities != ['__']):
            if type(cities) is not list:
                # FIXME sometimes the list of cities is read as a string (?)
                # eval to a list
                cities = eval(cities)
            # Create the cities list menu
            for city in cities:
                action = QAction(city, self)
                action.triggered.connect(partial(self.changecity, city))
                self.citiesMenu.addAction(action)
        else:
            self.empty_cities_list()

    @pyqtSlot(str)
    def changecity(self, city):
        cities_list = self.settings.value('CityList')
        logging.debug('Cities' + str(cities_list))
        if cities_list is None:
            self.empty_cities_list()
        if type(cities_list) is not list:
            # FIXME some times is read as string (?)
            cities_list = eval(cities_list)
        prev_city = (self.settings.value('City') + '_' +
                     self.settings.value('Country') + '_' +
                     self.settings.value('ID'))
        citytoset = ''
        # Set the chosen city as the default
        for town in cities_list:
            if town == city:
                ind = cities_list.index(town)
                citytoset = cities_list[ind]
                citytosetlist = citytoset.split('_')
                self.settings.setValue('City', citytosetlist[0])
                self.settings.setValue('Country', citytosetlist[1])
                self.settings.setValue('ID', citytosetlist[2])
                if prev_city not in cities_list:
                    cities_list.append(prev_city)
                self.settings.setValue('CityList', cities_list)
                logging.debug(cities_list)
        self.refresh()

    def empty_cities_list(self):
        self.citiesMenu.addAction(self.tr('Empty list'))

    def refresh(self):
        self.inerror = False
        self.window_visible = False
        self.systray.setIcon(QIcon(':/noicon'))
        if hasattr(self, 'overviewcity'):
            # if visible, it has to ...remain visible
            # (try reason) Prevent C++ wrapper error
            try:
                if not self.overviewcity.isVisible():
                    # kills the reference to overviewcity
                    # in order to be refreshed
                    self.overviewcity.close()
                    del self.overviewcity
                else:
                    self.overviewcity.close()
                    self.window_visible = True
            except:
                pass
        self.systray.setToolTip(self.tr('Fetching weather data ...'))
        self.city = self.settings.value('City') or ''
        self.id_ = self.settings.value('ID') or None
        if self.id_ is None:
            # Clear the menu, no cities configured
            self.citiesMenu.clear()
            self.empty_cities_list()
            # Sometimes self.overviewcity is in namespace but deleted
            try:
                self.overviewcity.close()
            except:
                e = sys.exc_info()[0]
                logging.error('Error closing overviewcity: ' + str(e))
                pass
            self.timer.singleShot(2000, self.firsttime)
            self.id_ = ''
            self.systray.setToolTip(self.tr('No city configured'))
            return
        # A city has been found, create the cities menu now
        self.cities_menu()
        self.country = self.settings.value('Country') or ''
        self.unit = self.settings.value('Unit') or 'metric'
        self.suffix = ('&mode=xml&units=' + self.unit + self.appid)
        self.interval = int(self.settings.value('Interval') or 30)*60*1000
        self.timer.start(self.interval)
        self.update()

    def firsttime(self):
        self.temp = ''
        self.wIcon = QPixmap(':/noicon')
        self.systray.showMessage(
            'meteo-qt:\n', self.tr('No city has been configured yet.') +
            '\n' + self.tr('Right click on the icon and click on Settings.'))

    def update(self):
        if hasattr(self, 'downloadThread'):
            if self.downloadThread.isRunning():
                logging.debug('remaining thread...')
                return
        logging.debug('Update...')
        self.icon_loading()
        self.wIcon = QPixmap(':/noicon')
        self.downloadThread = Download(
            self.wIconUrl, self.baseurl, self.forecast_url,
            self.day_forecast_url, self.id_, self.suffix)
        self.downloadThread.wimage['PyQt_PyObject'].connect(self.makeicon)
        self.downloadThread.finished.connect(self.tray)
        self.downloadThread.xmlpage['PyQt_PyObject'].connect(self.weatherdata)
        self.downloadThread.forecast_rawpage.connect(self.forecast)
        self.downloadThread.day_forecast_rawpage.connect(self.dayforecast)
        self.downloadThread.uv_signal.connect(self.uv)
        self.downloadThread.error.connect(self.error)
        self.downloadThread.done.connect(self.done, Qt.QueuedConnection)
        self.downloadThread.start()

    def uv(self, value):
        self.uv_coord = value

    def forecast(self, data):
        self.forecast_data = data

    def dayforecast(self, data):
        self.dayforecast_data = data

    def instance_overviewcity(self):
        try:
            self.inerror = False
            if hasattr(self, 'overviewcity'):
                logging.debug('Deleting overviewcity instance...')
                del self.overviewcity
            self.overviewcity = overview.OverviewCity(
                self.weatherDataDico, self.wIcon, self.forecast_data,
                self.dayforecast_data, self.unit, self.forecast_icon_url,
                self.uv_coord, self)
            self.overviewcity.closed_status_dialogue.connect(self.remove_object)
        except:
            self.inerror = True
            e = sys.exc_info()[0]
            logging.error('Error: ' + str(e))
            logging.debug('Try to create the city overview...\nAttempts: ' +
                          str(self.tentatives))
            return 'error'

    def remove_object(self):
        del self.overviewcity

    def done(self, done):
        if done == 0:
            self.inerror = False
        elif done == 1:
            self.inerror = True
            logging.debug('Trying to retrieve data ...')
            self.timer.singleShot(10000, self.try_again)
            return
        if hasattr(self, 'updateicon'):
            # Keep a reference of the image to update the icon in overview
            self.wIcon = self.updateicon
        if hasattr(self, 'forecast_data'):
            if hasattr(self, 'overviewcity'):
                # Update also the overview dialog if open
                if self.overviewcity.isVisible():
                    # delete dialog to prevent memory leak
                    self.overviewcity.close()
                    self.instance_overviewcity()
                    self.overview()
            elif self.window_visible is True:
                self.instance_overviewcity()
                self.overview()
            else:
                self.inerror = True
                self.try_create_overview()
        else:
            self.try_again()

    def try_create_overview(self):
        logging.debug('Tries to create overview :' + str(self.tentatives))
        instance = self.instance_overviewcity()
        if instance == 'error':
            self.inerror = True
            self.refresh()
        else:
            self.tentatives = 0
            self.inerror = False
            self.tooltip_weather()

    def try_again(self):
        self.nodata_message()
        logging.debug('Attempts: ' + str(self.tentatives))
        self.tentatives += 1
        self.timer.singleShot(5000, self.refresh)

    def nodata_message(self):
        nodata = QCoreApplication.translate(
            "Tray icon", "Searching for weather data...",
            "Tooltip (when mouse over the icon")
        self.systray.setToolTip(nodata)
        self.notification = nodata

    def error(self, error):
        logging.error('Error:\n' + str(error))
        self.nodata_message()
        self.timer.start(self.interval)
        self.inerror = True

    def makeicon(self, data):
        image = QImage()
        image.loadFromData(data)
        self.wIcon = QPixmap(image)
        # Keep a reference of the image to update the icon in overview
        self.updateicon = self.wIcon

    def weatherdata(self, tree):
        if self.inerror:
            return
        self.tempFloat = tree[1].get('value')
        self.temp = ' ' + str(round(float(self.tempFloat))) + '°'
        self.temp_decimal = '{0:.1f}'.format(float(self.tempFloat)) + '°'
        self.meteo = tree[8].get('value')
        meteo_condition = tree[8].get('number')
        try:
            self.meteo = self.conditions[meteo_condition]
        except:
            logging.debug('Cannot find localisation string for'
                          'meteo_condition:' + str(meteo_condition))
            pass
        clouds = tree[5].get('name')
        clouds_percent = tree[5].get('value') + '%'
        try:
            clouds = self.clouds[clouds]
            clouds = self.conditions[clouds]
        except:
            logging.debug('Cannot find localisation string for clouds:' +
                          str(clouds))
            pass
        wind = tree[4][0].get('name').lower()
        try:
            wind = self.wind[wind]
            wind = self.conditions[wind]
        except:
            logging.debug('Cannot find localisation string for wind:' +
                          str(wind))
            pass
        wind_codes = tree[4][2].get('code')
        try:
            wind_codes = self.wind_codes[wind_codes]
        except:
            logging.debug('Cannot find localisation string for wind_codes:' +
                          str(wind_codes))
            pass
        wind_dir = tree[4][2].get('name')
        try:
            wind_dir = self.wind_dir[tree[4][2].get('code')]
        except:
            logging.debug('Cannot find localisation string for wind_dir:' +
                          str(wind_dir))
            pass
        self.city_weather_info = (self.city + ' ' + self.country + ' ' +
                                  self.temp_decimal + ' ' + self.meteo)
        self.tooltip_weather()
        self.notification = self.city_weather_info
        self.weatherDataDico['City'] = self.city
        self.weatherDataDico['Country'] = self.country
        self.weatherDataDico['Temp'] = self.tempFloat + '°'
        self.weatherDataDico['Meteo'] = self.meteo
        self.weatherDataDico['Humidity'] = (tree[2].get('value'),
                                            tree[2].get('unit'))
        self.weatherDataDico['Wind'] = (
            tree[4][0].get('value'), wind, str(int(float(tree[4][2].get('value')))),
            wind_codes, wind_dir)
        self.weatherDataDico['Clouds'] = (clouds_percent + ' ' + clouds)
        self.weatherDataDico['Pressure'] = (tree[3].get('value'),
                                            tree[3].get('unit'))
        self.weatherDataDico['Humidity'] = (tree[2].get('value'),
                                            tree[2].get('unit'))
        self.weatherDataDico['Sunrise'] = tree[0][2].get('rise')
        self.weatherDataDico['Sunset'] = tree[0][2].get('set')
        rain_value = tree[7].get('value')
        if rain_value == None:
            rain_value = ''
        self.weatherDataDico['Precipitation'] = (tree[7].get('mode'), rain_value)

    def tooltip_weather(self):
        self.systray.setToolTip(self.city_weather_info)

    def tray(self):
        temp_decimal = eval(self.settings.value('Decimal') or 'False')
        try:
            if temp_decimal:
                temp_tray = self.temp_decimal
            else:
                temp_tray = self.temp
        except:
            # First time launch
            return
        if self.inerror or not hasattr(self, 'temp'):
            logging.critical('Cannot paint icon!')
            if hasattr(self, 'overviewcity'):
                try:
                    # delete dialog to prevent memory leak
                    self.overviewcity.close()
                except:
                    pass
            return
        try:
            self.gif_loading.stop()
        except:
            # In first time run the gif is not animated
            pass
        logging.debug('Paint tray icon...')
        # Place empty.png here to initialize the icon
        # don't paint the T° over the old value
        icon = QPixmap(':/empty')
        self.traycolor = self.settings.value('TrayColor') or ''
        self.fontsize = self.settings.value('FontSize') or '18'
        self.tray_type = self.settings.value('TrayType') or 'icon&temp'
        pt = QPainter()
        pt.begin(icon)
        if self.tray_type != 'temp':
            pt.drawPixmap(0, -12, 64, 64, self.wIcon)
        pt.setFont(QFont('sans-sertif', int(self.fontsize)))
        pt.setPen(QColor(self.traycolor))
        if self.tray_type == 'icon&temp':
            pt.drawText(icon.rect(), Qt.AlignBottom | Qt.AlignCenter,
                        str(temp_tray))
        if self.tray_type == 'temp':
            pt.drawText(icon.rect(), Qt.AlignCenter, str(temp_tray))
        pt.end()
        if self.tray_type == 'icon':
            self.systray.setIcon(QIcon(self.wIcon))
        else:
            self.systray.setIcon(QIcon(icon))
        try:
            if not self.overviewcity.isVisible():
                notifier = self.settings.value('Notifications') or 'True'
                notifier = eval(notifier)
                if notifier:
                    temp = int(re.search('\d+', self.temp_decimal).group())
                    if temp != self.notification_temp or self.id_ != self.notifications_id:
                        self.notifications_id = self.id_
                        self.notification_temp = temp
                        self.systray.showMessage('meteo-qt', self.notification)
        except:
            logging.debug('OverviewCity has been deleted' +
                          'Download weather information again...')
            self.try_again()
            return
        self.restore_city()
        self.tentatives = 0
        self.tooltip_weather()
        logging.info('Actual weather status for: ' + self.notification)

    def restore_city(self):
        if self.temporary_city_status:
            logging.debug('Restore the default settings (city)' +
                          'Forget the temporary city...')
            for e in ('ID', self.id_2), ('City', self.city2), ('Country', self.country2):
                self.citydata(e)
            self.temporary_city_status = False

    def activate(self, reason):
        if reason == 3:
            if self.inerror or self.id_ is None or self.id_ == '':
                return
            try:
                if hasattr(self, 'overviewcity') and self.overviewcity.isVisible():
                    self.overviewcity.hide()
                else:
                    self.overviewcity.hide()
                    # If dialog closed by the "X"
                    self.done(0)
                    self.overview()
            except:
                self.done(0)
                self.overview()
        elif reason == 1:
            self.menu.popup(QCursor.pos())

    def overview(self):
        if self.inerror or len(self.weatherDataDico) == 0:
            return
        self.overviewcity.show()

    def config_save(self):
        logging.debug('Config saving...')
        city = self.settings.value('City'),
        id_ = self.settings.value('ID')
        country = self.settings.value('Country')
        unit = self.settings.value('Unit')
        traycolor = self.settings.value('TrayColor')
        tray_type = self.settings.value('TrayType')
        fontsize = self.settings.value('FontSize')
        language = self.settings.value('Language')
        decimal = self.settings.value('Decimal')
        self.appid = '&APPID=' + self.settings.value('APPID') or ''
        if language != self.language and language is not None:
            self.systray.showMessage('meteo-qt:',QCoreApplication.translate(
                    "System tray notification",
                    "The application has to be restarted to apply the language setting", ''))
            self.language = language
        # Check if update is needed
        if traycolor is None:
            traycolor = ''
        if (self.traycolor != traycolor or self.tray_type != tray_type or
                self.fontsize != fontsize or decimal != self.temp_decimal):
            self.tray()
        if (city[0] == self.city and
           id_ == self.id_ and
           country == self.country and
           unit == self.unit):
            return
        else:
            logging.debug('Apply changes from settings...')
            self.refresh()

    def config(self):
        dialog = settings.MeteoSettings(self.accurate_url, self.appid, self)
        dialog.applied_signal.connect(self.config_save)
        if dialog.exec_() == 1:
            self.config_save()
            logging.debug('Update Cities menu...')
            self.cities_menu()

    def tempcity(self):
        # Prevent to register a temporary city
        # This happen when a temporary city is still loading
        self.restore_city()
        dialog = searchcity.SearchCity(self.accurate_url, self.appid, self)
        self.id_2, self.city2, self.country2 = (self.settings.value('ID'),
                                                self.settings.value('City'),
                                                self.settings.value('Country'))
        dialog.id_signal[tuple].connect(self.citydata)
        dialog.city_signal[tuple].connect(self.citydata)
        dialog.country_signal[tuple].connect(self.citydata)
        if dialog.exec_():
            self.temporary_city_status = True
            self.systray.setToolTip(self.tr('Fetching weather data...'))
            self.refresh()

    def citydata(self, what):
        self.settings.setValue(what[0], what[1])
        logging.debug('write ' + str(what[0]) + ' ' + str(what[1]))

    def about(self):
        title = self.tr("""<b>meteo-qt</b> v{0}
            <br/>License: GPLv3
            <br/>Python {1} - Qt {2} - PyQt {3} on {4}""").format(
                __version__, platform.python_version(),
                QT_VERSION_STR, PYQT_VERSION_STR, platform.system())
        image = ':/logo'
        text = self.tr("""<p>Author: Dimitrios Glentadakis <a href="mailto:[email protected]">[email protected]</a>
                        <p>A simple application showing the weather status
                        information on the system tray.
                        <p>Website: <a href="https://github.com/dglent/meteo-qt">
                        https://github.com/dglent/meteo-qt</a>
                        <br/>Data source: <a href="http://openweathermap.org/">
                        OpenWeatherMap</a>.
                        <br/>This software uses icons from the
                        <a href="http://www.kde.org/">Oxygen Project</a>.
                        <p>To translate meteo-qt in your language or contribute to
                        current translations, you can use the
                        <a href="https://www.transifex.com/projects/p/meteo-qt/">
                        Transifex</a> platform.
                        <p>If you want to report a dysfunction or a suggestion,
                        feel free to open an issue in <a href="https://github.com/dglent/meteo-qt/issues">
                        github</a>.""")

        contributors = QCoreApplication.translate("About dialog", """
            Pavel Fric<br/>
            [cs] Czech translation
            <p>Jürgen <a href="mailto:[email protected]">[email protected]</a><br/>
            [de] German translation
            <p>Peter Mattern <a href="mailto:[email protected]">[email protected]</a><br/>
            [de] German translation, Project
            <p>Dimitrios Glentadakis <a href="mailto:[email protected]">[email protected]</a><br/>
            [el] Greek translation
            <p>Ozkar L. Garcell <a href="mailto:[email protected]">[email protected]</a><br/>
            [es] Spanish translation
            <p>Laurene Albrand <a href="mailto:[email protected]">[email protected]</a><br/>
            [fr] French translation
            <p>Rémi Verschelde <a href="mailto:[email protected]">[email protected]</a><br/>
            [fr] French translation, Project
            <p>Daniel Napora <a href="mailto:[email protected]">[email protected]</a><br/>
            Tomasz Przybył <a href="mailto:[email protected]">[email protected]</a><br/>
            [pl] Polish translation
            <p>Artem Vorotnikov <a href="mailto:[email protected]">[email protected]</a><br/>
            [ru] Russian translation
            <p>Atilla Öntaş <a href="mailto:[email protected]">[email protected]</a><br/>
            [tr] Turkish translation
            <p>Yuri Chornoivan <a href="mailto:[email protected]">[email protected]</a><br/>
            [uk] Ukrainian translation
            <p>You-Cheng Hsieh <a href="mailto:[email protected]">[email protected]</a><br/>
            [zh_TW] Chinese (Taiwan) translation
            <p>pmav99<br/>
            Project""", "List of contributors")

        dialog = about_dlg.AboutDialog(title, text, image, contributors, self)
        dialog.exec_()
Esempio n. 48
0
class NetDotTsinghuaApplication(QApplication):
    """NetDotTsinghuaApplication"""
    start_worker = pyqtSignal()
    username_changed = pyqtSignal(str)
    update_all = pyqtSignal()

    def __init__(self, argv):
        super().__init__(argv)
        icon = QIcon(":/icon.png")

        self.setQuitOnLastWindowClosed(False)  # Run without windows.
        self.setWindowIcon(icon)
        self.account_setting_dialog = None

        self.worker = Worker()
        self.worker_thread = QThread()
        self.worker.moveToThread(self.worker_thread)

        # For convenience.
        worker = self.worker
        config = worker.config
        acc = worker.account

        # Set up tray menu.
        self.tray = QSystemTrayIcon(icon, self)
        self.tray_menu = QMenu()

        # Status section.
        self.status_action = self.add_unabled_action()
        self.status_changed(worker.account.status)
        self.status = acc.status
        self.last_session = None

        # Account info section.
        self.tray_menu.addSeparator()
        self.username_action = self.add_unabled_action()
        self.usage_action = self.add_unabled_action()
        self.balance_action = self.add_unabled_action()
        self.refresh_username(config['username'])
        self.refresh_account_info(None, None)

        # Sessions section.
        self.sessions = []
        self.session_menus = []
        self.last_check = None

        self.tray_menu.addSeparator()
        self.sessions_title_action = self.add_unabled_action()
        self.last_check_action = self.add_unabled_action()

        self.refresh_sessions([])

        # Actions.
        self.tray_menu.addSeparator()
        self.tray_menu.addAction('上线').triggered.connect(acc.login)
        self.tray_menu.addAction('下线').triggered.connect(acc.logout)
        self.tray_menu.addAction('现在刷新').triggered.connect(acc.update_all)

        # Config section.
        self.tray_menu.addSeparator()
        self.auto_manage_action = self.tray_menu.addAction('自动管理')
        self.auto_manage_action.setCheckable(True)
        self.auto_manage_action.setChecked(config['auto_manage'])
        self.auto_manage_action.toggled.connect(worker.auto_manage_changed)

        self.account_setting_action = self.tray_menu.addAction('账号设置...')
        self.account_setting_action.triggered.connect(self.account_setting)

        # About.
        self.tray_menu.addSeparator()
        self.tray_menu.addAction('关于').triggered.connect(self.show_about)

        # Quit.
        self.tray_menu.addSeparator()
        self.tray_menu.addAction('退出').triggered.connect(self.quit)

        self.tray.setContextMenu(self.tray_menu)
        self.tray.show()

        # Connect signals.
        self.start_worker.connect(worker.setup)
        self.username_changed.connect(self.refresh_username)
        self.username_changed.connect(worker.username_changed)
        self.update_all.connect(acc.update_all)

        acc.status_changed.connect(self.status_changed)
        acc.info_updated.connect(self.refresh_account_info)
        acc.last_session_updated.connect(self.last_session_changed)
        acc.sessions_updated.connect(self.refresh_sessions)

        # About to show.
        self.tray_menu.aboutToShow.connect(self.update_time)
        self.tray_menu.aboutToShow.connect(self.refresh_status)

    def add_unabled_action(self, text=''):
        action = self.tray_menu.addAction(text)
        action.setEnabled(False)
        return action

    def exec(self):
        self.worker_thread.start()
        self.start_worker.emit()  # Start timers & check status.

        logging.debug('GUI thread enters event loop')
        return super().exec()

    def refresh_status(self):
        logging.debug('Refreshing status in the menu')

        s = STATUS_STR[self.status]
        # Show session usage if possible.
        if self.last_session and self.status in ('ONLINE',
                                                 'OTHERS_ACCOUNT_ONLINE'):
            s = s + ' - ' + _usage_str(self.last_session.byte)

        self.status_action.setText(s)

    def refresh_username(self, username):
        logging.debug('Refreshing username in the menu')
        if not username:
            self.username_action.setText('未设置账号')
            self.usage_action.setVisible(False)
            self.balance_action.setVisible(False)
        else:
            self.username_action.setText(username)
            self.usage_action.setVisible(True)
            self.balance_action.setVisible(True)

    def refresh_account_info(self, balance, byte):
        logging.debug('Refreshing account info section in the menu')

        self.usage_action.setText('本月流量:{}'.format(_usage_str(byte)))
        self.balance_action.setText('当前余额:{}'.format(_balance_str(balance)))

    def status_changed(self, status):
        # Show tray message.
        if status == 'ONLINE':
            self.tray.showMessage('当前在线', '本人账号在线')
        elif status == 'OTHERS_ACCOUNT_ONLINE':
            self.tray.showMessage('当前在线', '他人账号在线')
        elif status == 'OFFLINE':
            self.tray.showMessage('当前离线', '可以登录校园网')

        self.status = status

    def last_session_changed(self, session):
        self.last_session = session

    def refresh_sessions(self, sessions):
        logging.debug('Refreshing sessions section in the menu')

        self.sessions = sessions
        self.last_check = datetime.now()

        if len(sessions):
            self.sessions_title_action.setText('当前在线')
        else:
            self.sessions_title_action.setText('无设备在线')

        # Remove old actions
        for menu in self.session_menus:
            self.tray_menu.removeAction(menu.menuAction())
        self.session_menus.clear()

        # Add new actions.
        for session in sessions:
            menu = SessionMenu(self.worker.account, session)
            self.tray_menu.insertMenu(self.last_check_action,
                                      menu).setText(session.device_name)
            self.session_menus.append(menu)

    def update_time(self):
        self.last_check_action.setText(
            '上次更新:{}'.format(_time_passed_str(self.last_check)))

    @pyqtSlot()
    def account_setting(self):
        if self.account_setting_dialog is None:
            self.account_setting_dialog = AccountSettingDialog()
            existed = False
        else:
            existed = True

        dialog = self.account_setting_dialog
        dialog.show()
        dialog.raise_()
        dialog.activateWindow()

        if existed:  # Avoid multiple dialogs.
            return

        if dialog.exec():
            username = dialog.username.text()
            # Set password if needed.
            if username:
                acc = Account(username)
                acc.password = dialog.password.text()

            if username != self.worker.account.username:
                # If username changed, emit signal and clear current account info.
                self.username_changed.emit(username)
                self.refresh_account_info(None, None)
            else:
                # Update all because password might has changed.
                self.update_all.emit()

        self.account_setting_dialog = None

    @pyqtSlot()
    def show_about(self):
        msg = """<p><b>net.tsinghua {}</b><br>
<small>Copyright Ⓒ 2015 Thomas Lee</small></p>

<p><a href="https://github.com/ThomasLee969/net.tsinghua">Github 主页</a>
</p>""".format(__VERSION__)

        QMessageBox.about(None, '关于 net.tsinghua', msg)
Esempio n. 49
0
class TrayIcon(QObject):

    def __init__(self):
        super().__init__()
        self._supported = QSystemTrayIcon.isSystemTrayAvailable()
        self._context_menu = None
        self._enabled = False
        self._trayicon = None
        self._state_icons = {}
        for state in (
            'disconnected',
            'disabled',
            'enabled',
        ):
            icon = QIcon(':/state-%s.svg' % state)
            if hasattr(icon, 'setIsMask'):
                icon.setIsMask(True)
            self._state_icons[state] = icon
        self._machine = None
        self._machine_state = 'disconnected'
        self._is_running = False
        self._update_state()

    def set_menu(self, menu):
        self._context_menu = menu
        if self._enabled:
            self._trayicon.setContextMenu(menu)

    def log(self, level, message):
        if self._enabled:
            if level <= log.INFO:
                icon = QSystemTrayIcon.Information
                timeout = 10
            elif level <= log.WARNING:
                icon = QSystemTrayIcon.Warning
                timeout = 15
            else:
                icon = QSystemTrayIcon.Critical
                timeout = 25
            self._trayicon.showMessage(__software_name__.capitalize(),
                                       message, icon, timeout * 1000)
        else:
            if level <= log.INFO:
                icon = QMessageBox.Information
            elif level <= log.WARNING:
                icon = QMessageBox.Warning
            else:
                icon = QMessageBox.Critical
            msgbox = QMessageBox()
            msgbox.setText(message)
            msgbox.setIcon(icon)
            msgbox.exec_()

    def is_supported(self):
        return self._supported

    def enable(self):
        if not self._supported:
            return
        self._trayicon = QSystemTrayIcon()
        # On OS X, the context menu is activated with either mouse buttons,
        # and activation messages are still sent, so ignore those...
        if not sys.platform.startswith('darwin'):
            self._trayicon.activated.connect(self._on_activated)
        if self._context_menu is not None:
            self._trayicon.setContextMenu(self._context_menu)
        self._enabled = True
        self._update_state()
        self._trayicon.show()

    def disable(self):
        if not self._enabled:
            return
        self._trayicon.hide()
        self._trayicon = None
        self._enabled = False

    def is_enabled(self):
        return self._enabled

    def update_machine_state(self, machine, state):
        self._machine = machine
        self._machine_state = state
        self._update_state()

    def update_output(self, enabled):
        self._is_running = enabled
        self._update_state()

    clicked = pyqtSignal()

    def _update_state(self):
        if self._machine_state not in ('initializing', 'connected'):
            state = 'disconnected'
        else:
            state = 'enabled' if self._is_running else 'disabled'
        icon = self._state_icons[state]
        if not self._enabled:
            return
        machine_state = _('{machine} is {state}').format(
            machine=_(self._machine),
            state=_(self._machine_state),
        )
        if self._is_running:
            output_state = _('output is enabled')
        else:
            output_state = _('output is disabled')
        self._trayicon.setIcon(icon)
        self._trayicon.setToolTip(
            'Plover:\n- %s\n- %s' % (output_state, machine_state)
        )

    def _on_activated(self, reason):
        if reason == QSystemTrayIcon.Trigger:
            self.clicked.emit()
Esempio n. 50
0
class MainWindow(QWidget):
    """ Main window of application. It is represented by icon in
    taskbar.

    Useful attributes
    -----------------
    addWindow : AddWindow object
    addActive : boolean
        If user wants to add new task, 'addWindow' becomes the QWidget for
        it, and while it is active 'addActive' remains True.
    editWindow : EditWindow object
    editActive : boolean
        If user wants to edit tasks, 'editWindow' becomes the QWidget for
        it, and while it is active 'editActive' remains True.
    tray : QSystemTrayIcon object
        Tray icon and all its attributes like context menu and
        activated action.
    timer : QTimer object
        Timer that fires every second. If one reminder's time is up,
        shows message.
    backupTimer : QTimer object
        Timer that fires every 5 minutes. Saves current state of
        tasks file to backup file.

    """
    def __init__(self):
        """ Init GUI and all required things. """
        super().__init__()

        iconAdd = Icon(byte=icons.add).convertToIcon().getIcon()
        self.tray = QSystemTrayIcon(iconAdd, self)

        menu = QMenu()
        menu.addAction(conf.lang.ADD_ACTION,
                       lambda: self.showWindow(QSystemTrayIcon.Trigger))
        menu.addAction(conf.lang.EDIT_ACTION,
                       lambda: self.showWindow('editAction'))
        menu.addSeparator()
        menu.addAction(conf.lang.OPT_ACTION,
                       lambda: self.showWindow('optAction'))

        menu.addAction(conf.lang.RESTORE, self.restore)
        menu.addAction(conf.lang.QUIT, self.quit)

        self.tray.setContextMenu(menu)
        self.tray.activated.connect(self.showWindow)

        self.tray.show()
        self.addWindow = None
        self.addActive = False
        self.editWindow = None
        self.editActive = False
        self.optWindow = None
        self.optActive = False

        self.timer = QTimer()
        self.timer.timeout.connect(self.timerTick)
        self.timer.start(1000)

        self.backup()
        self.backupTimer = QTimer()
        self.backupTimer.timeout.connect(self.backup)
        self.backupTimer.start(conf.backup * 1000)

    def timerTick(self):
        """ Checks tasks entry's time if it is up. Shows message with
        entry's text if its time's up.

        """
        global tasks
        global rewrite
        for entry in tasks:
            date = entry.getDateTime()
            today = dt.datetime.today()
            if (date - today).days < 0:
                tasks.remove(entry)
                class EvMessageBox(QMessageBox):
                    """ QMessageBox with timer.

                    Parameters
                    ----------
                    text : string
                        Text of message.
                    title : string
                        Title of message window.
                    wicon : QIcon object
                        Icon of message window.
                    icon : QMessageBox.Icon int
                        Icon of message body.
                    timeout : int
                        Time for message has being shown.

                    Useful attributes
                    -----------------
                    timer : QTimer object
                        Timer attached to message.

                    """
                    def __init__(self, text, title, wicon, icon, timeout):
                        super().__init__()
                        self.timeout = timeout
                        self.setText(text)
                        self.setWindowTitle(title)
                        self.setWindowIcon(wicon)
                        self.setIcon(icon)
                        self.addButton(QPushButton(conf.lang.REPEAT.format(
                                                   parseSeconds(conf.tdelta))),
                                       QMessageBox.YesRole)
                        self.addButton(QPushButton(conf.lang.CLOSE),
                                       QMessageBox.NoRole)
                        self.setWindowFlags(Qt.WindowStaysOnTopHint)
                        # self.setTextFormat(Qt.RichText)
                        self.timer = QTimer()
                        self.timer.timeout.connect(self.timerTick)

                    def showEvent(self, event):
                        """ Start timer on message showEvent. """
                        self.currentTime = 0
                        self.timer.start(1000)

                    def timerTick(self):
                        """ Done message on timeout. """
                        self.currentTime += 1
                        if self.currentTime >= self.timeout:
                            self.timer.stop()
                            self.done(-1)

                msgBox = EvMessageBox(
                    entry.text,
                    '{} {}'.format(conf.lang.TASK, date),
                    Icon(byte=icons.alert).convertToIcon().getIcon(),
                    QMessageBox.Information,
                    conf.mesout)
                reply = msgBox.exec_()
                msgBox.raise_()

                if reply != 1:
                    td = conf.tdelta if reply == 0 else 300 - conf.mesout
                    date = dateToStr(dt.datetime.now() + dt.timedelta(0, td))
                    date['date'] = date['date'].replace('/', '.')
                    date['time'] = date['time'].replace('.', ':')
                    tasks.append(Entry(date['date'], date['time'], entry.text))
                rewrite()
                if self.editActive:
                    self.editWindow.filterApply()

    def showWindow(self, event):
        """ Show child windows.
        If event is QSystemTrayIcon.Trigger then it checks if
        all windows are not open and show addWindow.

        If event is 'addAction' it means that user from editWindow
        want to edit reminder, so it opens addWindow.

        Then it checks if addAction or editAction is True, and alert
        appropriate window.

        Then if event is 'editAction' then it opens editWindow.

        """
        if event == 'editAction':
            if self.editActive:
                QApplication.alert(self.editWindow)
            else:
                self.editWindow = EditWindow(self)
                self.editWindow.show()
                self.editWindow.setFocus(True)
                self.editWindow.activateWindow()
            return self.editWindow
        elif event == 'addAction':
            self.addWindow = AddWindow(self)
            self.addWindow.show()
            self.addWindow.setFocus(True)
            self.addWindow.activateWindow()
            return self.addWindow
        elif event == QSystemTrayIcon.Trigger:
            if self.addActive:
                QApplication.alert(self.addWindow)
            else:
                self.addWindow = AddWindow(self)
                self.addWindow.show()
                self.addWindow.setFocus(True)
                self.addWindow.activateWindow()
            return self.addWindow
        elif event == 'optAction':
            if self.addActive:
                self.addWindow.hide()
            if self.editActive:
                self.editWindow.hide()
            self.optWindow = OptionsWindow(self)
            self.optWindow.show()
            self.optWindow.setFocus(True)
            self.optWindow.activateWindow()

    def backup(self):
        """ Copies content of tasks file to backup file. """
        with open(backup, 'w') as to_, open(filename, 'r') as from_:
            to_.write(from_.read())

    def restore(self):
        """ Restores content of tasks file from backup file after
        user confirmation.

        """
        global tasks
        shure = QMessageBox.question(self, conf.lang.RESTORE,
                                     conf.lang.RESTORE_TEXT,
                                     QMessageBox.No | QMessageBox.Yes,
                                     QMessageBox.No)

        if shure == QMessageBox.No:
            pass
        else:
            temp = open(backup).read() # don't forget to read backup
            self.backup()
            with open(filename, 'w') as to_:
                to_.write(temp)
            tasks = []
            readTasks()
            if self.editActive:
                self.editWindow.filterApply()

    def quit(self, really=True):
        """ Quits application. Hides tray icon firstly.
        If really is not True, do not quits the application.
        It is used to re-launch the application.

        """
        self.tray.hide()
        self.timer.stop()
        self.backupTimer.stop()
        if really:
            QCoreApplication.instance().quit()
Esempio n. 51
0
class Qt4SysTrayIcon:
    def __init__(self):
        self.snapshots = snapshots.Snapshots()
        self.config = self.snapshots.config
        self.decode = None

        if len(sys.argv) > 1:
            if not self.config.setCurrentProfile(sys.argv[1]):
                logger.warning("Failed to change Profile_ID %s"
                               %sys.argv[1], self)

        self.qapp = qt4tools.createQApplication(self.config.APP_NAME)
        translator = qt4tools.translator()
        self.qapp.installTranslator(translator)
        self.qapp.setQuitOnLastWindowClosed(False)

        import icon
        self.icon = icon
        self.qapp.setWindowIcon(icon.BIT_LOGO)

        self.status_icon = QSystemTrayIcon(icon.BIT_LOGO)
        #self.status_icon.actionCollection().clear()
        self.contextMenu = QMenu()

        self.menuProfileName = self.contextMenu.addAction(_('Profile: "%s"') % self.config.profileName())
        qt4tools.setFontBold(self.menuProfileName)
        self.contextMenu.addSeparator()

        self.menuStatusMessage = self.contextMenu.addAction(_('Done'))
        self.menuProgress = self.contextMenu.addAction('')
        self.menuProgress.setVisible(False)
        self.contextMenu.addSeparator()

        self.btnPause = self.contextMenu.addAction(icon.PAUSE, _('Pause snapshot process'))
        action = lambda: os.kill(self.snapshots.pid(), signal.SIGSTOP)
        self.btnPause.triggered.connect(action)

        self.btnResume = self.contextMenu.addAction(icon.RESUME, _('Resume snapshot process'))
        action = lambda: os.kill(self.snapshots.pid(), signal.SIGCONT)
        self.btnResume.triggered.connect(action)
        self.btnResume.setVisible(False)

        self.btnStop = self.contextMenu.addAction(icon.STOP, _('Stop snapshot process'))
        self.btnStop.triggered.connect(self.onBtnStop)
        self.contextMenu.addSeparator()

        self.btnDecode = self.contextMenu.addAction(icon.VIEW_SNAPSHOT_LOG, _('decode paths'))
        self.btnDecode.setCheckable(True)
        self.btnDecode.setVisible(self.config.snapshotsMode() == 'ssh_encfs')
        self.btnDecode.toggled.connect(self.onBtnDecode)

        self.openLog = self.contextMenu.addAction(icon.VIEW_LAST_LOG, _('View Last Log'))
        self.openLog.triggered.connect(self.onOpenLog)
        self.startBIT = self.contextMenu.addAction(icon.BIT_LOGO, _('Start BackInTime'))
        self.startBIT.triggered.connect(self.onStartBIT)
        self.status_icon.setContextMenu(self.contextMenu)

        self.pixmap = icon.BIT_LOGO.pixmap(24)
        self.progressBar = QProgressBar()
        self.progressBar.setMinimum(0)
        self.progressBar.setMaximum(100)
        self.progressBar.setValue(0)
        self.progressBar.setTextVisible(False)
        self.progressBar.resize(24, 6)
        self.progressBar.render(self.pixmap, sourceRegion = QRegion(0, -14, 24, 6), flags = QWidget.RenderFlags(QWidget.DrawChildren))

        self.first_error = self.config.notify()
        self.popup = None
        self.last_message = None

        self.timer = QTimer()
        self.timer.timeout.connect(self.updateInfo)

        self.ppid = os.getppid()

    def prepairExit(self):
        self.timer.stop()

        if not self.status_icon is None:
            self.status_icon.hide()
            self.status_icon = None

        if not self.popup is None:
            self.popup.deleteLater()
            self.popup = None

        self.qapp.processEvents()

    def run(self):
        self.status_icon.show()
        self.timer.start(500)

        logger.info("[qt4systrayicon] begin loop", self)

        self.qapp.exec_()

        logger.info("[qt4systrayicon] end loop", self)

        self.prepairExit()

    def updateInfo(self):
        if not tools.processAlive(self.ppid):
            self.prepairExit()
            self.qapp.exit(0)
            return

        paused = tools.processPaused(self.snapshots.pid())
        self.btnPause.setVisible(not paused)
        self.btnResume.setVisible(paused)

        message = self.snapshots.takeSnapshotMessage()
        if message is None and self.last_message is None:
            message = (0, _('Working...'))

        if not message is None:
            if message != self.last_message:
                self.last_message = message
                if self.decode:
                    message = (message[0], self.decode.log(message[1]))
                self.menuStatusMessage.setText('\n'.join(tools.wrapLine(message[1],\
                                                                         size = 80,\
                                                                         delimiters = '',\
                                                                         new_line_indicator = '') \
                                                                       ))
                self.status_icon.setToolTip(message[1])

        pg = progress.ProgressFile(self.config)
        if pg.fileReadable():
            pg.load()
            percent = pg.intValue('percent')
            if percent != self.progressBar.value():
                self.progressBar.setValue(percent)
                self.progressBar.render(self.pixmap, sourceRegion = QRegion(0, -14, 24, 6), flags = QWidget.RenderFlags(QWidget.DrawChildren))
                self.status_icon.setIcon(QIcon(self.pixmap))

            self.menuProgress.setText(' | '.join(self.getMenuProgress(pg)))
            self.menuProgress.setVisible(True)
        else:
            self.status_icon.setIcon(self.icon.BIT_LOGO)
            self.menuProgress.setVisible(False)


    def getMenuProgress(self, pg):
        d = (('sent',   _('Sent:')), \
             ('speed',  _('Speed:')),\
             ('eta',    _('ETA:')))
        for key, txt in d:
            value = pg.strValue(key, '')
            if not value:
                continue
            yield txt + ' ' + value

    def onStartBIT(self):
        profileID = self.config.currentProfile()
        cmd = ['backintime-qt4',]
        if not profileID == '1':
            cmd += ['--profile-id', profileID]
        proc = subprocess.Popen(cmd)

    def onOpenLog(self):
        dlg = logviewdialog.LogViewDialog(self, systray = True)
        dlg.decode = self.decode
        dlg.cbDecode.setChecked(self.btnDecode.isChecked())
        dlg.exec_()

    def onBtnDecode(self, checked):
        if checked:
            self.decode = encfstools.Decode(self.config)
            self.last_message = None
            self.updateInfo()
        else:
            self.decode = None

    def onBtnStop(self):
        os.kill(self.snapshots.pid(), signal.SIGKILL)
        self.btnStop.setEnabled(False)
        self.btnPause.setEnabled(False)
        self.btnResume.setEnabled(False)
        self.snapshots.setTakeSnapshotMessage(0, 'Snapshot terminated')
Esempio n. 52
0
class Example(QMainWindow):

    def __init__(self):
        super().__init__()

        self.initUI()
        self.trayIcon = None
        self.kill = False
        self.setupTrayIcon()
        try:
            cherrypy_server.start_server()
        except Exception as e:
            logging.getLogger(__name__).warn("Problem starting print server! {}".format(e))
            traceback.print_exc()

    def reallyClose(self):
        self.kill = True
        self.close()

    def openConsole(self):
        from web.server import cfg
        url = r'https://localhost:{}'.format(cfg.port)
        webbrowser.open(url)


    def initUI(self):

        openAction = QAction("&Open Console", self)
        openAction.setShortcut('Ctrl+O')
        openAction.setStatusTip('Open Console')
        openAction.triggered.connect(self.openConsole)

        exitAction = QAction(QIcon(os.path.join('web', 'static', 'img', 'exit-icon-3.png')), '&Exit', self)
        exitAction.setShortcut('Ctrl+Q')
        exitAction.setStatusTip('Exit application')
        exitAction.triggered.connect(self.reallyClose)

        self.statusBar()

        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(openAction)
        fileMenu.addSeparator()
        fileMenu.addAction(exitAction)

        wrapper = QWidget()
        txt = QTextEdit()
        txt.setReadOnly(True)
        txt.setLineWrapMode(QTextEdit.NoWrap)
        txt.setUndoRedoEnabled(False)
        txt.setAcceptDrops(False)
        txt.setAcceptRichText(False)

        font = txt.font()
        font.setFamily("Courier")
        font.setPointSize(9)
        txt.setFont(font)

        policy = txt.sizePolicy()
        policy.setVerticalStretch(1)
        txt.setSizePolicy(policy)

        layout = QGridLayout()
        layout.addWidget(txt)
        wrapper.setLayout(layout)

        self.setCentralWidget(wrapper)

        def _write(s):
            txt.moveCursor(QTextCursor.End)
            txt.insertPlainText(str(s))
            txt.moveCursor(QTextCursor.End)

        setup_logging(_write)

        self.setGeometry(300, 300, 800, 600)
        self.setWindowTitle('Antix Print Server')

    def setupTrayIcon(self):
        _icon = QIcon(os.path.join('web', 'static', 'img', 'Logo.144x144.png'))
        self.trayIcon = QSystemTrayIcon(_icon, self)
        menu = QMenu(self)
        menu.addAction("Show", self.show)
        menu.addAction("Hide", self.hide)
        menu.addAction("Exit", self.reallyClose)
        self.trayIcon.setContextMenu(menu)
        self.trayIcon.show()
        self.trayIcon.showMessage("Antix Printer Server", "Is running")

    def closeEvent(self, evnt):
        if self.kill:
            self.trayIcon.hide()
            try:
                cherrypy_server.stop_server()
            except Exception as e:
                logging.getLogger(__name__).warn("Problem stopping server! {}".format(e))
            qApp.exit(0)
        else:
            evnt.ignore()
            self.hide()
Esempio n. 53
0
class PymodoroGUI(QWidget):
    """
        GUI for Pymodoro
    """
    def __init__(self):
        """
            Initializer for the Pomodoro GUI class
        """
        super(PymodoroGUI, self).__init__()

        self.res_dir = os.path.join("../ext/")
        self.green_tomato_icon = os.path.join(self.res_dir, "greentomato.png")
        self.red_tomato_icon = os.path.join(self.res_dir, "redtomato.png")
        self.tray = QSystemTrayIcon(QIcon(self.green_tomato_icon))
        self.pom = Pomodoro()
        self.pom.ringer.connect(self.signal)
        self.init_ui()

    def signal(self, pomodori):
        """
            Callback given to the Pomodoro class.
            Called when a pomodoro is up
        """
        if pomodori % 4 == 0 and pomodori != 0:
            self.tray.showMessage("4 Pomodori has passed!",
                                   "Take a long break: 15-30min",
                                   QSystemTrayIcon.Information)
        else:
            self.tray.showMessage("Pomodoro's up!",
                                   "Take a short break: 3-5min",
                                   QSystemTrayIcon.Information)
        self.tray.setIcon(QIcon(self.green_tomato_icon))

    def init_tray(self):
        """
            Initializes the systray menu
        """
        traymenu = QMenu("Menu")
        self.tray.setContextMenu(traymenu)
        self.tray.show()
        self.tray.activated.connect(self.tray_click)
        self.tray.setToolTip("Pomodori: "+str(self.pom.pomodori))

        set_timer_tray = QLineEdit()
        set_timer_tray.setPlaceholderText("Set timer")
        set_timer_tray.textChanged.connect(lambda:
                                           self.update_timer_text(set_timer_tray.text()))
        traywidget = QWidgetAction(set_timer_tray)
        traywidget.setDefaultWidget(set_timer_tray)
        traymenu.addAction(traywidget)

        start_timer_action = QAction("&Start Timer", self)
        start_timer_action.triggered.connect(self.start_timer_click)
        traymenu.addAction(start_timer_action)

        exit_action = QAction("&Exit", self)
        exit_action.triggered.connect(QCoreApplication.instance().quit)
        traymenu.addAction(exit_action)

    def tray_click(self, activation):
        """
            Method called when clicking the tray icon
        """
        if activation == QSystemTrayIcon.Trigger:
            if self.isVisible():
                self.hide()
            else:
                self.show()
        elif activation == QSystemTrayIcon.Context:
            self._tray.show()

    def close_event(self, event):
        self._tray.showMessage("Running in system tray",
                                """The program will keep running in the system tray.\n
                                To terminate the program choose exit from the context menu""",
                                QSystemTrayIcon.Information)
        self.hide()
        event.ignore()

    def wheel_event(self, event):
        if event.delta() > 0:
            timervalue = int(self.settimertext.text())
            timervalue = timervalue + 1
            self.settimertext.setText(str(timervalue))
        else:
            timervalue = int(self.settimertext.text())
            timervalue = timervalue - 1
            self.settimertext.setText(str(timervalue))

    def init_ui(self):
        """
            Initializes the GUI
        """
        self.init_tray()
        resolution = QApplication.desktop().availableGeometry()
        width = 150
        height = 100

        # place exactly in center of screen
        self.setGeometry((resolution.width() / 2) - (width / 2),
                         (resolution.height() / 2) - (height / 2),
                         width, height)
        self.setWindowTitle("Pomodoro")
        self.setWindowIcon(QIcon(os.path.join(self.res_dir, "redtomato.png")))

        grid = QGridLayout()
        grid.setSpacing(5)
        self.settimertext = QLineEdit()
        grid.addWidget(self.settimertext, 1, 0)

        self.errortext = QLabel()
        grid.addWidget(self.errortext, 2, 0)
        self.errortext.hide()

        self.settimertext.setText(str(25))
        self.settimertext.textChanged.connect(lambda:
                                              self.update_timer_text(
                                                 self.settimertext.text()))

        self.start_timerbutton = QPushButton("start timer")
        grid.addWidget(self.start_timerbutton, 3, 0)
        self.start_timerbutton.clicked.connect(self.start_timer_click)

        self.setLayout(grid)
        self.show()

    def start_timer_click(self):
        """
            Method run when starting the pomodoro timer
        """
        self.pom.start_timer()
        self.tray.setIcon(QIcon(self.red_tomato_icon))
        self.hide()

    def update_timer_text(self, number):
        """
            Method run when setting the number of minutes in the timer
        """
        try:
            self.pom.set_timer_minutes(int(number))
            self.errortext.hide()
        except ValueError:
            self.errortext.setText("Please input a number")
            self.errortext.show()
Esempio n. 54
0
class Magneto(MagnetoCore):

    """
    Magneto Updates Notification Applet class.
    """

    def __init__(self):
        self._app = QApplication([sys.argv[0]])

        from dbus.mainloop.pyqt5 import DBusQtMainLoop
        super(Magneto, self).__init__(main_loop_class = DBusQtMainLoop)

        self._window = QSystemTrayIcon(self._app)
        icon_name = self.icons.get("okay")
        self._window.setIcon(QIcon.fromTheme(icon_name))
        self._window.activated.connect(self._applet_activated)

        self._menu = QMenu(_("Magneto Entropy Updates Applet"))
        self._window.setContextMenu(self._menu)

        self._menu_items = {}
        for item in self._menu_item_list:
            if item is None:
                self._menu.addSeparator()
                continue

            myid, _unused, mytxt, myslot_func = item
            name = self.get_menu_image(myid)
            action_icon = QIcon.fromTheme(name)

            w = QAction(action_icon, mytxt, self._window,
                        triggered=myslot_func)
            self._menu_items[myid] = w
            self._menu.addAction(w)

        self._menu.hide()

    def _first_check(self):
        def _do_check():
            self.send_check_updates_signal(startup_check = True)
            return False

        if self._dbus_service_available:
            const_debug_write("_first_check", "spawning check.")
            QTimer.singleShot(10000, _do_check)

    def startup(self):
        self._dbus_service_available = self.setup_dbus()
        if config.settings["APPLET_ENABLED"] and \
            self._dbus_service_available:
            self.enable_applet(do_check = False)
            const_debug_write("startup", "applet enabled, dbus service available.")
        else:
            const_debug_write("startup", "applet disabled.")
            self.disable_applet()
        if not self._dbus_service_available:
            const_debug_write("startup", "dbus service not available.")
            QTimer.singleShot(30000, self.show_service_not_available)
        else:
            const_debug_write("startup", "spawning first check.")
            self._first_check()

        # Notice Window instance
        self._notice_window = AppletNoticeWindow(self)

        self._window.show()

        # Enter main loop
        self._app.exec_()

    def close_service(self):
        super(Magneto, self).close_service()
        self._app.quit()

    def change_icon(self, icon_name):
        name = self.icons.get(icon_name)
        self._window.setIcon(QIcon.fromTheme(name))

    def disable_applet(self, *args):
        super(Magneto, self).disable_applet()
        self._menu_items["disable_applet"].setEnabled(False)
        self._menu_items["enable_applet"].setEnabled(True)

    def enable_applet(self, w = None, do_check = True):
        done = super(Magneto, self).enable_applet(do_check = do_check)
        if done:
            self._menu_items["disable_applet"].setEnabled(True)
            self._menu_items["enable_applet"].setEnabled(False)

    def show_alert(self, title, text, urgency = None, force = False,
                   buttons = None):

        # NOTE: there is no support for buttons via QSystemTrayIcon.

        if ((title, text) == self.last_alert) and not force:
            return

        def _action_activate_cb(action_num):
            if not buttons:
                return

            try:
                action_info = buttons[action_num - 1]
            except IndexError:
                return

            _action_id, _button_name, button_callback = action_info
            button_callback()

        def do_show():
            if not self._window.supportsMessages():
                const_debug_write("show_alert", "messages not supported.")
                return

            icon_id = QSystemTrayIcon.Information
            if urgency == "critical":
                icon_id = QSystemTrayIcon.Critical

            self._window.showMessage(title, text, icon_id)
            self.last_alert = (title, text)

        QTimer.singleShot(0, do_show)

    def update_tooltip(self, tip):
        def do_update():
            self._window.setToolTip(tip)
        QTimer.singleShot(0, do_update)

    def applet_context_menu(self):
        """No action for now."""

    def _applet_activated(self, reason):
        const_debug_write("applet_activated", "Applet activated: %s" % reason)
        if reason == QSystemTrayIcon.DoubleClick:
            const_debug_write("applet_activated", "Double click event.")
            self.applet_doubleclick()

    def hide_notice_window(self):
        self.notice_window_shown = False
        self._notice_window.hide()

    def show_notice_window(self):

        if self.notice_window_shown:
            const_debug_write("show_notice_window", "Notice window already shown.")
            return

        if not self.package_updates:
            const_debug_write("show_notice_window", "No computed updates.")
            return

        entropy_ver = None
        packages = []
        for atom in self.package_updates:

            key = entropy.dep.dep_getkey(atom)
            avail_rev = entropy.dep.dep_get_entropy_revision(atom)
            avail_tag = entropy.dep.dep_gettag(atom)
            my_pkg = entropy.dep.remove_entropy_revision(atom)
            my_pkg = entropy.dep.remove_tag(my_pkg)
            pkgcat, pkgname, pkgver, pkgrev = entropy.dep.catpkgsplit(my_pkg)
            ver = pkgver
            if pkgrev != "r0":
                ver += "-%s" % (pkgrev,)
            if avail_tag:
                ver += "#%s" % (avail_tag,)
            if avail_rev:
                ver += "~%s" % (avail_tag,)

            if key == "sys-apps/entropy":
                entropy_ver = ver

            packages.append("%s (%s)" % (key, ver,))

        critical_msg = ""
        if entropy_ver is not None:
            critical_msg = "%s <b>sys-apps/entropy</b> %s, %s <b>%s</b>. %s." % (
                _("Your system currently has an outdated version of"),
                _("installed"),
                _("the latest available version is"),
                entropy_ver,
                _("It is recommended that you upgrade to "
                  "the latest before updating any other packages")
            )

        self._notice_window.populate(packages, critical_msg)

        self._notice_window.show()
        self.notice_window_shown = True
Esempio n. 55
0
class Window(QDialog):
    def __init__(self, gui_connection):
        super(Window, self).__init__()
        self.gui_connection = gui_connection
        self.gui_connection.changeState.connect(self.changeState)
        self.gui_connection.whatTime.connect(self.setTime)

        #init settings dialog
        self.settings_dialog = settings.SettingsDialog()

        self.createActions()
        self.createTrayIcon()
        self.setTrayIcon('work-full')
        self.trayIcon.show()
        self.setWindowTitle("KoffeeBreak")

    def createActions(self):
        self.openAction = QAction(QIcon().fromTheme('document-open'),
                                  "Open", self,
                                  triggered=self.showNormal)
        self.takeBreakAction = QAction(QIcon().fromTheme("koffeebreak-break-full"),
                                  "Take a break", self,
                                  triggered=self.start_break)
        self.pauseAction = QAction(QIcon().fromTheme('media-playback-pause'),
                                  "Pause program",self,
                                  triggered=self.pauseProgram)
        self.settingsAction = QAction(QIcon().fromTheme('configure'),
                                  "Settings", self,
                                  triggered=self.settings_dialog.show)
        self.quitAction = QAction(QIcon().fromTheme('application-exit'),
                                  "Quit", self, triggered=self.close_app)

    def createTrayIcon(self):
        self.trayIconMenu = QMenu(self)
        self.trayIconMenu.addAction(self.openAction)
        self.trayIconMenu.addAction(self.settingsAction)
        self.trayIconMenu.addSeparator()
        self.trayIconMenu.addAction(self.takeBreakAction)
        self.trayIconMenu.addAction(self.pauseAction)
        self.trayIconMenu.addSeparator()
        self.trayIconMenu.addAction(self.quitAction)

        self.trayIcon = QSystemTrayIcon(self)
        self.trayIcon.setContextMenu(self.trayIconMenu)

    def setTrayIcon(self, iconName):
        icon = QIcon().fromTheme('koffeebreak-' + iconName)
        self.trayIcon.setIcon(icon)

    def start_break(self):
        self.break_screen = break_screen.BreakWindow(self.gui_connection)

    def changeState(self, state):
        self.setTrayIcon(state)
        if state == "break-1-4":
            pass
            #self.gui_connection.whatTime.emit()
            #self.trayIcon.showMessage("Break-1-4", str(self.time))
        elif state == "break-2-4":
            pass
        elif state == "break-3-4":
            pass
        elif state == "break-full":
            if (not self.break_screen.isVisible()):
                self.start_break()
        elif state == "work-1-8":
            pass
        elif state == "work-2-8":
            pass
        elif state == "work-3-8":
            pass
        elif state == "work-4-8":
            pass
        elif state == "work-5-8":
            pass
        elif state == "work-6-8":
            pass
        elif state == "work-7-8":
            pass
        elif state == "work-full":
            if (self.break_screen.isVisible()):
                self.break_screen.close()

    def setTime(self, time):
        self.time = time

    def pauseProgram(self):
        self.gui_connection.pauseTimer.emit()

    def close_app(self):
        self.gui_connection.closeApp.emit()
Esempio n. 56
0
class Window(QDialog):
    def __init__(self):
        super(Window, self).__init__()

        # UI
        self.createActions()
        self.setTitle = programTitle
        self.createTrayIcon()
        # Draw system tray icon
        pixmap = QtGui.QPixmap(QtGui.QPixmap(":icons/mailbox_empty.png"))
        painter = QtGui.QPainter(pixmap)
        painter.setPen(QtGui.QColor(255, 0, 0))
        painter.setFont(QtGui.QFont("Arial", QtGui.QFont.Bold))
        painter.drawText(QtCore.QRectF(pixmap.rect()), QtCore.Qt.AlignCenter, "0")
        painter.end()
        self.trayIcon.setIcon(QtGui.QIcon(pixmap))
        # End drawing system tray icon

        self.trayIcon.setToolTip("You have no unread letters")
        self.trayIcon.show()

        # setup settings
        self.ui = Ui_Settings()
        self.ui.setupUi(self)
        self.setWindowIcon(QIcon(os.path.dirname(os.path.realpath(__file__)) + "/icons/mailbox_empty.png"))
        self.SettingsRestore()

        self.ui.buttonBox.button(QtWidgets.QDialogButtonBox.Ok).clicked.connect(self.btnOK_clicked)
        self.ui.buttonBox.button(QtWidgets.QDialogButtonBox.Cancel).clicked.connect(self.btnCancel_clicked)
        self.ui.btnTestConnection.clicked.connect(self.btnTestConnection_clicked)
        self.ui.comboAccounts.currentTextChanged.connect(self.comboAccounts_changed)
        self.ui.btnAddAccount.clicked.connect(self.btnAddAccount_clicked)
        self.ui.btnRenameAccount.clicked.connect(self.btnRenameAccount_clicked)
        self.ui.btnSaveAccount.clicked.connect(self.btnSaveAccount_clicked)
        self.ui.btnRemoveAccount.clicked.connect(self.btnRemoveAccount_clicked)

        # Main timer
        self.timer = QTimer(self)
        self.timer.timeout.connect(mail_check)

        self.lastCheckCount = (
            0
        )  # variable for prevent annoying popup notification when mail count didn't change since last check

        # Menu actions

    def createActions(self):
        self.detailsShow = QAction(QIcon(":icons/details.png"), "&Details", self, triggered=self.detailsShow)
        self.aboutShow = QAction(QIcon(":icons/mailbox_empty.png"), "&About", self, triggered=self.aboutShow)
        self.checkNow = QAction(QIcon(":icons/check_now.png"), "&Check now", self, triggered=mail_check)
        self.restoreAction = QAction(QIcon(":icons/settings.png"), "&Settings", self, triggered=self.showNormal)
        self.quitAction = QAction(QIcon(":icons/menu_quit.png"), "&Quit", self, triggered=QApplication.instance().quit)

        # UI functions

    def createTrayIcon(self):
        self.trayIconMenu = QMenu(self)
        self.trayIconMenu.addAction(self.aboutShow)
        self.trayIconMenu.addAction(self.detailsShow)
        self.trayIconMenu.addAction(self.checkNow)
        self.trayIconMenu.addAction(self.restoreAction)
        self.trayIconMenu.addAction(self.quitAction)
        self.trayIcon = QSystemTrayIcon(self)
        self.trayIcon.setContextMenu(self.trayIconMenu)
        self.trayIcon.activated.connect(self.trayIconActivated)

    def SettingsRestore(self):
        if GlobalSettingsExist() and AccountExist():
            groups = settings.childGroups()
            for i in range(len(groups)):
                self.ui.comboAccounts.addItem(groups[i])
                self.ui.comboAccounts.setCurrentText(groups[i])
                settings.beginGroup(groups[i])
                self.ui.txtboxMailServer.setText(settings.value("MailServer"))
                self.ui.txtboxPort.setText(settings.value("Port"))
                self.ui.txtboxLogin.setText(settings.value("Login"))
                self.ui.txtboxPassword.setText(settings.value("Password"))
                self.ui.boolifSSL.setChecked(bool(settings.value("SSL")))
                settings.endGroup()
            if self.ui.comboAccounts.count() == 0:
                self.ui.comboAccounts.addItem("Default")
                self.ui.comboAccounts.setCurrentText("Default")
            self.ui.checkFreq.setValue(int(settings.value("CheckInterval")))
            self.ui.boolifNotify.setChecked(bool(settings.value("Notify")))

    def SettingsSave(self, account):
        settings.setValue("CheckInterval", self.ui.checkFreq.value())
        settings.setValue("Notify", self.ui.boolifNotify.isChecked())
        settings.beginGroup(account)
        settings.setValue("MailServer", self.ui.txtboxMailServer.text())
        settings.setValue("Port", self.ui.txtboxPort.text())
        settings.setValue("Login", self.ui.txtboxLogin.text())
        settings.setValue("Password", self.ui.txtboxPassword.text())
        settings.setValue("SSL", self.ui.boolifSSL.isChecked())
        settings.endGroup()

    def SettingsRemove(self, group):
        settings.beginGroup(group)
        settings.remove("")
        settings.endGroup()

    def btnOK_clicked(self):
        self.SettingsSave(self.ui.comboAccounts.currentText())

        if (
            settings.value("MailServer") == ""
            or settings.value("Port") == ""
            or settings.value("Login") == ""
            or settings.value("Password") == ""
        ):
            QMessageBox.critical(self, "Warning", "You should fill all fields in IMAP settings!")
            self.show()
        mail_check()
        self.ui.lblTestOutput.setText("")
        self.stop()
        self.start()

    def btnCancel_clicked(self):
        self.SettingsRestore()
        self.ui.lblTestOutput.setText("")

    def btnTestConnection_clicked(self):
        try:
            if self.ui.boolifSSL.isChecked:
                self.imap = imaplib.IMAP4_SSL(self.ui.txtboxMailServer.text(), self.ui.txtboxPort.text())
            else:
                self.imap = imaplib.IMAP4(self.ui.txtboxMailServer.text(), self.ui.txtboxPort.text())
            self.imap.login(self.ui.txtboxLogin.text(), self.ui.txtboxPassword.text())
            output = "Connection was established successfully"
        except:
            output = "Unable to establish connection to mailbox"
        finally:
            self.ui.lblTestOutput.setText(output)

    def btnAddAccount_clicked(self):
        GroupName = QInputDialog.getText(self, "Enter account name", "Enter account name", QLineEdit.Normal, "")
        if GroupName[0]:
            self.ui.comboAccounts.addItem(GroupName[0])
            self.ui.comboAccounts.setCurrentText(GroupName[0])

    def btnRenameAccount_clicked(self):
        Index = self.ui.comboAccounts.currentIndex()
        OldGroupName = self.ui.comboAccounts.currentText()
        GroupName = QInputDialog.getText(
            self, "Enter account name", "Enter account name", QLineEdit.Normal, self.ui.comboAccounts.currentText()
        )
        if GroupName[0]:
            self.SettingsSave(GroupName[0])
            self.ui.comboAccounts.setItemText(Index, GroupName[0])
            self.ui.comboAccounts.setCurrentText(GroupName[0])
            self.SettingsRemove(OldGroupName)

    def btnSaveAccount_clicked(self):
        self.SettingsSave(self.ui.comboAccounts.currentText())
        self.ui.lblTestOutput.setText("Account saved")

    def btnRemoveAccount_clicked(self):
        reply = QMessageBox.warning(
            self, "Warning!", "Delete this account permanently?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No
        )
        if reply == QMessageBox.Yes:
            Index = self.ui.comboAccounts.currentIndex()
            GroupName = self.ui.comboAccounts.currentText()
            self.ui.comboAccounts.removeItem(Index)
            self.SettingsRemove(GroupName)

    def comboAccounts_changed(self):
        self.ui.lblTestOutput.setText("")
        settings.beginGroup(self.ui.comboAccounts.currentText())
        self.ui.txtboxMailServer.setText(settings.value("MailServer"))
        self.ui.txtboxPort.setText(settings.value("Port"))
        self.ui.txtboxLogin.setText(settings.value("Login"))
        self.ui.txtboxPassword.setText(settings.value("Password"))
        self.ui.boolifSSL.setChecked(bool(settings.value("SSL")))
        settings.endGroup()

    def aboutShow(self):
        if about.isMinimized:
            about.hide()
        about.show()
        about.activateWindow()

    def detailsShow(self):
        details.show()
        details.activateWindow()

    def trayIconActivated(self, reason):
        if reason in (QSystemTrayIcon.Trigger, QSystemTrayIcon.DoubleClick):
            details.show()
            details.activateWindow()

    def start(self):
        if GlobalSettingsExist() and AccountExist():
            CheckInterval = 1000 * 60 * int(settings.value("CheckInterval"))
        else:
            CheckInterval = 1000 * 60 * 5
        self.timer.setInterval(CheckInterval)
        self.timer.start()

    def stop(self):
        self.timer.stop()
Esempio n. 57
0
	def initUI(self):
		# 获取电脑屏幕宽高 让主界面初始化后处于屏幕中间
		wh = QApplication.desktop().screenGeometry()
		self.screen_w , self.screen_h = wh.width() ,wh.height()
		self.setGeometry(int((self.screen_w-300)/2),int((self.screen_h-600)/2),300,600)
		# self.setWindowOpacity(0.97); 

		#当前播放歌曲的封面 
		songer_img = DragLabel(self)
		# songer_img.setwinflag.connect(self.setwinflag)
		songer_img.setParent(self)
		songer_img.resize(300,200)

		self.picture = QLabel(songer_img)
		self.picture.resize(300,200)
		self.picture.setStyleSheet("QLabel{ border-image:url("+conf['pifu']+")}")

		# syl = QLabel(songer_img)
		# syl.setGeometry(15,5,34,15)
		# syl.setStyleSheet("QLabel{ border-image:url(image/newimg/logo.png);}")

		# ================================
		songinfo = QLabel(songer_img)
		songinfo.setGeometry(0,30,300,80)
		songinfo.setStyleSheet("QLabel{ background:transparent;}")

		songpic = QLabel(songinfo)
		songpic.setGeometry(10,0,80,80)
		songpic.setStyleSheet("QLabel{ border-image:url(image/newimg/user.jpg);border-radius:2px;}")

		self.songname = QLabel("老鼠爱大米 - 香香",songinfo)
		self.songname.setGeometry(105,0,210,25)
		self.songname.setStyleSheet("QLabel{ color:#EEE;font-size:15px;}")
		uploaduser = QLabel("By 张三的歌",songinfo)
		uploaduser.move(105,25)
		# uploaduser.setCursor(QCursor(Qt.PointingHandCursor))
		uploaduser.setStyleSheet("QLabel{ color:yellow;font-size:15px;} QLabel:hover{color:red}")

		fenshu = QLabel("评分 - 7.6",songinfo)
		fenshu.setGeometry(105,50,210,25)
		# self.picture.setGraphicsEffect(QGraphicsBlurEffect())
		fenshu.setStyleSheet("QLabel{ color:#EEE;font-size:15px;}")


		songtool = QLabel(songer_img)
		songtool.setGeometry(0,110,300,35)
		songtool.setStyleSheet("QLabel{ background:transparent;}")

		# 喜欢歌曲
		lovesong = QLabel(songtool)
		lovesong.setGeometry(20,10,25,25)
		lovesong.setStyleSheet("QLabel{ border-image:url(image/newimg/kg_ic_player_liked.png);}")
		# 评论
		pinglun = QLabel(songtool)
		pinglun.setGeometry(50,5,33,33)
		pinglun.setStyleSheet("QLabel{ border-image:url(image/newimg/pinglun.png);}")
		# 歌曲更多信息
		songmore = QLabel("查看这首歌的更多资料",songtool)
		songmore.move(100,10)
		# songmore.setCursor(QCursor(Qt.PointingHandCursor))
		songmore.setStyleSheet("QLabel{ color:#BBB} QLabel:hover{color:pink}")


		# ======================================

		# 顶部工具栏
		# 隐藏
		btn = QPushButton("",self)
		btn.setGeometry(270,0,15,32)
		# btn.setCursor(QCursor(Qt.PointingHandCursor))
		btn.setStyleSheet("QPushButton{ border:none;color:white;background:transparent;border-image:url(image/newimg/mini.png) } QPushButton:hover{ border-image:url(image/newimg/mini_2.png) } ")
		btn.clicked.connect(self.close)

		# 换皮肤
		btn = QPushButton("",self)
		btn.setGeometry(230,10,20,20)
		# btn.setCursor(QCursor(Qt.PointingHandCursor))
		btn.setStyleSheet("QPushButton{ border:none;color:white;background:transparent;border-image:url(image/newimg/fx_slide_menu_change_bg_2.png) } QPushButton:hover{ border-image:url(image/newimg/fx_slide_menu_change_bg.png) } ")
		btn.clicked.connect(self.huanfu)
		# 设置封面
		# btn = QPushButton("",self)
		# btn.setGeometry(230,-10,41,48)
		# btn.setCursor(QCursor(Qt.PointingHandCursor))
		# btn.setStyleSheet("QPushButton{ border:none;color:white;background:transparent;border-image:url(image/newimg/fengmian.png) } ")
		# btn.clicked.connect(self.setHeaderImg)
		# 开启/关闭歌词
		# btn = QPushButton("",self)
		# btn.setGeometry(200,0,30,30)
		# btn.setCursor(QCursor(Qt.PointingHandCursor))
		# btn.setStyleSheet("QPushButton{ border:none;color:white;background:transparent;border-image:url(image/newimg/geci.png) } ")
		# btn.clicked.connect(self.lrc)
		# 播放组件  ( 播放  前进 后退 播放时间 进度条 歌曲名 音量 )
		# 播放/暂停
		self.playBtn = QPushButton("",songer_img)
		self.playBtn.setGeometry(130,155,32,25)
		self.playBtn.setStyleSheet("QPushButton{ border-image:url(image/newimg/statusbar_btn_play.png);border:none } QPushButton:hover{ border-image:url(image/newimg/statusbar_btn_play_2.png)} ")
		# 下一首
		self.nextBtn = QPushButton("",songer_img)
		self.nextBtn.setGeometry(186,159,20,20)
		self.nextBtn.setStyleSheet("QPushButton{ border-image:url(image/newimg/statusbar_btn_next.png);border:none } QPushButton:hover{ border-image:url(image/newimg/statusbar_btn_next_2.png)}")
		# 音量调节
		self.songvolume = QPushButton("",songer_img)
		self.songvolume.setGeometry(236,159,20,20)
		self.songvolume.setStyleSheet("QPushButton{ border-image:url(image/newimg/ic_player_menu_volume.png);border:none } QPushButton:hover{ border-image:url(image/newimg/ic_player_menu_volume_2.png)}")
		self.songvolume.clicked.connect(self.setvolume)
		# 音量
		self.volslider = QSlider(Qt.Horizontal,self)
		self.volslider.setCursor(QCursor(Qt.UpArrowCursor))
		self.volslider.setGeometry(250,165,45,6)
		self.volslider.setValue(70)
		self.volslider.setRange(0,100)
		self.volslider.setStyleSheet(qss_vol)
		self.volslider.setVisible(False)

		# 上一首
		self.prevBtn = QPushButton("",songer_img)
		self.prevBtn.setGeometry(85,159,20,20)
		self.prevBtn.setStyleSheet("QPushButton{ border-image:url(image/newimg/statusbar_btn_prev.png);border:none } QPushButton:hover{ border-image:url(image/newimg/statusbar_btn_prev_2.png)}")
		# 播放模式
		self.playmodel = QPushButton("",songer_img)
		self.playmodel.setGeometry(35,156,25,25)
		self.playmodel.setStyleSheet("QPushButton{ border-image:url(image/newimg/allmodel.png);border:none } QPushButton:hover{ border-image:url(image/newimg/allmodel_2.png)}")
		self.playmodel.clicked.connect(self.moshi)

		# 当前播放时间
		self.songTime = QLabel("",self)
		self.songTime.setGeometry(240,180,80,20)
		self.songTime.setStyleSheet("QLabel{ color:#AAA;font-size:12px;}")
		self.songTime.setAlignment(Qt.AlignHCenter)
		
		# 当前歌曲名   
		self.currentMusicName = QLabel("",songer_img)
		self.currentMusicName.setGeometry(0,180,200,20)
		self.currentMusicName.setStyleSheet("QLabel{ color:white ;font-weight:100;font-size:12px;margin-left:5px;}")
		# 歌曲进度条
		self.processSlider = QSlider(Qt.Horizontal,self)
		self.processSlider.setGeometry(0,193,300,7)
		# self.processSlider.setRange(1,100)
		self.processSlider.setValue(0)
		self.processSlider.setStyleSheet(qss_process_slider)
		
		self.processSlider.setCursor(QCursor(Qt.UpArrowCursor))

		# 歌曲列表 ---------------------------
		listWgt = QWidget(self)
		listWgt.setGeometry(0, 200, 300,380)
		listWgt.setStyleSheet(qss_scrollbar)

		#列表
		self.songList = QListWidget(listWgt)
		self.songList.setGeometry(5,0,235,380)   
		self.songList.setStyleSheet(qss_songlist)	
		# 列表添加右键菜单
		# self.songList.setContextMenuPolicy(Qt.CustomContextMenu)
		# self.songList.customContextMenuRequested.connect(self.rightMenuShow)

		#歌曲列表右边的功能列表
		funcList = QListWidget(listWgt)
		funcList.setGeometry(240,0,55,380)   
		funcList.setStyleSheet(qss_menu)
		btn = QPushButton("",funcList)
		btn.clicked.connect(self.newwindow)
		btn.setGeometry(15,10,30,30)
		btn.setStyleSheet("QPushButton{ border-image:url(image/home.png)} \
			QPushButton:hover{ border-image:url(image/homehover.png) }")
		# btn.setCursor(QCursor(Qt.PointingHandCursor))
		btn = QPushButton("",funcList)
		btn.setGeometry(15,60,30,30)
		btn.setStyleSheet("QPushButton{ border-image:url(image/tuijian.png) } \
			QPushButton:hover{ border-image:url(image/tuijianhover.png) }")
		# btn.setCursor(QCursor(Qt.PointingHandCursor))
		btn = QPushButton("",funcList)
		btn.setGeometry(15,100,30,30)
		btn.setStyleSheet("QPushButton{ border-image:url(image/shoucang.png) }\QPushButton:hover{ border-image:url(image/shoucanghover.png) }")
		# btn.setCursor(QCursor(Qt.PointingHandCursor))

		btn = QPushButton("",funcList)
		btn.setGeometry(15,140,30,30)
		btn.setStyleSheet("QPushButton{ border-image:url(image/rizhi.png) }\
			QPushButton:hover{ border-image:url(image/rizhihover.png) }")
		# btn.setCursor(QCursor(Qt.PointingHandCursor))

		btn = QPushButton("",funcList)
		btn.setGeometry(17,180,30,30)
		btn.setStyleSheet("QPushButton{ border-image:url(image/mv.png) }\
			QPushButton:hover{ border-image:url(image/mvhover.png) }")
		# btn.setCursor(QCursor(Qt.PointingHandCursor))

		setbtn = QPushButton("",funcList)
		setbtn.setGeometry(15,225,33,33)
		setbtn.setStyleSheet("QPushButton{ border-image:url(image/settinghover.png) }\
			QPushButton:hover{ border-image:url(image/setting.png) }")
		setbtn.clicked.connect(self.openseting)

		#底部状态栏
		wg = QWidget(self)
		wg.setGeometry(0, 580, 300,20)
		wg.setStyleSheet("QWidget{ background:#2D2D2D; } ")
		# ql = QLabel(" <a style='color:#444;text-decoration:none;font-size:12px;'  href ='https://github.com/codeAB/music-player' >S Y L </a>",wg)
		# ql.resize(300,20)
		# ql.setAlignment(Qt.AlignRight)
		# ql.linkActivated.connect(self.openurl)

		#设置托盘图标
		tray = QSystemTrayIcon(self)
		tray.setIcon(QIcon('image/tray.png'))
		self.trayIconMenu = QMenu(self)
		self.trayIconMenu.setStyleSheet(qss_tray)
		showAction = QAction(QIcon('image/tray.png'),u"显示主面板", self,triggered=self.show)
		self.trayIconMenu.addAction(showAction)
		# self.trayIconMenu.addAction(preAction)
		# self.trayIconMenu.addAction(pauseAction)
		# self.trayIconMenu.addAction(nextAction)
		# self.trayIconMenu.addAction(quitAction)
		tray.setContextMenu(self.trayIconMenu)
		tray.show()
		tray.activated.connect(self.dbclick_tray)
class MainWindow(QMainWindow):

    """Voice Changer main window."""

    def __init__(self, parent=None):
        super(MainWindow, self).__init__()
        self.statusBar().showMessage("Move Dial to Deform Microphone Voice !.")
        self.setWindowTitle(__doc__)
        self.setMinimumSize(240, 240)
        self.setMaximumSize(480, 480)
        self.resize(self.minimumSize())
        self.setWindowIcon(QIcon.fromTheme("audio-input-microphone"))
        self.tray = QSystemTrayIcon(self)
        self.center()
        QShortcut("Ctrl+q", self, activated=lambda: self.close())
        self.menuBar().addMenu("&File").addAction("Quit", lambda: exit())
        self.menuBar().addMenu("Sound").addAction(
            "STOP !", lambda: call('killall rec', shell=True))
        windowMenu = self.menuBar().addMenu("&Window")
        windowMenu.addAction("Hide", lambda: self.hide())
        windowMenu.addAction("Minimize", lambda: self.showMinimized())
        windowMenu.addAction("Maximize", lambda: self.showMaximized())
        windowMenu.addAction("Restore", lambda: self.showNormal())
        windowMenu.addAction("FullScreen", lambda: self.showFullScreen())
        windowMenu.addAction("Center", lambda: self.center())
        windowMenu.addAction("Top-Left", lambda: self.move(0, 0))
        windowMenu.addAction("To Mouse", lambda: self.move_to_mouse_position())
        # widgets
        group0 = QGroupBox("Voice Deformation")
        self.setCentralWidget(group0)
        self.process = QProcess(self)
        self.process.error.connect(
            lambda: self.statusBar().showMessage("Info: Process Killed", 5000))
        self.control = QDial()
        self.control.setRange(-10, 20)
        self.control.setSingleStep(5)
        self.control.setValue(0)
        self.control.setCursor(QCursor(Qt.OpenHandCursor))
        self.control.sliderPressed.connect(
            lambda: self.control.setCursor(QCursor(Qt.ClosedHandCursor)))
        self.control.sliderReleased.connect(
            lambda: self.control.setCursor(QCursor(Qt.OpenHandCursor)))
        self.control.valueChanged.connect(
            lambda: self.control.setToolTip(f"<b>{self.control.value()}"))
        self.control.valueChanged.connect(
            lambda: self.statusBar().showMessage(
                f"Voice deformation: {self.control.value()}", 5000))
        self.control.valueChanged.connect(self.run)
        self.control.valueChanged.connect(lambda: self.process.kill())
        # Graphic effect
        self.glow = QGraphicsDropShadowEffect(self)
        self.glow.setOffset(0)
        self.glow.setBlurRadius(99)
        self.glow.setColor(QColor(99, 255, 255))
        self.control.setGraphicsEffect(self.glow)
        self.glow.setEnabled(False)
        # Timer to start
        self.slider_timer = QTimer(self)
        self.slider_timer.setSingleShot(True)
        self.slider_timer.timeout.connect(self.on_slider_timer_timeout)
        # an icon and set focus
        QLabel(self.control).setPixmap(
            QIcon.fromTheme("audio-input-microphone").pixmap(32))
        self.control.setFocus()
        QVBoxLayout(group0).addWidget(self.control)
        self.menu = QMenu(__doc__)
        self.menu.addAction(__doc__).setDisabled(True)
        self.menu.setIcon(self.windowIcon())
        self.menu.addSeparator()
        self.menu.addAction(
            "Show / Hide",
            lambda: self.hide() if self.isVisible() else self.showNormal())
        self.menu.addAction("STOP !", lambda: call('killall rec', shell=True))
        self.menu.addSeparator()
        self.menu.addAction("Quit", lambda: exit())
        self.tray.setContextMenu(self.menu)
        self.make_trayicon()

    def run(self):
        """Run/Stop the QTimer."""
        if self.slider_timer.isActive():
            self.slider_timer.stop()
        self.glow.setEnabled(True)
        call('killall rec ; killall play', shell=True)
        self.slider_timer.start(3000)

    def on_slider_timer_timeout(self):
        """Run subprocess to deform voice."""
        self.glow.setEnabled(False)
        value = int(self.control.value()) * 100
        command = f'play -q -V0 "|rec -q -V0 -n -d -R riaa bend pitch {value} "'
        print(f"Voice Deformation Value: {value}")
        print(f"Voice Deformation Command: {command}")
        self.process.start(command)
        if self.isVisible():
            self.statusBar().showMessage("Minimizing to System TrayIcon", 3000)
            print("Minimizing Main Window to System TrayIcon now...")
            sleep(3)
            self.hide()

    def center(self):
        """Center Window on the Current Screen,with Multi-Monitor support."""
        window_geometry = self.frameGeometry()
        mousepointer_position = QApplication.desktop().cursor().pos()
        screen = QApplication.desktop().screenNumber(mousepointer_position)
        centerPoint = QApplication.desktop().screenGeometry(screen).center()
        window_geometry.moveCenter(centerPoint)
        self.move(window_geometry.topLeft())

    def move_to_mouse_position(self):
        """Center the Window on the Current Mouse position."""
        window_geometry = self.frameGeometry()
        window_geometry.moveCenter(QApplication.desktop().cursor().pos())
        self.move(window_geometry.topLeft())

    def make_trayicon(self):
        """Make a Tray Icon."""
        if self.windowIcon() and __doc__:
            self.tray.setIcon(self.windowIcon())
            self.tray.setToolTip(__doc__)
            self.tray.activated.connect(
                lambda: self.hide() if self.isVisible()
                else self.showNormal())
            return self.tray.show()
Esempio n. 59
0
class ElectrumGui(PrintError):

    @profiler
    def __init__(self, config, daemon, plugins):
        set_language(config.get('language', get_default_language()))
        # Uncomment this call to verify objects are being properly
        # GC-ed when windows are closed
        #network.add_jobs([DebugMem([Abstract_Wallet, SPV, Synchronizer,
        #                            ElectrumWindow], interval=5)])
        QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_X11InitThreads)
        if hasattr(QtCore.Qt, "AA_ShareOpenGLContexts"):
            QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_ShareOpenGLContexts)
        if hasattr(QGuiApplication, 'setDesktopFileName'):
            QGuiApplication.setDesktopFileName('electrum.desktop')
        self.gui_thread = threading.current_thread()
        self.config = config
        self.daemon = daemon
        self.plugins = plugins
        self.windows = []
        self.efilter = OpenFileEventFilter(self.windows)
        self.app = QElectrumApplication(sys.argv)
        self.app.installEventFilter(self.efilter)
        self.app.setWindowIcon(read_QIcon("electrum.png"))
        # timer
        self.timer = QTimer(self.app)
        self.timer.setSingleShot(False)
        self.timer.setInterval(500)  # msec

        self.nd = None
        self.network_updated_signal_obj = QNetworkUpdatedSignalObject()
        self._num_wizards_in_progress = 0
        self._num_wizards_lock = threading.Lock()
        # init tray
        self.dark_icon = self.config.get("dark_icon", False)
        self.tray = QSystemTrayIcon(self.tray_icon(), None)
        self.tray.setToolTip('Electrum')
        self.tray.activated.connect(self.tray_activated)
        self.build_tray_menu()
        self.tray.show()
        self.app.new_window_signal.connect(self.start_new_window)
        self.set_dark_theme_if_needed()
        run_hook('init_qt', self)

    def set_dark_theme_if_needed(self):
        use_dark_theme = self.config.get('qt_gui_color_theme', 'default') == 'dark'
        if use_dark_theme:
            try:
                import qdarkstyle
                self.app.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())
            except BaseException as e:
                use_dark_theme = False
                self.print_error('Error setting dark theme: {}'.format(repr(e)))
        # Even if we ourselves don't set the dark theme,
        # the OS/window manager/etc might set *a dark theme*.
        # Hence, try to choose colors accordingly:
        ColorScheme.update_from_widget(QWidget(), force_dark=use_dark_theme)

    def build_tray_menu(self):
        # Avoid immediate GC of old menu when window closed via its action
        if self.tray.contextMenu() is None:
            m = QMenu()
            self.tray.setContextMenu(m)
        else:
            m = self.tray.contextMenu()
            m.clear()
        for window in self.windows:
            submenu = m.addMenu(window.wallet.basename())
            submenu.addAction(_("Show/Hide"), window.show_or_hide)
            submenu.addAction(_("Close"), window.close)
        m.addAction(_("Dark/Light"), self.toggle_tray_icon)
        m.addSeparator()
        m.addAction(_("Exit Electrum"), self.close)

    def tray_icon(self):
        if self.dark_icon:
            return read_QIcon('electrum_dark_icon.png')
        else:
            return read_QIcon('electrum_light_icon.png')

    def toggle_tray_icon(self):
        self.dark_icon = not self.dark_icon
        self.config.set_key("dark_icon", self.dark_icon, True)
        self.tray.setIcon(self.tray_icon())

    def tray_activated(self, reason):
        if reason == QSystemTrayIcon.DoubleClick:
            if all([w.is_hidden() for w in self.windows]):
                for w in self.windows:
                    w.bring_to_top()
            else:
                for w in self.windows:
                    w.hide()

    def close(self):
        for window in self.windows:
            window.close()

    def new_window(self, path, uri=None):
        # Use a signal as can be called from daemon thread
        self.app.new_window_signal.emit(path, uri)

    def show_network_dialog(self, parent):
        if not self.daemon.network:
            parent.show_warning(_('You are using Electrum in offline mode; restart Electrum if you want to get connected'), title=_('Offline'))
            return
        if self.nd:
            self.nd.on_update()
            self.nd.show()
            self.nd.raise_()
            return
        self.nd = NetworkDialog(self.daemon.network, self.config,
                                self.network_updated_signal_obj)
        self.nd.show()

    def _create_window_for_wallet(self, wallet):
        w = ElectrumWindow(self, wallet)
        self.windows.append(w)
        self.build_tray_menu()
        # FIXME: Remove in favour of the load_wallet hook
        run_hook('on_new_window', w)
        w.warn_if_watching_only()
        return w

    def count_wizards_in_progress(func):
        def wrapper(self: 'ElectrumGui', *args, **kwargs):
            with self._num_wizards_lock:
                self._num_wizards_in_progress += 1
            try:
                return func(self, *args, **kwargs)
            finally:
                with self._num_wizards_lock:
                    self._num_wizards_in_progress -= 1
        return wrapper

    @count_wizards_in_progress
    def start_new_window(self, path, uri, *, app_is_starting=False):
        '''Raises the window for the wallet if it is open.  Otherwise
        opens the wallet and creates a new window for it'''
        wallet = None
        try:
            wallet = self.daemon.load_wallet(path, None)
        except BaseException as e:
            traceback.print_exc(file=sys.stdout)
            QMessageBox.warning(None, _('Error'),
                                _('Cannot load wallet') + ' (1):\n' + str(e))
            # if app is starting, still let wizard to appear
            if not app_is_starting:
                return
        if not wallet:
            wallet = self._start_wizard_to_select_or_create_wallet(path)
        if not wallet:
            return
        # create or raise window
        try:
            for window in self.windows:
                if window.wallet.storage.path == wallet.storage.path:
                    break
            else:
                window = self._create_window_for_wallet(wallet)
        except BaseException as e:
            traceback.print_exc(file=sys.stdout)
            QMessageBox.warning(None, _('Error'),
                                _('Cannot create window for wallet') + ':\n' + str(e))
            if app_is_starting:
                wallet_dir = os.path.dirname(path)
                path = os.path.join(wallet_dir, get_new_wallet_name(wallet_dir))
                self.start_new_window(path, uri)
            return
        if uri:
            window.pay_to_URI(uri)
        window.bring_to_top()
        window.setWindowState(window.windowState() & ~QtCore.Qt.WindowMinimized | QtCore.Qt.WindowActive)

        window.activateWindow()
        return window

    def _start_wizard_to_select_or_create_wallet(self, path) -> Optional[Abstract_Wallet]:
        wizard = InstallWizard(self.config, self.app, self.plugins)
        try:
            path, storage = wizard.select_storage(path, self.daemon.get_wallet)
            # storage is None if file does not exist
            if storage is None:
                wizard.path = path  # needed by trustedcoin plugin
                wizard.run('new')
                storage = wizard.create_storage(path)
            else:
                wizard.run_upgrades(storage)
        except (UserCancelled, GoBack):
            return
        except WalletAlreadyOpenInMemory as e:
            return e.wallet
        except (WalletFileException, BitcoinException) as e:
            traceback.print_exc(file=sys.stderr)
            QMessageBox.warning(None, _('Error'),
                                _('Cannot load wallet') + ' (2):\n' + str(e))
            return
        finally:
            wizard.terminate()
        # return if wallet creation is not complete
        if storage is None or storage.get_action():
            return
        wallet = Wallet(storage)
        wallet.start_network(self.daemon.network)
        self.daemon.add_wallet(wallet)
        return wallet

    def close_window(self, window):
        if window in self.windows:
           self.windows.remove(window)
        self.build_tray_menu()
        # save wallet path of last open window
        if not self.windows:
            self.config.save_last_wallet(window.wallet)
        run_hook('on_close_window', window)
        self.daemon.stop_wallet(window.wallet.storage.path)

    def init_network(self):
        # Show network dialog if config does not exist
        if self.daemon.network:
            if self.config.get('auto_connect') is None:
                wizard = InstallWizard(self.config, self.app, self.plugins)
                wizard.init_network(self.daemon.network)
                wizard.terminate()

    def main(self):
        try:
            self.init_network()
        except UserCancelled:
            return
        except GoBack:
            return
        except BaseException as e:
            traceback.print_exc(file=sys.stdout)
            return
        self.timer.start()
        self.config.open_last_wallet()
        path = self.config.get_wallet_path()
        if not self.start_new_window(path, self.config.get('url'), app_is_starting=True):
            return
        signal.signal(signal.SIGINT, lambda *args: self.app.quit())

        def quit_after_last_window():
            # keep daemon running after close
            if self.config.get('daemon'):
                return
            # check if a wizard is in progress
            with self._num_wizards_lock:
                if self._num_wizards_in_progress > 0 or len(self.windows) > 0:
                    return
            self.app.quit()
        self.app.setQuitOnLastWindowClosed(False)  # so _we_ can decide whether to quit
        self.app.lastWindowClosed.connect(quit_after_last_window)

        def clean_up():
            # Shut down the timer cleanly
            self.timer.stop()
            # clipboard persistence. see http://www.mail-archive.com/[email protected]/msg17328.html
            event = QtCore.QEvent(QtCore.QEvent.Clipboard)
            self.app.sendEvent(self.app.clipboard(), event)
            self.tray.hide()
        self.app.aboutToQuit.connect(clean_up)

        # main loop
        self.app.exec_()
        # on some platforms the exec_ call may not return, so use clean_up()

    def stop(self):
        self.print_error('closing GUI')
        self.app.quit()
Esempio n. 60
0
class MainWindow(QMainWindow):
	"""The main GUI application."""
	def __init__(self, config):
		"""Initializer for the GUI widgets. Pass in an instance of Config class, so that it may interact with the config."""
		super().__init__()

		self.config = config

		self.setWindowTitle("Livestreamer GUI v{}".format(APPVERSION))

		self.setup_systray()
		self.setup_menu()
		self.setup_geometry()

		self.livestreamer_thread = None
		self.thread_exit_grace_time = 10000 # How long a thread can take to exit in milliseconds
		self.timestamp_format = self.config.get_config_value("timestamp-format")

		self.setup_control_widgets()
		self.update_colors()

		# Load all streaming-related data
		self.selections = {"streamer": None, "channel": None}
		self.load_streamers()
		self.load_channels(self.streamer_input.currentText())
		
		# Do the first configuration, if the application was run for the first time
		self.do_init_config()

		# Finally show the window and the system tray icon, if it should be shown
		self.show()

		self.close_override = False
		self.show_hide_systray()

		self.check_and_do_database_migration()

	def do_init_config(self):
		do_config = self.config.get_config_value("is-configured")
		if do_config == 0:
			self.menu_cmd_configure()
			self.config.set_config_value("is-configured", 1)
		self.insertText("Using config database version '{}'".format(self.config.get_config_value("db-version")))

	def setup_systray(self):
		if not self.config.get_config_value("enable-systray-icon"):
			self.systray = None
			return

		self.systray = QSystemTrayIcon(self)
		self.systray.activated.connect(self.systray_activated)
		main_menu = QMenu(self)

		quit_action = QAction("&Quit", self)
		quit_action.triggered.connect(self.on_close_override)
		main_menu.addAction(quit_action)

		self.systray.setContextMenu(main_menu)

	def systray_activated(self, reason):
		if reason == QSystemTrayIcon.Trigger:
			if self.isVisible():
				self.hide()
			else:
				self.showNormal()

	def check_and_do_database_migration(self):
		current_version = self.config.get_config_value("db-version")
		if self.config.is_migration_needed():
			self.insertText("Detected pending config database upgrade to version '{}'. Awaiting user input...".format(DBVERSION))
			message = "You are using an older version of the application config database.\n\nWould you like to upgrade the database now? Your existing config database will be backed up."

			upgrade_is_mandatory = current_version < MANDATORY_DBVERSION

			if upgrade_is_mandatory:
				message = message + "\n\nWARNING: Your config database is not compatible with this version of Livestreamer GUI. UPDATE IS MANDATORY! If you cancel the update, the application will exit."

			reply = QMessageBox.question(self, "Pending config database upgrade", message, QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
			if reply == QMessageBox.Yes:
				self.insertText("Backing up config database...")
				backup = self.config.make_database_backup()
				self.insertText("Current config database backed up to '{}'".format(backup))
				self.insertText("Config database update initialized...")
				self.update()
				self.config.execute_migration()
				new_version = self.config.get_config_value("db-version")
				self.insertText("Config database update from version '{}' to '{}' finished.".format(current_version, new_version))
			elif reply == QMessageBox.No and upgrade_is_mandatory:
				QtCore.QTimer.singleShot(500, self.on_close_override)
				# self.on_close_override() # Calling this in an __init__()-called method doesn't seem to work...
			else:
				self.insertText("Config database update cancelled. No changes were made.")

	def setup_menu(self):
		config_action = QAction("&Configure...", self)
		config_action.triggered.connect(self.menu_cmd_configure)

		quit_action = QAction("&Quit", self)
		quit_action.setShortcut("Ctrl+Q")
		quit_action.triggered.connect(self.on_close_override)

		menu = self.menuBar()
		file_menu = menu.addMenu("&File")
		file_menu.addAction(config_action)
		file_menu.addSeparator()
		file_menu.addAction(quit_action)

	def setup_geometry(self):
		width = self.config.get_config_value("root-width")
		height = self.config.get_config_value("root-height")

		topleft = QApplication.desktop().availableGeometry().topLeft()
		if self.config.get_config_value("remember-window-position"):
			xoffset = self.config.get_config_value("root-xoffset")
			yoffset = self.config.get_config_value("root-yoffset")
			topleft.setX(self.config.get_config_value("root-xoffset"))
			topleft.setY(self.config.get_config_value("root-yoffset"))

		self.resize(width, height)
		self.setMinimumSize(500, 300)
		self.move(topleft)

		# Center the window
		# center_point = QApplication.desktop().availableGeometry().center()
		# frame_geometry = self.frameGeometry()
		# frame_geometry.moveCenter(center_point)
		# self.move(frame_geometry.topLeft())

	def setup_control_widgets(self):
		self.cwidget = QWidget(self)
		self.setCentralWidget(self.cwidget)

		layout = QGridLayout(self.cwidget)
		self.cwidget.setLayout(layout)

		fg_fav = self.config.get_config_value("button-foreground-favorite")
		fg_edit = self.config.get_config_value("button-foreground-edit")
		fg_add = self.config.get_config_value("button-foreground-add")
		fg_delete = self.config.get_config_value("button-foreground-delete")

		control_button_width = 30
		control_button_font_style = "QPushButton { font-family: Arial, sans-serif; font-size: 16px }"

		column = 0
		label_streamer_input = QLabel("Streamer", self.cwidget)
		layout.addWidget(label_streamer_input, 0, column)
		label_channel_input = QLabel("Channel", self.cwidget)
		layout.addWidget(label_channel_input, 1, column)
		label_quality_input = QLabel("Stream quality", self.cwidget)
		layout.addWidget(label_quality_input, 2, column)

		column += 1
		self.streamer_input = QComboBox(self.cwidget)
		self.streamer_input.setEnabled(False)
		self.streamer_input.currentIndexChanged.connect(self.on_streamer_select)
		layout.addWidget(self.streamer_input, 0, column)
		self.channel_input = QComboBox(self.cwidget)
		self.channel_input.setEnabled(False)
		self.channel_input.currentIndexChanged.connect(self.on_channel_select)
		layout.addWidget(self.channel_input, 1, column)
		self.quality_input = QComboBox(self.cwidget)
		self.quality_input.addItem("(auto-refresh is disabled; please refresh manually)")
		self.quality_input.setEnabled(False)
		layout.addWidget(self.quality_input, 2, column)
		layout.setColumnStretch(column, 5)

		column += 1
		self.fav_streamer_button = QPushButton("\u2764", self.cwidget)
		self.fav_streamer_button.setMaximumWidth(control_button_width)
		self.fav_streamer_button.setStyleSheet(":enabled {{ color: {0} }} {1}".format(fg_fav, control_button_font_style))
		self.fav_streamer_button.setEnabled(False)
		self.fav_streamer_button.setToolTip("Set the selected streamer as your most favorite streamer")
		self.fav_streamer_button.clicked.connect(self.cmd_set_favorite_streamer)
		layout.addWidget(self.fav_streamer_button, 0, column)
		self.fav_channel_button = QPushButton("\u2764", self.cwidget)
		self.fav_channel_button.setMaximumWidth(control_button_width)
		self.fav_channel_button.setStyleSheet(':enabled {{ color: {0} }} {1}'.format(fg_fav, control_button_font_style))
		self.fav_channel_button.setEnabled(False)
		self.fav_channel_button.setToolTip("Set the selected channel as your most favorite channel")
		self.fav_channel_button.clicked.connect(self.cmd_set_favorite_channel)
		layout.addWidget(self.fav_channel_button, 1, column)
		self.clear_quality_cache_button = QPushButton("Refresh streams", self.cwidget)
		self.clear_quality_cache_button.setEnabled(False)
		self.clear_quality_cache_button.clicked.connect(self.cmd_refresh_quality_cache)
		layout.addWidget(self.clear_quality_cache_button, 2, column, 1, 4)

		column += 1
		self.edit_streamer_button = QPushButton("\u270E", self.cwidget)
		self.edit_streamer_button.setMaximumWidth(control_button_width)
		self.edit_streamer_button.setStyleSheet(":enabled {{ color: {0} }} {1}".format(fg_edit, control_button_font_style))
		self.edit_streamer_button.setEnabled(False)
		self.edit_streamer_button.setToolTip("Edit data about the selected streamer")
		self.edit_streamer_button.clicked.connect(self.cmd_edit_streamer)
		layout.addWidget(self.edit_streamer_button, 0, column)
		self.edit_channel_button = QPushButton("\u270E", self.cwidget)
		self.edit_channel_button.setMaximumWidth(control_button_width)
		self.edit_channel_button.setStyleSheet(":enabled {{ color: {0} }} {1}".format(fg_edit, control_button_font_style))
		self.edit_channel_button.setToolTip("Edit data about the selected channel")
		self.edit_channel_button.clicked.connect(self.cmd_edit_channel)
		layout.addWidget(self.edit_channel_button, 1, column)

		column += 1
		self.add_streamer_button = QPushButton("\u271A", self.cwidget)
		self.add_streamer_button.setMaximumWidth(control_button_width)
		self.add_streamer_button.setStyleSheet(":enabled {{ color: {0} }} {1}".format(fg_add, control_button_font_style))
		self.add_streamer_button.setEnabled(False)
		self.add_streamer_button.setToolTip("Add a new streamer")
		self.add_streamer_button.clicked.connect(self.cmd_add_streamer)
		layout.addWidget(self.add_streamer_button, 0, column)
		self.add_channel_button = QPushButton("\u271A", self.cwidget)
		self.add_channel_button.setMaximumWidth(control_button_width)
		self.add_channel_button.setStyleSheet(":enabled {{ color: {0} }} {1}".format(fg_add, control_button_font_style))
		self.add_channel_button.setToolTip("Add a new channel")
		self.add_channel_button.clicked.connect(self.cmd_add_channel)
		layout.addWidget(self.add_channel_button, 1, column)

		column += 1
		self.delete_streamer_button = QPushButton("\u2716", self.cwidget)
		self.delete_streamer_button.setMaximumWidth(control_button_width)
		self.delete_streamer_button.setStyleSheet(":enabled {{ color: {0} }} {1}".format(fg_delete, control_button_font_style))
		self.delete_streamer_button.setEnabled(False)
		self.delete_streamer_button.setToolTip("Remove the selected streamer permanently")
		self.delete_streamer_button.clicked.connect(self.cmd_delete_streamer)
		layout.addWidget(self.delete_streamer_button, 0, column)
		self.delete_channel_button = QPushButton("\u2716", self.cwidget)
		self.delete_channel_button.setMaximumWidth(control_button_width)
		self.delete_channel_button.setStyleSheet(":enabled {{ color: {0} }} {1}".format(fg_delete, control_button_font_style))
		self.delete_channel_button.setToolTip("Remove the selected channel permanently")
		self.delete_channel_button.clicked.connect(self.cmd_delete_channel)
		layout.addWidget(self.delete_channel_button, 1, column)

		# Add button for running livestreamer at the fourth row
		self.run_livestreamer_button = QPushButton("Run Livestreamer", self.cwidget)
		self.run_livestreamer_button.setEnabled(False)
		self.run_livestreamer_button.clicked.connect(self.run_livestreamer)
		layout.addWidget(self.run_livestreamer_button, 3, 0)

		self.log_widget = QTextEdit(self.cwidget)
		layout.addWidget(self.log_widget, 4, 0, 1, column+1)
		self.log_widget.setAcceptRichText(False)
		self.log_widget.setReadOnly(True)
		self.log_widget.setTabChangesFocus(True)

	def set_window_icon(self):
		"""Sets the root window's icon, which is also shown in the taskbar."""
		streamer = self.config.get_streamer(self.streamer_input.currentText())
		icon = QIcon(os.path.join(IMAGESROOT, streamer["icon"]))
		self.setWindowIcon(icon)

		if self.systray is not None:
			self.systray.setIcon(icon)

	def closeEvent(self, event):
		"""When the QWidget is closed, QCloseEvent is triggered, and this method catches and handles it."""
		if not self.close_override and self.put_to_systray("close"):
			event.ignore()
			return

		if self.livestreamer_thread is not None and self.livestreamer_thread.keep_running:
			reply = QMessageBox.question(self, "Really quit Livestreamer GUI?", "Livestreamer is still running. Quitting will close it and the opened player.\n\nQuit?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
			if reply == QMessageBox.Yes:
				# Terminate the child process, else it'll keep running even after this application is closed
				if self.livestreamer_thread is not None:
					self.livestreamer_thread.term_process()
					self.livestreamer_thread.wait(self.thread_exit_grace_time)
					self.update()
				event.accept()
			else:
				event.ignore()

		# Explicitly hide the icon, if it remains visible after the application closes
		if self.systray is not None:
			self.systray.hide()

		# Remember the position of the window
		self.remember_window_position()

		event.accept()

	def changeEvent(self, event):
		if type(event) is not QWindowStateChangeEvent:
			return

		# It's one of the window state change events (normal, minimize, maximize, fullscreen, active)
		if self.isMinimized():
			self.put_to_systray("minimize")

	def remember_window_position(self):
		if self.config.get_config_value("remember-window-position"):
			point = self.frameGeometry().topLeft()
			self.config.set_config_value("root-xoffset", point.x())
			self.config.set_config_value("root-yoffset", point.y())
			self.insertText("Window position saved.")

	def show_hide_systray(self):
		if self.systray is None:
			self.setup_systray()
			if self.systray is None:
				return

		if self.config.get_config_value("enable-systray-icon"):
			self.systray.show()
		else:
			self.systray.hide()

	def put_to_systray(self, event):
		if event == "minimize":
			config_value = "minimize-to-systray"
		elif event == "close":
			config_value = "close-to-systray"
		else:
			return False

		if self.systray is not None and self.config.get_config_value(config_value) and self.isVisible():
			self.hide()
			return True
		return False

	def menu_cmd_configure(self):
		streamer = self.config.get_streamer(self.streamer_input.currentText())
		dialog = AppConfigDialog(self, self.config, streamer_icon=os.path.join(IMAGESROOT, streamer["icon"]))
		dialog.exec()
		if dialog.result() == QDialog.Accepted:
			self.show_hide_systray()
			self.update_colors()
		dialog.close()
		dialog = None

	def cmd_set_favorite_streamer(self):
		raise NotImplementedException()
		# self.fav_streamer_button.setEnabled(False)
		# self.config.set_favorite_streamer(self.streamer_input.setCurrentText())
		# self.insertText("Favorited streamer '{}'.".format(self.streamer_input.setCurrentText()))

	def cmd_edit_streamer(self):
		raise NotImplementedException()

	def cmd_add_streamer(self):
		raise NotImplementedException()

	def cmd_delete_streamer(self):
		raise NotImplementedException()

	def cmd_set_favorite_channel(self):
		self.fav_channel_button.setEnabled(False)
		self.config.set_favorite_channel(self.streamer_input.currentText(), self.channel_input.currentText())
		self.insertText("Favorited channel '{}'.".format(self.channel_input.currentText()))

	def cmd_edit_channel(self):
		streamer = self.config.get_streamer(self.streamer_input.currentText())
		streamer_icon = os.path.join(IMAGESROOT, streamer["icon"])
		channel_data = self.config.get_streamer_channel(streamer["name"], self.channel_input.currentText())
		dialog = AddEditChannelsDialog(self, self.config, title="Edit the channel", streamer_icon=streamer_icon, streamer=streamer, channel_data=channel_data)
		dialog.exec()
		result = dialog.result_data
		dialog.close()
		dialog = None
		if result is not None:
			self.insertText("Updated channel name '{old_name}' => '{new_name}, URL '{old_url}' => '{new_url}'".format(old_name=channel_data["name"], new_name=result["name"], old_url=channel_data["url"], new_url=result["url"]))
			self.load_channels(streamer["name"])
			
			# Set the active channel to the previously selected (due to possible name change and sorting)
			self.channel_input.setCurrentIndex(self.channel_input.findText(result["name"]))
			
	def cmd_add_channel(self):
		streamer = self.config.get_streamer(self.streamer_input.currentText())
		streamer_icon = os.path.join(IMAGESROOT, streamer["icon"])
		dialog = AddEditChannelsDialog(self, self.config, title="Add a channel", streamer_icon=streamer_icon, streamer=streamer)
		dialog.exec()
		result = dialog.result_data
		dialog.close()
		dialog = None
		if result is not None:
			self.insertText("Added channel '{}' with URL '{}'".format(result["name"], result["url"]))
			self.load_channels(streamer["name"])

	def cmd_delete_channel(self):
		channel = self.config.get_streamer_channel(self.streamer_input.currentText(), self.channel_input.currentText())
		reply = QMessageBox.question(self, "Delete channel", "Are you sure you want to remove the channel?\nName: {}\nURL: {}".format(channel["name"], channel["url"]), QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
		if reply == QMessageBox.Yes:
			self.config.delete_channel(self.streamer_input.currentText(), channel["name"])
			self.insertText("Removed channel '{}' with URL '{}'".format(channel["name"], channel["url"]))
			self.load_channels(self.streamer_input.currentText())

	def cmd_refresh_quality_cache(self):
		self.insertText("Refreshing cache for channel '{}'.".format(self.channel_input.currentText()))
		self.clear_quality_cache_button.setEnabled(False)
		self.clear_quality_cache_button.repaint() # Loading streams seems to block repainting of the GUI, so force a repaint here
		self.config.clean_quality_cache(self.streamer_input.currentText(), self.channel_input.currentText(), True)
		self.load_streams(True)
		self.clear_quality_cache_button.setEnabled(True)

	def on_close_override(self):
		self.close_override = True
		self.close()

	def on_streamer_select(self, event):
		# If the previously selected item is selected again, don't do anything
		if self.selections["streamer"] == self.streamer_input.currentText():
			return
		self.selections["streamer"] = self.streamer_input.currentText()
		streamer = self.config.get_streamer(self.streamer_input.currentText())
		self.set_window_icon()
		if streamer["favorite"]:
			self.fav_streamer_button.setEnabled(False)
		else:
			self.fav_streamer_button.setEnabled(True)

	def on_channel_select(self, event):
		# If the previously selected item is selected again, don't do anything
		if self.selections["channel"] == self.channel_input.currentText() or not self.channel_input.currentText():
			return
		self.selections["channel"] = self.channel_input.currentText()
		channel = self.config.get_streamer_channel(self.streamer_input.currentText(), self.channel_input.currentText())
		if channel and channel["favorite"]:
			self.fav_channel_button.setEnabled(False)
		else:
			self.fav_channel_button.setEnabled(True)

		self.load_streams()
		self.channel_input.setFocus(True)

	def load_streamers(self):
		streamers = self.config.get_streamers()
		favorite_streamer_index = 0
		streamer_list = []
		for index, streamer in enumerate(streamers):
			streamer_list.append(streamer["name"])
			if streamer["favorite"]:
				favorite_streamer_index = index
		self.streamer_input.clear()
		self.streamer_input.addItems(streamer_list)
		if len(streamer_list) != 0:
			self.streamer_input.setCurrentIndex(favorite_streamer_index)
		self.selections["streamer"] = self.streamer_input.currentText()
		self.fav_streamer_button.setEnabled(False)

	def load_channels(self, streamer_name):
		channels = self.config.get_streamer_channels(streamer_name)
		self.channel_input.clear()
		favorite_channel = None
		channel_list = []
		self.fav_channel_button.setEnabled(False)
		for index, channel in enumerate(channels):
			channel_list.append(channel["name"])
			if channel["favorite"]:
				favorite_channel = channel["name"]
		self.channel_input.addItems(sorted(channel_list))
		if len(channel_list) == 0:
			self.channel_input.addItem("(no channels exist for this streamer)")
			self.fav_channel_button.setEnabled(False)
			self.edit_channel_button.setEnabled(False)
			self.delete_channel_button.setEnabled(False)
			self.clear_quality_cache_button.setEnabled(False)
			self.channel_input.setEnabled(False)
		else:
			self.edit_channel_button.setEnabled(True)
			self.delete_channel_button.setEnabled(True)
			self.clear_quality_cache_button.setEnabled(True)
			self.channel_input.setEnabled(True)
			
			if favorite_channel is None:
				self.channel_input.setCurrentIndex(0)
				self.fav_channel_button.setEnabled(True)
			else:
				self.channel_input.setCurrentIndex(self.channel_input.findText(favorite_channel))

		self.selections["channel"] = self.channel_input.currentText()

	def display_loaded_streams(self, streams, skip_caching=False):
		self.quality_input.clear()
		if len(streams) == 0:
			self.quality_input.addItem("(channel is currently not streaming)")
		else:
			self.run_livestreamer_button.setEnabled(True)
			self.clear_quality_cache_button.setEnabled(True)
			self.quality_input.addItems(sorted(streams))
			self.quality_input.setCurrentIndex(0)
			self.quality_input.setEnabled(True)
			if not skip_caching:
				self.insertText("Cleaning any cached streams for channel '{}'...".format(self.channel_input.currentText()))
				self.config.clean_quality_cache(self.streamer_input.currentText(), self.channel_input.currentText())
				self.insertText("Adding probed streams for channel '{}' to cache...".format(self.channel_input.currentText()))
				self.config.add_quality_to_cache(self.streamer_input.currentText(), self.channel_input.currentText(), streams)
				self.insertText("Done.")

	def load_streams(self, force_refresh=False):
		self.quality_input.clear()
		self.run_livestreamer_button.setEnabled(False)
		self.channel_input.setEnabled(False)
		self.quality_input.setEnabled(False)

		if self.channel_input.count() == 0:
			return

		streams = self.config.get_quality_from_cache(self.streamer_input.currentText(), self.channel_input.currentText())
		if len(streams) > 0:
			self.display_loaded_streams(streams, True)
			self.insertText("Loaded streams for channel '{}' from cache.".format(self.channel_input.currentText()))
		else:
			self.insertText("No cached channel streams found for channel '{}'".format(self.channel_input.currentText()))
			if not force_refresh and self.config.get_config_value('auto-refresh-quality') == 0:
				self.quality_input.addItem("(auto-refresh is disabled; please refresh manually)")
				self.quality_input.setEnabled(False)
			else:
				stream_url = self.get_streamer_url()
				if stream_url is None:
					self.insertText("Failed to form a complete streamer URL (missing streamer/channel/stream)!")
					return
				self.probe_for_streams(stream_url)
		
		self.channel_input.setEnabled(True)

	def probe_for_streams(self, stream_url):
		self.insertText("Probing streamer's channel for live streams: {}".format(stream_url))
		livestreamer = self.config.get_config_value("livestreamer-path")
		if livestreamer is None or livestreamer.strip() == "" or not os.path.isfile(livestreamer):
			self.insertText("Livestreamer path is not configured or file doesn't exist!")
			return
		command_format = self.config.get_config_value("probe-command-format")
		command = command_format.format(livestreamer=livestreamer, url=stream_url)
		self.livestreamer_thread = LivestreamerWorker(shlex.split(command))
		self.livestreamer_thread.statusMessage.connect(self.parse_probed_streams, False)
		self.livestreamer_thread.start()
		self.livestreamer_thread.wait(self.thread_exit_grace_time)

	def parse_probed_streams(self, event):
		streams = []

		message = event.message.lower()
		if "no streams found on this url" in message:
			self.insertText("No streams found. The channel is probably not streaming.")
		else:
			pos = message.find("available streams:")
			if pos == -1:
				return

			if "(best, worst)" in message:
				message = message.replace("(best, worst)", "(best and worst)")
			elif "(worst, best)" in message:
				message = message.replace("(worst, best)", "(worst and best)")
			qualities = message[pos+18:].split(",")
			for item in qualities:
				streams.append(item.strip())
				left_parenthesis = item.find("(")
				if left_parenthesis == -1:
					continue
				if item.find("worst", left_parenthesis) >= left_parenthesis:
					streams.append("worst")
				if item.find("best", left_parenthesis) >= left_parenthesis:
					streams.append("best")
			streams.sort()
			self.insertText("Found {} stream(s): {}".format(len(streams), ", ".join(streams)))

		self.display_loaded_streams(streams)

	def get_streamer_url(self):
		streamer = self.config.get_streamer(self.streamer_input.currentText())
		if streamer is None:
			self.insertText("No streamer selected!")
			return
		if streamer["url"] is None or streamer["url"].strip() == "":
			self.insertText("Invalid streamer URL!")
			return
		if self.channel_input.count() == 0:
			self.insertText("No channels exist!")
			return
		channel = self.config.get_streamer_channel(streamer["name"], self.channel_input.currentText())
		return urljoin(streamer["url"], channel["url"])

	def run_livestreamer(self):
		if self.livestreamer_thread is not None:
			if self.livestreamer_thread.isRunning():
				self.insertText("Livestreamer should still be running!")
				return
			else:
				self.livestreamer_thread.wait(self.thread_exit_grace_time)
				self.livestreamer_thread = None
				self.update()

		if self.livestreamer_thread is None:
			livestreamer = self.config.get_config_value("livestreamer-path")
			if livestreamer is None or livestreamer.strip() == "" or not os.path.isfile(livestreamer):
				self.insertText("Livestreamer path is not configured or file doesn't exist!")
				return
			player = self.config.get_config_value("player-path")
			if player is None or player.strip() == "" or not os.path.isfile(player):
				self.insertText("Player path is not configured or file doesn't exist!")
				return
			stream_url = self.get_streamer_url()
			if stream_url is None:
				self.insertText("Failed to form a complete streamer URL (missing streamer/channel/stream)!")
				return
			command_format = self.config.get_config_value("command-format")
			quality = self.quality_input.currentText()
			if "(" in quality:
				quality = quality[:quality.find("(")].strip()
			command = command_format.format(livestreamer=livestreamer, player=player, url=stream_url, quality=quality)
			self.livestreamer_thread = LivestreamerWorker(shlex.split(command))
			self.insertText("Starting Livestreamer thread.")
			self.livestreamer_thread.finished.connect(self.handle_livestreamer_thread_finished_signal)
			self.livestreamer_thread.statusMessage.connect(self.handle_livestreamer_thread_message_signal)
			self.livestreamer_thread.start()

	@QtCore.pyqtSlot(object)
	def handle_livestreamer_thread_message_signal(self, event):
		self.insertText(event.message, event.add_newline, event.add_timestamp)

	def handle_livestreamer_thread_finished_signal(self):
		self.livestreamer_thread = None

	def update_colors(self):
		foreground_color = self.config.get_config_value("foreground-color")
		background_color = self.config.get_config_value("background-color")
		self.cwidget.setStyleSheet("QWidget QLabel {{ color: {0} }} .QWidget {{ background-color: {1} }}".format(foreground_color, background_color))
		self.cwidget.update()

	def insertText(self, msg, add_newline=True, timestamp=True):
		"""Helper method for outputting text to the text box."""
		text = ""
		if timestamp and self.timestamp_format is not None:
			timestamp = format(datetime.now().strftime(self.timestamp_format))
			text = "{} ".format(timestamp)
		text += msg
		self.log_widget.moveCursor(QTextCursor.End)
		self.log_widget.insertPlainText(text)
		if add_newline:
			self.log_widget.insertPlainText("\n")
		self.log_widget.update()