예제 #1
0
def main():
    app = QtWidgets.QApplication(sys.argv)
    app.setOrganizationName("Leitisoft")
    app.setOrganizationDomain("leitschuh.net")
    app.setApplicationName("SnapSort")

    app.setQuitOnLastWindowClosed(False)
    w = QtWidgets.QWidget()
    wait_window = TrayIcon(QtGui.QIcon("resources/images/icon_systray.png"), w)
    wait_window.show()

    sys.exit(app.exec_())
예제 #2
0
파일: Main.py 프로젝트: varunkamble2018/cbi
def main():
    __pychecker__ = 'unusednames=tray'

    gnome.program_init('tray', SamplerConfig.version)
    unique = Service.unique()
    if not unique: return

    client = gconf.client_get_default()
    gconf_dir = GConfDir(client, Keys.root, gconf.CLIENT_PRELOAD_ONELEVEL)

    tray = TrayIcon(client)
    gtk.main()

    del gconf_dir
예제 #3
0
파일: __main__.py 프로젝트: ruXlab/SafeEyes
def main():
    initialize_config()

    # Configure logging. Reset with every restart
    logging.basicConfig(
        format='%(asctime)s [%(levelname)s]:[%(threadName)s] %(message)s',
        filename=log_file_path,
        filemode='w',
        level=logging.INFO)
    logging.info("Starting Safe Eyes")

    if not running():
        validate_config()

        global break_screen
        global core
        global notification
        global tray_icon
        global language
        global context

        context = {}
        language = Utility.load_language(config['language'])

        # Initialize the Safe Eyes Context
        context['version'] = SAFE_EYES_VERSION

        tray_icon = TrayIcon(config, language, show_settings, show_about,
                             enable_safeeyes, disable_safeeyes, on_quit)
        break_screen = BreakScreen(on_skipped, on_postponed,
                                   break_screen_glade, style_sheet_path)
        break_screen.initialize(config, language)
        core = SafeEyesCore(context, show_notification, show_alert,
                            close_alert, on_countdown,
                            tray_icon.next_break_time)
        core.initialize(config, language)
        core.start()
        notification = Notification(language)

        handle_system_suspend()

        Gtk.main()
    else:
        logging.info('SafeEyes is already running')
        sys.exit(0)
예제 #4
0
파일: main.py 프로젝트: rrader/powerstatt
 def __init__(self, parent):
     wx.Frame.__init__(self,
                       parent,
                       -1,
                       "Battery state",
                       style=wx.BORDER_DEFAULT,
                       size=(
                           240,
                           120,
                       ))
     self.panel = wx.Panel(self, -1)
     self._params = {
         dr.BAT_CHARGINGSTATE: "Charging state",
         dr.BAT_PRESENTRATE: "Present rate",
         dr.BAT_PRESENTVOLTAGE: "Present voltage",
         dr.BAT_REMAININGCAPACITY: "Remaining capacity"
     }
     self._ys = [10, 35, 60, 85]
     make_text_ctrl = lambda y: wx.TextCtrl(self.panel,
                                            -1,
                                            "",
                                            pos=(150, y),
                                            style=wx.TE_READONLY,
                                            size=(80, -1))
     make_static_text = lambda text, y: wx.StaticText(
         self.panel, -1, text, pos=(10, y))
     self._st = map(make_static_text, self._params.values(), self._ys)
     self._ed = dict(zip(self._params, map(make_text_ctrl, self._ys)))
     #updater
     self.info_getter = dr.IGSys("BAT0")
     self.fill_info(None)
     self.Bind(wx.EVT_TIMER, self.fill_info)
     self.timer = wx.Timer(self)
     self.timer.Start(3000)
     self.fill_info(None)
     self.tray = TrayIcon(self)
예제 #5
0
 def __init__(self, parent=None):
     QtGui.QMainWindow.__init__(self, parent)
     self.setWindowTitle(u'掉话分析')
     self.setWindowIcon(QtGui.QIcon(resource_path('img/log.png')))
     self.centralwidget = QWidget()
     self.setCentralWidget(self.centralwidget)
     self.resize(1000, 500)
     self.mainLayout = QtGui.QVBoxLayout()
     self.mainLayout.setAlignment(QtCore.Qt.AlignTop)
     self.mainLayout.setContentsMargins(5, 2, 5, 2)
     # select directory
     self.selectDirectoryLayout = QtGui.QHBoxLayout()
     self.selectDirectoryLineEdit = QtGui.QLineEdit()
     self.selectDirectoryLineEdit.setTextMargins(10, 0, 10, 0)
     self.selectDirectoryLineEdit.setMinimumHeight(25)
     self.selectDirectoryLineEdit.setFont(QtFontUtil().getFont(
         'Monospace', 12))
     self.selectDirectoryBtn = QtGui.QPushButton(u'选择文件夹')
     self.selectDirectoryBtn.connect(self.selectDirectoryBtn,
                                     QtCore.SIGNAL('clicked()'),
                                     self.selectDirectoryMethod)
     self.selectDirectoryLayout.addWidget(self.selectDirectoryBtn)
     self.selectDirectoryLayout.addWidget(self.selectDirectoryLineEdit)
     # download the log [from http://172.28.199.58/watch/index_prod.html#/watchda_web/logCollection]
     self.downloadLogLayout = QtGui.QHBoxLayout()
     self.dlBinderNumberLineEdit = QtGui.QLineEdit()
     self.dlBinderNumberLineEdit.setTextMargins(10, 0, 10, 0)
     self.dlBinderNumberLineEdit.setMinimumHeight(25)
     self.dlBinderNumberLineEdit.setFont(QtFontUtil().getFont(
         'Monospace', 12))
     self.dlImportBinderNumberBtn = QtGui.QPushButton(u'导入绑定号')
     self.dlImportBinderNumberBtn.connect(self.dlImportBinderNumberBtn,
                                          QtCore.SIGNAL('clicked()'),
                                          self.dlImportBinderNumberMethod)
     self.downloadLogLayout.addWidget(self.dlImportBinderNumberBtn)
     self.downloadLogLayout.addWidget(self.dlBinderNumberLineEdit)
     # analytics key word
     self.keywordLayout = QtGui.QHBoxLayout()
     self.keywordLineEdit = QtGui.QLineEdit()
     self.keywordLineEdit.setPlaceholderText(u'reportCallFailLD =')
     self.keywordLineEdit.setTextMargins(10, 0, 10, 0)
     self.keywordLineEdit.setMinimumHeight(25)
     self.keywordLineEdit.setFont(QtFontUtil().getFont('Monospace', 12))
     self.keywordBtn = QtGui.QPushButton(u'输入关键字')
     self.keywordBtn.setDisabled(True)
     self.keywordLayout.addWidget(self.keywordBtn)
     self.keywordLayout.addWidget(self.keywordLineEdit)
     # operate buttons
     self.btnsLayout = QtGui.QHBoxLayout()
     self.downloadLogBtn = QtGui.QPushButton(u'下载日志')
     self.unzipBtn = QtGui.QPushButton(u'解压日志')
     self.analyticsBtn = QtGui.QPushButton(u'开始分析')
     self.generateDocumentBtn = QtGui.QPushButton(u'生成文档')
     self.openDirBtn = QtGui.QPushButton(u'打开文件夹')
     self.unzipBtn.setMinimumHeight(25)
     self.analyticsBtn.setMinimumHeight(25)
     self.generateDocumentBtn.setMinimumHeight(25)
     self.openDirBtn.setMinimumHeight(25)
     self.downloadLogBtn.connect(self.downloadLogBtn,
                                 QtCore.SIGNAL('clicked()'),
                                 self.downloadLogMethod)
     self.unzipBtn.connect(self.unzipBtn, QtCore.SIGNAL('clicked()'),
                           self.unZipMethod)
     self.analyticsBtn.connect(self.analyticsBtn,
                               QtCore.SIGNAL('clicked()'),
                               self.analyticsMethod)
     self.analyticsBtn.connect(self.analyticsBtn,
                               QtCore.SIGNAL('combineLogSignal(QString)'),
                               self.combineLogWithAttr)
     self.generateDocumentBtn.connect(self.generateDocumentBtn,
                                      QtCore.SIGNAL('clicked()'),
                                      self.genDocMethod)
     self.openDirBtn.connect(self.openDirBtn, QtCore.SIGNAL('clicked()'),
                             self.openDirMethod)
     self.btnsLayout.addWidget(self.downloadLogBtn)
     self.btnsLayout.addWidget(self.unzipBtn)
     self.btnsLayout.addWidget(self.analyticsBtn)
     self.btnsLayout.addWidget(self.generateDocumentBtn)
     self.btnsLayout.addWidget(self.openDirBtn)
     # show log
     self.LogTextEdit = QtGui.QTextEdit()
     self.LogTextEdit.setSizePolicy(QSizePolicy.Expanding,
                                    QSizePolicy.Expanding)
     self.LogTextEdit.setFont(QtFontUtil().getFont('Monospace', 12))
     self.LogTextEdit.connect(self.LogTextEdit,
                              QtCore.SIGNAL('appendLogSignal(QString)'),
                              self.appendLog)
     # addLayout
     self.mainLayout.addLayout(self.selectDirectoryLayout)
     self.mainLayout.addLayout(self.downloadLogLayout)
     self.mainLayout.addLayout(self.keywordLayout)
     self.mainLayout.addLayout(self.btnsLayout)
     self.mainLayout.addWidget(self.LogTextEdit)
     self.centralwidget.setLayout(self.mainLayout)
     # 优化文件数据分析性能,已分组形式进行, 这两个变量记录总共需要分析的分组数量,以及已经分析的组数
     # self.analyticsGroupTotalSize = 0
     # self.processedGroupSize = 0
     # self.processedGroupLock = threading.Lock()
     # 接收 keywordLineEdit 中输入的关键字
     self.analyKeyword = None
     # 接收基础信息 baseAttr 的关键字
     self.baseAttrKeyword = None
     # # 搜索keyword 时,返回包含keyword的行数据
     # self.searchedKeywordLines = ""
     # # 搜索基础信息baseAttr时, 返回包含baseAttr的行数据
     # self.searchedBaseAttrLines = ""
     # 保存分析的日志信息集合
     self.analyticsLogList = []
     # 保存基本信息的集合
     self.baseAttrList = []
     # 多线程中进行集合过滤的锁
     self.filterLogLock = threading.Lock()
     self.filterAttrLock = threading.Lock()
     # 保存最后分析结果 CallFailBean 的集合
     self.callFailList = []
     # 保存从excel 导入的绑定号集合
     self.binderNumberList = []
     # 显示托盘
     self.tray = TrayIcon(parent=self, clickEnable=False)
     self.tray.connect(self.tray,
                       QtCore.SIGNAL('showTrayMsgSignal(QString)'),
                       self.showTrayMsg)
예제 #6
0
class CallFailWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QMainWindow.__init__(self, parent)
        self.setWindowTitle(u'掉话分析')
        self.setWindowIcon(QtGui.QIcon(resource_path('img/log.png')))
        self.centralwidget = QWidget()
        self.setCentralWidget(self.centralwidget)
        self.resize(1000, 500)
        self.mainLayout = QtGui.QVBoxLayout()
        self.mainLayout.setAlignment(QtCore.Qt.AlignTop)
        self.mainLayout.setContentsMargins(5, 2, 5, 2)
        # select directory
        self.selectDirectoryLayout = QtGui.QHBoxLayout()
        self.selectDirectoryLineEdit = QtGui.QLineEdit()
        self.selectDirectoryLineEdit.setTextMargins(10, 0, 10, 0)
        self.selectDirectoryLineEdit.setMinimumHeight(25)
        self.selectDirectoryLineEdit.setFont(QtFontUtil().getFont(
            'Monospace', 12))
        self.selectDirectoryBtn = QtGui.QPushButton(u'选择文件夹')
        self.selectDirectoryBtn.connect(self.selectDirectoryBtn,
                                        QtCore.SIGNAL('clicked()'),
                                        self.selectDirectoryMethod)
        self.selectDirectoryLayout.addWidget(self.selectDirectoryBtn)
        self.selectDirectoryLayout.addWidget(self.selectDirectoryLineEdit)
        # download the log [from http://172.28.199.58/watch/index_prod.html#/watchda_web/logCollection]
        self.downloadLogLayout = QtGui.QHBoxLayout()
        self.dlBinderNumberLineEdit = QtGui.QLineEdit()
        self.dlBinderNumberLineEdit.setTextMargins(10, 0, 10, 0)
        self.dlBinderNumberLineEdit.setMinimumHeight(25)
        self.dlBinderNumberLineEdit.setFont(QtFontUtil().getFont(
            'Monospace', 12))
        self.dlImportBinderNumberBtn = QtGui.QPushButton(u'导入绑定号')
        self.dlImportBinderNumberBtn.connect(self.dlImportBinderNumberBtn,
                                             QtCore.SIGNAL('clicked()'),
                                             self.dlImportBinderNumberMethod)
        self.downloadLogLayout.addWidget(self.dlImportBinderNumberBtn)
        self.downloadLogLayout.addWidget(self.dlBinderNumberLineEdit)
        # analytics key word
        self.keywordLayout = QtGui.QHBoxLayout()
        self.keywordLineEdit = QtGui.QLineEdit()
        self.keywordLineEdit.setPlaceholderText(u'reportCallFailLD =')
        self.keywordLineEdit.setTextMargins(10, 0, 10, 0)
        self.keywordLineEdit.setMinimumHeight(25)
        self.keywordLineEdit.setFont(QtFontUtil().getFont('Monospace', 12))
        self.keywordBtn = QtGui.QPushButton(u'输入关键字')
        self.keywordBtn.setDisabled(True)
        self.keywordLayout.addWidget(self.keywordBtn)
        self.keywordLayout.addWidget(self.keywordLineEdit)
        # operate buttons
        self.btnsLayout = QtGui.QHBoxLayout()
        self.downloadLogBtn = QtGui.QPushButton(u'下载日志')
        self.unzipBtn = QtGui.QPushButton(u'解压日志')
        self.analyticsBtn = QtGui.QPushButton(u'开始分析')
        self.generateDocumentBtn = QtGui.QPushButton(u'生成文档')
        self.openDirBtn = QtGui.QPushButton(u'打开文件夹')
        self.unzipBtn.setMinimumHeight(25)
        self.analyticsBtn.setMinimumHeight(25)
        self.generateDocumentBtn.setMinimumHeight(25)
        self.openDirBtn.setMinimumHeight(25)
        self.downloadLogBtn.connect(self.downloadLogBtn,
                                    QtCore.SIGNAL('clicked()'),
                                    self.downloadLogMethod)
        self.unzipBtn.connect(self.unzipBtn, QtCore.SIGNAL('clicked()'),
                              self.unZipMethod)
        self.analyticsBtn.connect(self.analyticsBtn,
                                  QtCore.SIGNAL('clicked()'),
                                  self.analyticsMethod)
        self.analyticsBtn.connect(self.analyticsBtn,
                                  QtCore.SIGNAL('combineLogSignal(QString)'),
                                  self.combineLogWithAttr)
        self.generateDocumentBtn.connect(self.generateDocumentBtn,
                                         QtCore.SIGNAL('clicked()'),
                                         self.genDocMethod)
        self.openDirBtn.connect(self.openDirBtn, QtCore.SIGNAL('clicked()'),
                                self.openDirMethod)
        self.btnsLayout.addWidget(self.downloadLogBtn)
        self.btnsLayout.addWidget(self.unzipBtn)
        self.btnsLayout.addWidget(self.analyticsBtn)
        self.btnsLayout.addWidget(self.generateDocumentBtn)
        self.btnsLayout.addWidget(self.openDirBtn)
        # show log
        self.LogTextEdit = QtGui.QTextEdit()
        self.LogTextEdit.setSizePolicy(QSizePolicy.Expanding,
                                       QSizePolicy.Expanding)
        self.LogTextEdit.setFont(QtFontUtil().getFont('Monospace', 12))
        self.LogTextEdit.connect(self.LogTextEdit,
                                 QtCore.SIGNAL('appendLogSignal(QString)'),
                                 self.appendLog)
        # addLayout
        self.mainLayout.addLayout(self.selectDirectoryLayout)
        self.mainLayout.addLayout(self.downloadLogLayout)
        self.mainLayout.addLayout(self.keywordLayout)
        self.mainLayout.addLayout(self.btnsLayout)
        self.mainLayout.addWidget(self.LogTextEdit)
        self.centralwidget.setLayout(self.mainLayout)
        # 优化文件数据分析性能,已分组形式进行, 这两个变量记录总共需要分析的分组数量,以及已经分析的组数
        # self.analyticsGroupTotalSize = 0
        # self.processedGroupSize = 0
        # self.processedGroupLock = threading.Lock()
        # 接收 keywordLineEdit 中输入的关键字
        self.analyKeyword = None
        # 接收基础信息 baseAttr 的关键字
        self.baseAttrKeyword = None
        # # 搜索keyword 时,返回包含keyword的行数据
        # self.searchedKeywordLines = ""
        # # 搜索基础信息baseAttr时, 返回包含baseAttr的行数据
        # self.searchedBaseAttrLines = ""
        # 保存分析的日志信息集合
        self.analyticsLogList = []
        # 保存基本信息的集合
        self.baseAttrList = []
        # 多线程中进行集合过滤的锁
        self.filterLogLock = threading.Lock()
        self.filterAttrLock = threading.Lock()
        # 保存最后分析结果 CallFailBean 的集合
        self.callFailList = []
        # 保存从excel 导入的绑定号集合
        self.binderNumberList = []
        # 显示托盘
        self.tray = TrayIcon(parent=self, clickEnable=False)
        self.tray.connect(self.tray,
                          QtCore.SIGNAL('showTrayMsgSignal(QString)'),
                          self.showTrayMsg)

    # 选择文件夹
    def selectDirectoryMethod(self):
        lastDir = self.getLastOpenDir()
        dirPath = unicode(
            QtGui.QFileDialog.getExistingDirectory(None, u'选择文件夹', lastDir))
        if not dirPath or not os.path.exists(dirPath):
            self.appendLog(u'您尚未选择日志文件路径! 请先选择日志路径。')
            return
        logStr = u'日志路径为: ' + str(dirPath)
        self.appendLog(logStr)
        self.selectDirectoryLineEdit.setText(dirPath)

    # 获取QFileDialog 上次打开的路径
    def getLastOpenDir(self):
        lastDir = self.selectDirectoryLineEdit.text()
        if lastDir:
            return str(lastDir)
        # open last remember directory
        lastDir = QSettingsUtil.getLastDir()
        if not QtCore.QDir(lastDir).exists():
            lastDir = 'd://'
        return str(lastDir)

    # download log. load binder number(下载日志时,需要提前导入绑定号)
    # 操作excel 数据 https://www.cnblogs.com/lhj588/archive/2012/01/06/2314181.html
    def dlImportBinderNumberMethod(self):
        filePath = unicode(
            QtGui.QFileDialog.getOpenFileName(None, 'Select file',
                                              self.getLastOpenDir(),
                                              'binder_number(*.xls *.xlsx)'))
        if not filePath:
            return
        # print 'binderNumberFilePath: ', filePath
        binderNumberListStr = ''
        try:
            data = xlrd.open_workbook(unicode(filePath))
            binderNumberTable = data.sheets()[0]
            # print 'table row: ', binderNumberTable.nrows
            # print 'table col: ', binderNumberTable.ncols
            for i in range(binderNumberTable.ncols):
                binderNumberColList = binderNumberTable.col_values(i)
                for binderNumber in binderNumberColList:
                    if binderNumber not in self.binderNumberList:
                        self.binderNumberList.append(binderNumber)
                        binderNumberListStr += (binderNumber + '|')
                # print 'table col: ', binderNumberTable.col_values(i)
                # print 'table row: ', binderNumberTable.row_values(i)
        except Exception as e:
            self.binderNumberList = []
            raise e
        print 'binderNumberList: ', self.binderNumberList
        self.dlBinderNumberLineEdit.setText(binderNumberListStr)

    # 点击下载日志按钮,从服务器[http://172.28.199.58/watch/index_prod.html#/watchda_web/logCollection]下载日志
    def downloadLogMethod(self):
        selectDir = str(self.selectDirectoryLineEdit.text())
        if not selectDir:
            self.appendLog(u'您尚未选择日志文件路径! 请先选择日志路径。')
            return
        importedBinderNumbers = str(self.dlBinderNumberLineEdit.text())
        if not importedBinderNumbers:
            self.appendLog(u'请导入需要下载日志的绑定号!')
            return
        # self.doDownloadLog(log_call_back=self.emitAppendLogSignal)
        threadUtil = ThreadUtil(funcName=self.doDownloadLog,
                                log_call_back=self.emitAppendLogSignal)
        threadUtil.setDaemon(True)
        threadUtil.start()

    # 开始下载日志
    def doDownloadLog(self, log_call_back):
        dlLogByWeb = DownloadLogByWeb()
        dlLogByWeb.setCallBack(log_call_back)
        dlLogByWeb.login()
        dlLogByWeb.setBinderNumberList(self.binderNumberList)
        dlLogByWeb.downloadLog()

    # 点击解压日志按钮
    def unZipMethod(self):
        # self.doUnzipFile(log_call_back=self.emitAppendLogSignal)
        threadUtil = ThreadUtil(funcName=self.doUnzipFile,
                                log_call_back=self.emitAppendLogSignal)
        threadUtil.setDaemon(True)
        threadUtil.start()

    # 解压文件
    def doUnzipFile(self, log_call_back):
        selectDir = str(self.selectDirectoryLineEdit.text())
        if not selectDir:
            log_call_back(u'您尚未选择日志文件路径! 请先选择日志路径。')
            return
        zipFileUtil = ZipFileUtil(log_call_back)
        zipFileUtil.recursiveUnZipFile(selectDir)
        log_call_back(u'解压完成')

    # 点击分析日志按钮
    def analyticsMethod(self):
        self.analyticsBtn.setDisabled(True)
        self.generateDocumentBtn.setDisabled(True)
        self.doAnalyticsWithGroup()

    """
    开始分析, 分析步骤:
    # 1. 先将文件进行分组;利用线程分组策略,每一线程处理多个文件 (!!多进程操作文件的情况下,已去除!!)
    2. 先分析给定的关键字,在单个数据文件中进行搜索;利用多进程读取策略读取单个文件(提升速度)
    3. 再搜索基础信息,同样在分组数据中进行搜索;(基本信息BaseAttrBean: binderNumber, machineMode, osVersion 等)
    4. 组合数据,则将 AnalyticsLogBean 内容与 baseAttr 基本信息进行整合,保存进 CallFailBeanList 中。便于后面生成文档。
    """

    def doAnalyticsWithGroup(self):
        selectDir = str(self.selectDirectoryLineEdit.text())
        if not selectDir:
            logMsg = u'您尚未选择日志文件路径! 请先选择日志路径。'
            self.appendLog(logMsg)
            self.analyticsBtn.setEnabled(True)
            self.generateDocumentBtn.setEnabled(True)
            return
        allFilePaths = FileUtil.getAllFiles(selectDir)
        print 'len(allFilePaths): ', len(allFilePaths)
        supportFilePaths = []
        for filePath in allFilePaths:
            if SupportFiles.hasSupportFile(filePath) and \
                    not SupportFiles.hasContainsPath(filePath, *self.removeThePathKeys()):
                supportFilePaths.append(filePath)
        if not supportFilePaths:
            return
        # self.analyticsGroupTotalSize = len([supportFilePaths[i:i+10] for i in xrange(0, len(supportFilePaths), 10)])
        print 'len(supportFilePaths): ', len(supportFilePaths)
        # print 'len(analyticsGroupTotalSize): ', self.analyticsGroupTotalSize
        # 1. 数组分组,以10个一组
        # for i in xrange(0, len(supportFilePaths), 10):
        #     filePathList = supportFilePaths[i:i+10]
        #     # print 'filePathList: ', filePathList
        #     # 2,3 进行分组数据搜索
        #     # 无线程版
        #     # self.doSearchFile(filePathList)
        #     threadUtil = ThreadUtil(funcName=self.doSearchFile, filePaths=filePathList)
        #     threadUtil.setDaemon(True)
        #     threadUtil.start()
        # self.doSearchFile(supportFilePaths)
        # 去除多线程分组,默认采用多进程分析文件,避免同时使用多线程的情况下使用多进程,否则电脑会被冲爆
        threadUtil = ThreadUtil(funcName=self.doSearchFile,
                                filePaths=supportFilePaths)
        threadUtil.setDaemon(True)
        threadUtil.start()

    # 2,3 进行分组数据搜索
    def doSearchFile(self, filePaths):
        if not filePaths:
            return
        # 进行搜索前,确认本次搜索关键字
        self.analyKeyword = str(self.keywordLineEdit.text()) if str(
            self.keywordLineEdit.text()).strip() else str("reportCallFailLD =")
        self.baseAttrKeyword = str("base attribute info")
        # 搜索关键字信息
        for filePath in filePaths:
            # print "filePath---> : %s --> currentThread: %s" % (_translateUtf8(filePath), threading.currentThread().getName())
            self.searchkeywordByMultiProcess(filePath)
        # 再搜索基本信息
        for filePath in filePaths:
            self.searchBaseAttrByMultiProcess(filePath)
        # 4. 组合数据,去主线程组装数据
        self.emitCombineLogSignal(threading.currentThread().getName())

    def combineLogSignal(self, thread_name):
        pass

    def emitCombineLogSignal(self, thread_name):
        self.analyticsBtn.emit(QtCore.SIGNAL('combineLogSignal(QString)'),
                               thread_name)

    # 4. 组合数据,主线程组装数据(提高优先级)
    def combineLogWithAttr(self, thread_name):
        print u'----线程%s已完成工作, 正在使用线程%s开始组装数据-----' % (
            thread_name, threading.currentThread().getName())
        # self.processedGroupSize += 1
        # logMsg = u'一共需要分析:' + str(self.analyticsGroupTotalSize) + u'组,已经分析:' + str(self.processedGroupSize) \
        #          + u'组,剩余:' + str(self.analyticsGroupTotalSize - self.processedGroupSize) + u'组。'
        logMsg = u'已分析完文件,正在开始组装数据'
        self.appendLog(logMsg)
        print logMsg
        # if self.analyticsGroupTotalSize == self.processedGroupSize:
        for analyLog in self.analyticsLogList:
            analyLogTxt = analyLog.logTxt
            analyLogFilePath = analyLog.filePath
            analyLogStr = re.search(r'ReportCallFailLD\s(\{.+})',
                                    analyLogTxt).group(1)
            analyLogJson = self.convertStr2JsonStr(analyLogStr)
            if not analyLogJson:
                continue
            for baseAttr in self.baseAttrList:
                binderNumber = baseAttr.binderNumber
                # 组合同一个绑定号数据
                if analyLogStr.find(
                        binderNumber) != -1 or analyLogFilePath.find(
                            binderNumber) != -1:
                    callFail = CallFailBean()
                    callFail.binderNumber = binderNumber
                    callFail.machineMode = baseAttr.machineMode
                    callFail.osVersion = baseAttr.osVersion
                    callFail.failTime = analyLog.logTime
                    callFail.voiceNetworkType = analyLogJson[
                        'voiceNetWorkTypeLD']
                    callFail.dialMode = analyLogJson['selfDialModeLD']
                    callFail.causeCode = analyLogJson['callFailCauseCodeLD']
                    callFail.vendorCauseCode = analyLogJson[
                        'callFailVendorCauseLD']
                    callFail.logText = analyLogTxt
                    callFail.logFilePath = analyLogFilePath
                    print '----> callFail (bindNumber: %s,  machineMode: %s, osVersion: %s, failTime: %s, ' \
                          'voiceNetworkType: %s, dailMode: %s, causeCode: %s, vendorCause: %s, logText: %s,' \
                          ' logFilePath: %s) ' \
                          % (callFail.binderNumber, callFail.machineMode, callFail.osVersion, callFail.failTime,
                             callFail.voiceNetworkType, callFail.dialMode, callFail.causeCode,
                             callFail.vendorCauseCode, callFail.logText, callFail.logFilePath)
                    self.callFailList.append(callFail)
        self.analyticsBtn.setEnabled(True)
        self.generateDocumentBtn.setEnabled(True)
        logMsg = u'---------- 日志分析完毕 -----------'
        self.appendLog(logMsg)
        self.emitTrayMsgSignal(u'日志分析完毕')
        print '------------- over ---------------'
        # end if self.analyticsGroupTotalSize == self.processedGroupSize: (此处只做一个end if 语句记号)

    # 多进程操作文件,搜索输入关键字
    def searchkeywordByMultiProcess(self, file_path):
        searchKeywordMultiProcess = SearchKeywordByMultiProcess(
            file_path, self, self.searchKeywordCallBack, self.analyKeyword)
        searchKeywordMultiProcess.createAndDoJobs()

    # 多进程操作文件,用于状态回调
    @staticmethod
    def searchKeywordCallBack(self, status, file_path, searchedLogJobs):
        # print '-0---searchKeywordCallBack keyword:%s == lines: %s, status: %s' % (self.analyKeyword, searchedLogList, status)
        if not self.analyKeyword:
            return
        if status == SearchByMultiProcess.STATUS_PROCESSING:
            logMsg = u'正在分析文件:' + _translateUtf8(file_path)
            self.dologCallBack(self.emitAppendLogSignal, logMsg)
            return
        if not searchedLogJobs:
            return
        for searchedLogJob in searchedLogJobs:
            if not searchedLogJob:
                continue
            for searchedLog in searchedLogJob:
                if not searchedLog:
                    continue
                self.filterAnalyLog2List(self.analyticsLogList, searchedLog)

    # 多进程操作文件,搜索基础信息
    def searchBaseAttrByMultiProcess(self, file_path):
        searchBaseAttrMultiProcess = SearchBaseAttrByMultiProcess(
            file_path, self, self.searchBaseAttrCallBack, self.baseAttrKeyword)
        searchBaseAttrMultiProcess.createAndDoJobs()

    # 多进程操作文件,用于状态回调
    @staticmethod
    def searchBaseAttrCallBack(self, status, file_path, searchedBaseAttrJobs):
        if not self.baseAttrKeyword:
            return
        if status == SearchByMultiProcess.STATUS_PROCESSING:
            return
        if not searchedBaseAttrJobs:
            return
        for searchedBaseAttrJob in searchedBaseAttrJobs:
            if not searchedBaseAttrJob:
                continue
            for searchedBaseAttr in searchedBaseAttrJob:
                if not searchedBaseAttr:
                    continue
                self.filterBaseAttr2List(self.baseAttrList, searchedBaseAttr)

    # 在文件中,搜索关键字,并返回该关键字所在的行数据
    def searchWordInFile(self, keyword, file_path, log_call_back=None):
        if not file_path or not keyword.strip():
            return
        filePath = _translate('', file_path, None)
        file = QFile(filePath)
        if not file.open(QtCore.QIODevice.ReadOnly):
            logMsg = u'无法打开文件:' + _translateUtf8(file_path)
            self.dologCallBack(log_call_back, logMsg)
            file.close()
            return
        logMsg = u'正在分析文件:' + _translateUtf8(file_path)
        self.dologCallBack(log_call_back, logMsg)
        # stream = QtCore.QTextStream(file)
        # stream.setCodec('UTF-8')
        # data = stream.readAll()
        # file.close()
        # stream.flush()
        # dataTmp = StringIO.StringIO(data)
        searchedText = ''
        # while True:
        with open(filePath) as f:
            print 'len(file): ', len(f.readlines())
            for line in f:
                textLine = str(_translateUtf8(line))
                if textLine == '':
                    # logMsg = u'已分析完文件:' + _translateUtf8(file_path)
                    # log_call_back(logMsg)
                    # print logMsg
                    break
                textLineLower = textLine.lower()
                keywordIndex = textLineLower.find(keyword.lower())
                if keywordIndex != -1:
                    searchedText += textLine
        # release StringIO memory
        # dataTmp.close()
        return searchedText

    # 处理 log_call_back 函数,去除None空回调和返回信息的问题
    def dologCallBack(self, log_call_back=None, msg=None):
        if not log_call_back or not msg:
            return
        log_call_back(msg)

    # 将字符串转换为json 格式
    # http://www.runoob.com/python/python-reg-expressions.html
    def convertStr2JsonStr(self, string):
        if not string:
            return None
        string = string.replace("\'", "\"")
        strList = re.findall(r'([A-Za-z0-9]+=)', string)
        for strTmp in strList:
            strTmp = strTmp.replace("=", "")
            string = string.replace(strTmp, "\"" + strTmp + "\"")
        string = string.replace("=", ":")
        # print '---> string: ', string
        # print '---> strList: ', strList
        jsonStr = None
        try:
            jsonStr = json.loads(string)
        except Exception as e:
            pass
        # print "json >>> ", jsonStr
        return jsonStr

    # 过滤日志信息, 去重后添加进集合
    def filterAnalyLog2List(self, analyticsLogList, analyLogBean):
        with self.filterLogLock:
            if not analyLogBean:
                return
            if len(analyticsLogList) == 0:
                analyticsLogList.append(analyLogBean)
                return
            if not self.hasListContainLog(analyticsLogList, analyLogBean):
                # print '>>>> append analyticsLogList: %s ---> analyLogBean:%s' % (analyticsLogList, analyLogBean)
                analyticsLogList.append(analyLogBean)

    # 集合中是否已经包含了重复LOG
    def hasListContainLog(self, analyticsLogList, analyLogBean):
        for analyLog in analyticsLogList:
            if analyLog.logTxt == analyLogBean.logTxt:
                return True
            elif analyLogBean in analyticsLogList:
                return True
        return False

    # 过滤 baseAttr 信息, 去重后添加进集合
    def filterBaseAttr2List(self, baseAttrList, baseAttr):
        with self.filterAttrLock:
            if not baseAttr:
                return
            if len(baseAttrList) == 0:
                baseAttrList.append(baseAttr)
                return
            if not self.hasListContainAttr(baseAttrList, baseAttr):
                # print '>>>> append baseAttrList: %s ---> baseAttr:%s' % (baseAttrList, baseAttr)
                baseAttrList.append(baseAttr)

    # 集合中是否已经包含了重复attr属性
    def hasListContainAttr(self, baseAttrList, baseAttr):
        for baseAttrTmp in baseAttrList:
            if baseAttrTmp.binderNumber == baseAttr.binderNumber:
                return True
            elif baseAttr in baseAttrList:
                return True
        return False

    # 找出有效的基础信息,进行json 转换
    def filterBaseAttr2Json(self, searchedBaseAttr):
        if not searchedBaseAttr:
            return None
        baseAttrJson = None
        baseAttrList = re.findall(r'BaseAttr(\{.+})', searchedBaseAttr)
        # print '---> baseAttrList: ', baseAttrList
        if baseAttrList:
            for baseAttrStr in baseAttrList:
                baseAttrJson = self.convertStr2JsonStr(baseAttrStr)
                # print '==> baseAttrJson: ', baseAttrJson
                if baseAttrJson:
                    return baseAttrJson
        return baseAttrJson

    # 点击生成文档按钮
    def genDocMethod(self):
        selectDir = self.selectDirectoryLineEdit.text()
        if not selectDir:
            logMsg = u'您尚未选择日志文件路径! 请先选择日志路径。'
            self.appendLog(logMsg)
            return
        if not self.callFailList:
            logMsg = u'请先分析LOG, 再生成文档!'
            self.appendLog(logMsg)
            return
        # self.doGenDocFile(self.emitAppendLogSignal)
        threadUtil = ThreadUtil(funcName=self.doGenDocFile,
                                log_call_back=self.emitAppendLogSignal)
        threadUtil.setDaemon(True)
        threadUtil.start()

    def doGenDocFile(self, log_call_back):
        docTitle = u'# 问题分析'
        docSecondTitle = u'## 上层分析'
        docTempleteBinder = u'绑定号: '
        docTempleteMachine = u'+ 机型 : '
        docTempleteTime = u'+ 时间点: '
        docTempleteNetworkType = u'+ 通话类型:'
        docTempleteDialMode = u'+ 通话方向:'
        docTempleteCause = u'+ 掉话code: '
        docTempleteDetail = u'+ 详情:'
        print 'callFailList len: ', len(self.callFailList)
        for callFail in self.callFailList:
            docFilePath = callFail.logFilePath
            binderNumber = callFail.binderNumber
            docFilePathTmp = re.findall(r'([A-Za-z0-9_.]+)', docFilePath)
            docFilePath.rfind(binderNumber)
            fileDirPath = ''
            for fileDirPathTmp in docFilePathTmp:
                if fileDirPathTmp == binderNumber:
                    fileDirPathIndex = docFilePath.find(binderNumber)
                    fileDirPath = docFilePath[:fileDirPathIndex +
                                              len(binderNumber) + 1]
                    break
                elif fileDirPathTmp.find(binderNumber) != -1:
                    fileDirPathIndex = docFilePath.find(binderNumber)
                    fileDirPath = docFilePath[:fileDirPathIndex]
                else:
                    fileDirPath = os.path.join(
                        str(self.selectDirectoryLineEdit.text()), binderNumber)
            FileUtil.mkdirNotExist(fileDirPath)
            print 'docFilePath: ', fileDirPath
            fileName = binderNumber + u'_问题分析.txt'
            filePath = os.path.join(fileDirPath, fileName)
            hasFileExists = os.path.exists(filePath)
            docFile = open(filePath, 'a+')
            docContentBinderNumber = str(docTempleteBinder +
                                         binderNumber).encode('utf-8')
            docContentMachine = str(docTempleteMachine + callFail.machineMode +
                                    "\t" + callFail.osVersion).encode('utf-8')
            docContentTime = str(docTempleteTime +
                                 callFail.failTime).encode('utf-8')
            docContentNetworkType = str(docTempleteNetworkType +
                                        callFail.voiceNetworkType).encode(
                                            'utf-8')
            docContentDialMode = str(docTempleteDialMode +
                                     callFail.dialMode).encode('utf-8')
            docContentCause = str(docTempleteCause +
                                  callFail.vendorCauseCode).encode('utf-8')
            docContentDetail = str(docTempleteDetail +
                                   callFail.logText).encode('utf-8')
            if not hasFileExists:
                docFile.write('\n' + docTitle + '\n')
                docFile.write('\n' + docContentBinderNumber + '\n')
                docFile.write('\n' + docSecondTitle + '\n')
                docFile.write('\n' + docContentMachine + '\n')
            else:
                docFile.write('\n\n\n')
            docFile.write(docContentTime + '\n')
            docFile.write(docContentNetworkType + '\n')
            docFile.write(docContentDialMode + '\n')
            docFile.write(docContentCause + '\n')
            docFile.write(docContentDetail + '\n')
            docFile.flush()
            docFile.close()
            logMsg = u'已生成文档:' + _translateUtf8(filePath)
            log_call_back(logMsg)
            print logMsg
        self.release()
        logMsg = u'---------- 文档生成完毕 -----------'
        log_call_back(logMsg)
        self.emitTrayMsgSignal(u'文档生成完毕')

    # 打开文件夹
    def openDirMethod(self):
        selectDir = self.selectDirectoryLineEdit.text()
        if not selectDir:
            logMsg = u'您尚未选择日志文件路径! 请先选择日志路径。'
            self.appendLog(logMsg)
            return
        os.startfile(unicode(selectDir))

    # 需要去除包含以下关键字的路径
    def removeThePathKeys(self):
        return ["traces", "bugreport", "diag_logs"]

    # release
    def release(self):
        # 清空本次数据
        self.analyKeyword = None
        self.baseAttrKeyword = None
        self.analyticsLogList = []
        self.baseAttrList = []
        self.callFailList = []
        # self.analyticsGroupTotalSize = 0
        # self.processedGroupSize = 0

    # 显示操作日志
    def appendLog(self, logTxt):
        self.LogTextEdit.append(_translateUtf8(logTxt))

    # 解决在子线程中刷新UI 的问题。' QWidget::repaint: Recursive repaint detected '
    def appendLogSignal(self, logTxt):
        pass

    def emitAppendLogSignal(self, logTxt):
        self.LogTextEdit.emit(QtCore.SIGNAL('appendLogSignal(QString)'),
                              logTxt)

    # 托盘消息
    def showTrayMsg(self, trayMsg):
        self.tray.show()
        # show 5 min
        self.tray.showMsg(trayMsg)

    def showTrayMsgSignal(self, trayMsg):
        pass

    def emitTrayMsgSignal(self, trayMsg):
        self.tray.emit(QtCore.SIGNAL('showTrayMsgSignal(QString)'), trayMsg)

    def keyPressEvent(self, event):
        # 设置 "Ctrl+w" 快捷键,用于关闭 tab
        if event.key() == QtCore.Qt.Key_W and event.modifiers(
        ) == QtCore.Qt.ControlModifier:
            self.close()
예제 #7
0
    def mouseReleaseEvent(self, QMouseEvent):
        self.moveFlag = False
        self.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))


if __name__ == '__main__':
    os_system = platform.system()
    # myself_anime_connect = False
    if os_system == "Darwin":
        # MAC 要改 工作路徑,此路徑為 Applications 絕對路徑。
        os.chdir('/Applications/MyselfAnime.app/Contents/Macos')
    app = QtWidgets.QApplication(sys.argv)
    if not connect_myself_anime():
        msg = QtWidgets.QMessageBox()
        msg.setIcon(QtWidgets.QMessageBox.Critical)
        msg.setText("請確認可以進入 <a href=https://myself-bbs.com/portal.php>MyselfAnime</a> 網站")
        msg.setWindowTitle("無法取得 MyselfAnime 網站資料!")
        msg.setWindowIcon(QtGui.QIcon('./image/logo.ico'))
        msg.exec_()
    else:
        # myStyle = MyProxyStyle()
        # app.setStyle(myStyle)
        anime = Anime(pid=os.getpid(), os_system=os_system)
        # config = Config(anime=anime)
        about = About()
        # anime.menu.actions()[0].triggered.connect(config.show)
        anime.show()
        tray_icon = TrayIcon(anime)
        app.exec_()
        kill_pid(os.getpid())
예제 #8
0
 def __init__(self, parent=None):
     QtGui.QMainWindow.__init__(self, parent)
     self.setWindowTitle(u'拆分Excel数据')
     self.setWindowIcon(QtGui.QIcon(resource_path('img/log.png')))
     self.centralwidget = QWidget()
     self.setCentralWidget(self.centralwidget)
     self.resize(650, 500)
     self.mainLayout = QtGui.QVBoxLayout()
     self.mainLayout.setAlignment(QtCore.Qt.AlignTop)
     self.mainLayout.setContentsMargins(5, 10, 5, 2)
     # 选取excel文件
     self.excelFileLayout = QtGui.QHBoxLayout()
     self.selectExcelFileBtn = QtGui.QPushButton(u'选择Excel文件')
     self.selectExcelFileBtn.connect(self.selectExcelFileBtn,
                                     QtCore.SIGNAL('clicked()'),
                                     self.selectExcelFileMethod)
     self.selectExcelFileLineEdit = QtGui.QLineEdit()
     self.selectExcelFileLineEdit.setTextMargins(10, 0, 10, 0)
     self.selectExcelFileLineEdit.setMinimumHeight(25)
     self.selectExcelFileLineEdit.setFont(QtFontUtil().getFont(
         'Monospace', 12))
     self.excelFileLayout.addWidget(self.selectExcelFileBtn)
     self.excelFileLayout.addWidget(self.selectExcelFileLineEdit)
     # excel 行限制条件 directory
     self.LineConditionLayout = QtGui.QHBoxLayout()
     self.LineConditionStartLineEdit = QtGui.QLineEdit()
     self.LineConditionStartLineEdit.setTextMargins(10, 0, 10, 0)
     self.LineConditionStartLineEdit.setMinimumHeight(25)
     self.LineConditionStartLineEdit.setPlaceholderText(u'开始行号')
     self.LineConditionStartLineEdit.setFont(QtFontUtil().getFont(
         'Monospace', 12))
     self.LineConditionEndLineEdit = QtGui.QLineEdit()
     self.LineConditionEndLineEdit.setTextMargins(10, 0, 10, 0)
     self.LineConditionEndLineEdit.setMinimumHeight(25)
     self.LineConditionEndLineEdit.setPlaceholderText(u'结束行号')
     self.LineConditionEndLineEdit.setFont(QtFontUtil().getFont(
         'Monospace', 12))
     self.LineConditionIntervalTitle = QtGui.QLabel()
     self.LineConditionIntervalTitle.setText(u'行拆分间隔条数:')
     self.LineConditionIntervalTitle.setFont(QtFontUtil().getFont(
         '微软雅黑', 14))
     self.LineConditionIntervalEdit = QtGui.QLineEdit()
     self.LineConditionIntervalEdit.setTextMargins(10, 0, 10, 0)
     self.LineConditionIntervalEdit.setMinimumHeight(25)
     self.LineConditionIntervalEdit.setPlaceholderText('0')
     self.LineConditionIntervalEdit.setFont(QtFontUtil().getFont(
         'Monospace', 12))
     self.LineConditionTitle = QtGui.QLabel()
     self.LineConditionTitle.setText(u' 行数据: ')
     self.LineConditionTitle.setFont(QtFontUtil().getFont('微软雅黑', 14))
     self.LineConditionLabel = QtGui.QLabel()
     self.LineConditionLabel.setText(u'-->')
     self.LineConditionLabel.setFont(QtFontUtil().getFont('Monospace', 12))
     self.LineConditionLayout.addWidget(self.LineConditionTitle)
     self.LineConditionLayout.addWidget(self.LineConditionStartLineEdit)
     self.LineConditionLayout.addWidget(self.LineConditionLabel)
     self.LineConditionLayout.addWidget(self.LineConditionEndLineEdit)
     self.LineConditionLayout.addStretch()
     self.LineConditionLayout.addWidget(self.LineConditionIntervalTitle)
     self.LineConditionLayout.addWidget(self.LineConditionIntervalEdit)
     # excel 列限制条件 directory
     self.ColumnConditionLayout = QtGui.QHBoxLayout()
     self.ColumnConditionStartLineEdit = QtGui.QLineEdit()
     self.ColumnConditionStartLineEdit.setTextMargins(10, 0, 10, 0)
     self.ColumnConditionStartLineEdit.setMinimumHeight(25)
     self.ColumnConditionStartLineEdit.setPlaceholderText(u'开始列号')
     self.ColumnConditionStartLineEdit.setFont(QtFontUtil().getFont(
         'Monospace', 12))
     self.ColumnConditionEndLineEdit = QtGui.QLineEdit()
     self.ColumnConditionEndLineEdit.setTextMargins(10, 0, 10, 0)
     self.ColumnConditionEndLineEdit.setMinimumHeight(25)
     self.ColumnConditionEndLineEdit.setPlaceholderText(u'结束列号')
     self.ColumnConditionEndLineEdit.setFont(QtFontUtil().getFont(
         'Monospace', 12))
     self.ColumnConditionIntervalTitle = QtGui.QLabel()
     self.ColumnConditionIntervalTitle.setText(u'列拆分间隔条数:')
     self.ColumnConditionIntervalTitle.setFont(QtFontUtil().getFont(
         '微软雅黑', 14))
     self.ColumnConditionIntervalEdit = QtGui.QLineEdit()
     self.ColumnConditionIntervalEdit.setTextMargins(10, 0, 10, 0)
     self.ColumnConditionIntervalEdit.setMinimumHeight(25)
     self.ColumnConditionIntervalEdit.setPlaceholderText('0')
     self.ColumnConditionIntervalEdit.setFont(QtFontUtil().getFont(
         'Monospace', 12))
     self.ColumnConditionTitle = QtGui.QLabel()
     self.ColumnConditionTitle.setText(u' 列数据: ')
     self.ColumnConditionTitle.setFont(QtFontUtil().getFont('微软雅黑', 14))
     self.ColumnConditionLabel = QtGui.QLabel()
     self.ColumnConditionLabel.setText(u'-->')
     self.ColumnConditionLabel.setFont(QtFontUtil().getFont(
         'Monospace', 12))
     self.ColumnConditionLayout.addWidget(self.ColumnConditionTitle)
     self.ColumnConditionLayout.addWidget(self.ColumnConditionStartLineEdit)
     self.ColumnConditionLayout.addWidget(self.ColumnConditionLabel)
     self.ColumnConditionLayout.addWidget(self.ColumnConditionEndLineEdit)
     self.ColumnConditionLayout.addStretch()
     self.ColumnConditionLayout.addWidget(self.ColumnConditionIntervalTitle)
     self.ColumnConditionLayout.addWidget(self.ColumnConditionIntervalEdit)
     # operate buttons
     self.btnsLayout = QtGui.QHBoxLayout()
     self.splitExcelBtn = QtGui.QPushButton(u'开始拆分')
     self.splitExcelBtn.setMinimumHeight(25)
     self.splitExcelBtn.connect(self.splitExcelBtn,
                                QtCore.SIGNAL('clicked()'),
                                self.splitExcelDataMethod)
     self.openDirBtn = QtGui.QPushButton(u'打开文件夹')
     self.openDirBtn.setMinimumHeight(25)
     self.openDirBtn.connect(self.openDirBtn, QtCore.SIGNAL('clicked()'),
                             self.openDirMethod)
     self.btnsLayout.addWidget(self.splitExcelBtn)
     self.btnsLayout.addWidget(self.openDirBtn)
     # show log
     self.LogTextEdit = QtGui.QTextEdit()
     self.LogTextEdit.setSizePolicy(QSizePolicy.Expanding,
                                    QSizePolicy.Expanding)
     self.LogTextEdit.setFont(QtFontUtil().getFont('Monospace', 12))
     self.LogTextEdit.connect(self.LogTextEdit,
                              QtCore.SIGNAL('appendLogSignal(QString)'),
                              self.appendLog)
     # addLayout
     self.mainLayout.addLayout(self.excelFileLayout)
     self.mainLayout.addSpacing(10)
     self.mainLayout.addLayout(self.LineConditionLayout)
     self.mainLayout.addLayout(self.ColumnConditionLayout)
     self.mainLayout.addSpacing(10)
     self.mainLayout.addLayout(self.btnsLayout)
     self.centralwidget.setLayout(self.mainLayout)
     self.mainLayout.addWidget(self.LogTextEdit)
     # excelFileDataList 为新生成的每一个新excel 数据集合的集合
     self.excelFileDataList = []
     # 显示托盘
     self.tray = TrayIcon(parent=self, clickEnable=False)
     self.tray.connect(self.tray,
                       QtCore.SIGNAL('showTrayMsgSignal(QString)'),
                       self.showTrayMsg)
예제 #9
0
class SplitExcelWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QMainWindow.__init__(self, parent)
        self.setWindowTitle(u'拆分Excel数据')
        self.setWindowIcon(QtGui.QIcon(resource_path('img/log.png')))
        self.centralwidget = QWidget()
        self.setCentralWidget(self.centralwidget)
        self.resize(650, 500)
        self.mainLayout = QtGui.QVBoxLayout()
        self.mainLayout.setAlignment(QtCore.Qt.AlignTop)
        self.mainLayout.setContentsMargins(5, 10, 5, 2)
        # 选取excel文件
        self.excelFileLayout = QtGui.QHBoxLayout()
        self.selectExcelFileBtn = QtGui.QPushButton(u'选择Excel文件')
        self.selectExcelFileBtn.connect(self.selectExcelFileBtn,
                                        QtCore.SIGNAL('clicked()'),
                                        self.selectExcelFileMethod)
        self.selectExcelFileLineEdit = QtGui.QLineEdit()
        self.selectExcelFileLineEdit.setTextMargins(10, 0, 10, 0)
        self.selectExcelFileLineEdit.setMinimumHeight(25)
        self.selectExcelFileLineEdit.setFont(QtFontUtil().getFont(
            'Monospace', 12))
        self.excelFileLayout.addWidget(self.selectExcelFileBtn)
        self.excelFileLayout.addWidget(self.selectExcelFileLineEdit)
        # excel 行限制条件 directory
        self.LineConditionLayout = QtGui.QHBoxLayout()
        self.LineConditionStartLineEdit = QtGui.QLineEdit()
        self.LineConditionStartLineEdit.setTextMargins(10, 0, 10, 0)
        self.LineConditionStartLineEdit.setMinimumHeight(25)
        self.LineConditionStartLineEdit.setPlaceholderText(u'开始行号')
        self.LineConditionStartLineEdit.setFont(QtFontUtil().getFont(
            'Monospace', 12))
        self.LineConditionEndLineEdit = QtGui.QLineEdit()
        self.LineConditionEndLineEdit.setTextMargins(10, 0, 10, 0)
        self.LineConditionEndLineEdit.setMinimumHeight(25)
        self.LineConditionEndLineEdit.setPlaceholderText(u'结束行号')
        self.LineConditionEndLineEdit.setFont(QtFontUtil().getFont(
            'Monospace', 12))
        self.LineConditionIntervalTitle = QtGui.QLabel()
        self.LineConditionIntervalTitle.setText(u'行拆分间隔条数:')
        self.LineConditionIntervalTitle.setFont(QtFontUtil().getFont(
            '微软雅黑', 14))
        self.LineConditionIntervalEdit = QtGui.QLineEdit()
        self.LineConditionIntervalEdit.setTextMargins(10, 0, 10, 0)
        self.LineConditionIntervalEdit.setMinimumHeight(25)
        self.LineConditionIntervalEdit.setPlaceholderText('0')
        self.LineConditionIntervalEdit.setFont(QtFontUtil().getFont(
            'Monospace', 12))
        self.LineConditionTitle = QtGui.QLabel()
        self.LineConditionTitle.setText(u' 行数据: ')
        self.LineConditionTitle.setFont(QtFontUtil().getFont('微软雅黑', 14))
        self.LineConditionLabel = QtGui.QLabel()
        self.LineConditionLabel.setText(u'-->')
        self.LineConditionLabel.setFont(QtFontUtil().getFont('Monospace', 12))
        self.LineConditionLayout.addWidget(self.LineConditionTitle)
        self.LineConditionLayout.addWidget(self.LineConditionStartLineEdit)
        self.LineConditionLayout.addWidget(self.LineConditionLabel)
        self.LineConditionLayout.addWidget(self.LineConditionEndLineEdit)
        self.LineConditionLayout.addStretch()
        self.LineConditionLayout.addWidget(self.LineConditionIntervalTitle)
        self.LineConditionLayout.addWidget(self.LineConditionIntervalEdit)
        # excel 列限制条件 directory
        self.ColumnConditionLayout = QtGui.QHBoxLayout()
        self.ColumnConditionStartLineEdit = QtGui.QLineEdit()
        self.ColumnConditionStartLineEdit.setTextMargins(10, 0, 10, 0)
        self.ColumnConditionStartLineEdit.setMinimumHeight(25)
        self.ColumnConditionStartLineEdit.setPlaceholderText(u'开始列号')
        self.ColumnConditionStartLineEdit.setFont(QtFontUtil().getFont(
            'Monospace', 12))
        self.ColumnConditionEndLineEdit = QtGui.QLineEdit()
        self.ColumnConditionEndLineEdit.setTextMargins(10, 0, 10, 0)
        self.ColumnConditionEndLineEdit.setMinimumHeight(25)
        self.ColumnConditionEndLineEdit.setPlaceholderText(u'结束列号')
        self.ColumnConditionEndLineEdit.setFont(QtFontUtil().getFont(
            'Monospace', 12))
        self.ColumnConditionIntervalTitle = QtGui.QLabel()
        self.ColumnConditionIntervalTitle.setText(u'列拆分间隔条数:')
        self.ColumnConditionIntervalTitle.setFont(QtFontUtil().getFont(
            '微软雅黑', 14))
        self.ColumnConditionIntervalEdit = QtGui.QLineEdit()
        self.ColumnConditionIntervalEdit.setTextMargins(10, 0, 10, 0)
        self.ColumnConditionIntervalEdit.setMinimumHeight(25)
        self.ColumnConditionIntervalEdit.setPlaceholderText('0')
        self.ColumnConditionIntervalEdit.setFont(QtFontUtil().getFont(
            'Monospace', 12))
        self.ColumnConditionTitle = QtGui.QLabel()
        self.ColumnConditionTitle.setText(u' 列数据: ')
        self.ColumnConditionTitle.setFont(QtFontUtil().getFont('微软雅黑', 14))
        self.ColumnConditionLabel = QtGui.QLabel()
        self.ColumnConditionLabel.setText(u'-->')
        self.ColumnConditionLabel.setFont(QtFontUtil().getFont(
            'Monospace', 12))
        self.ColumnConditionLayout.addWidget(self.ColumnConditionTitle)
        self.ColumnConditionLayout.addWidget(self.ColumnConditionStartLineEdit)
        self.ColumnConditionLayout.addWidget(self.ColumnConditionLabel)
        self.ColumnConditionLayout.addWidget(self.ColumnConditionEndLineEdit)
        self.ColumnConditionLayout.addStretch()
        self.ColumnConditionLayout.addWidget(self.ColumnConditionIntervalTitle)
        self.ColumnConditionLayout.addWidget(self.ColumnConditionIntervalEdit)
        # operate buttons
        self.btnsLayout = QtGui.QHBoxLayout()
        self.splitExcelBtn = QtGui.QPushButton(u'开始拆分')
        self.splitExcelBtn.setMinimumHeight(25)
        self.splitExcelBtn.connect(self.splitExcelBtn,
                                   QtCore.SIGNAL('clicked()'),
                                   self.splitExcelDataMethod)
        self.openDirBtn = QtGui.QPushButton(u'打开文件夹')
        self.openDirBtn.setMinimumHeight(25)
        self.openDirBtn.connect(self.openDirBtn, QtCore.SIGNAL('clicked()'),
                                self.openDirMethod)
        self.btnsLayout.addWidget(self.splitExcelBtn)
        self.btnsLayout.addWidget(self.openDirBtn)
        # show log
        self.LogTextEdit = QtGui.QTextEdit()
        self.LogTextEdit.setSizePolicy(QSizePolicy.Expanding,
                                       QSizePolicy.Expanding)
        self.LogTextEdit.setFont(QtFontUtil().getFont('Monospace', 12))
        self.LogTextEdit.connect(self.LogTextEdit,
                                 QtCore.SIGNAL('appendLogSignal(QString)'),
                                 self.appendLog)
        # addLayout
        self.mainLayout.addLayout(self.excelFileLayout)
        self.mainLayout.addSpacing(10)
        self.mainLayout.addLayout(self.LineConditionLayout)
        self.mainLayout.addLayout(self.ColumnConditionLayout)
        self.mainLayout.addSpacing(10)
        self.mainLayout.addLayout(self.btnsLayout)
        self.centralwidget.setLayout(self.mainLayout)
        self.mainLayout.addWidget(self.LogTextEdit)
        # excelFileDataList 为新生成的每一个新excel 数据集合的集合
        self.excelFileDataList = []
        # 显示托盘
        self.tray = TrayIcon(parent=self, clickEnable=False)
        self.tray.connect(self.tray,
                          QtCore.SIGNAL('showTrayMsgSignal(QString)'),
                          self.showTrayMsg)

    # 选取Excel 文件
    def selectExcelFileMethod(self):
        filePath = unicode(
            QtGui.QFileDialog.getOpenFileName(None, 'Select excel',
                                              self.getLastOpenDir(),
                                              'binder_number(*.xls *.xlsx)'))
        if not filePath:
            return
        self.selectExcelFileLineEdit.setText(filePath)

    # 获取QFileDialog 上次打开的路径
    def getLastOpenDir(self):
        lastDir = self.selectExcelFileLineEdit.text()
        if lastDir:
            return str(lastDir)
        # open last remember directory
        lastDir = QSettingsUtil.getLastDir()
        if not QtCore.QDir(lastDir).exists():
            lastDir = 'd://'
        return str(lastDir)

    def splitExcelDataMethod(self):
        # self.doSplitExcelData(log_call_back=self.emitAppendLogSignal)
        threadUtil = ThreadUtil(funcName=self.doSplitExcelData,
                                log_call_back=self.emitAppendLogSignal)
        threadUtil.setDaemon(True)
        threadUtil.start()

    def doSplitExcelData(self, log_call_back):
        # 先进行清空操作
        self.excelFileDataList = []
        filePath = str(self.selectExcelFileLineEdit.text())
        if not filePath:
            log_call_back(u'请先选择Excel文件')
        log_call_back(u'行拆分和列拆分,是互斥操作,优先行拆分.')
        startLineStr = str(self.LineConditionStartLineEdit.text())
        endLineStr = str(self.LineConditionEndLineEdit.text())
        lineIntervalStr = str(self.LineConditionIntervalEdit.text())
        startColumnStr = str(self.ColumnConditionStartLineEdit.text())
        endColumnStr = str(self.ColumnConditionEndLineEdit.text())
        columnIntervalStr = str(self.ColumnConditionIntervalEdit.text())
        try:
            data = xlrd.open_workbook(unicode(filePath))
            dataTable = data.sheets()[0]
            tableRow = dataTable.nrows
            tableColumn = dataTable.ncols
            # print 'table row: ', tableRow
            # print 'table col: ', tableColumn
            # 配合 xrange ()的方式
            excelStartLine = int(startLineStr) - 1 if startLineStr else 0
            excelEndLine = int(endLineStr) if endLineStr else tableRow
            excelLineInterval = int(lineIntervalStr) if lineIntervalStr else -1
            excelStartColumn = int(startColumnStr) - 1 if startColumnStr else 0
            excelEndColumn = int(endColumnStr) if endColumnStr else tableColumn
            excelColumnInterval = int(
                columnIntervalStr) if columnIntervalStr else -1
            if excelLineInterval < 0 and excelColumnInterval < 0:
                log_call_back(u'必须要有一个行或者列拆分间隔!')
                return
            if excelStartLine < 0 or excelStartLine > tableRow or excelStartLine > excelEndLine or excelEndLine < 0 \
                    or excelStartColumn < 0 or excelStartColumn > tableColumn or excelStartColumn > excelEndColumn \
                    or excelEndColumn < 0:
                log_call_back(u'参数不合法,请重新输入!')
                return
            cellDataList = []
            newLineNo = 0
            newColumnNo = 0
            # 先准备数据
            for i in xrange(excelStartLine, excelEndLine):
                for j in xrange(excelStartColumn, excelEndColumn):
                    # print 'i = %d, j= %d ' % (i, j)
                    # rowDataList = dataTable.row_values(i)
                    # columnDataList = dataTable.col_values(j)
                    # cellData = dataTable.cell(i, j).value
                    # print 'rowDataList: ', rowDataList
                    # print 'columnDataList: ', columnDataList
                    # print 'cellData: ', cellData
                    # print 'i = %d , interval = %d , sp = %d ' % (i, excelLineInterval, i % excelLineInterval)
                    if i != 0 and excelLineInterval > 0 and i % excelLineInterval == 0:
                        newLineNo = 0
                    elif j != 0 and excelColumnInterval > 0 and j % excelColumnInterval == 0:
                        newColumnNo = 0
                    else:
                        pass
                    excelData = ExcelData()
                    excelData.lineNo = newLineNo
                    excelData.columnNo = newColumnNo
                    excelData.value = dataTable.cell(i, j).value
                    cellDataList.append(excelData)
                    newColumnNo += 1
                newLineNo += 1
                newColumnNo = 0
            # 拆分数据,到各个excel文件中去
            tempList = []
            for i in xrange(len(cellDataList)):
                if tempList and cellDataList[i].lineNo == 0 and cellDataList[
                        i].columnNo == 0:
                    self.excelFileDataList.append(tempList)
                    tempList = []
                tempList.append(cellDataList[i])
                if i == len(cellDataList) - 1:
                    self.excelFileDataList.append(tempList)
            # print 'excelFileDataList: ', self.excelFileDataList
            # for excelList in self.excelFileDataList:
            #     print '-------------------------------'
            #     for cellData in excelList:
            #         print 'cellData: ', cellData
            interval = excelLineInterval if excelLineInterval > 0 else \
                (excelColumnInterval if excelColumnInterval > 0 else -1)
            self.genExcelData(self.excelFileDataList, interval, log_call_back)
        except Exception as e:
            raise e

    def genExcelData(self, allExcelDataList, interval, log_call_back):
        if not allExcelDataList:
            log_call_back(u'未生成相关数据!')
            return
        if interval == -1:
            log_call_back(u'拆分间隔未设置,不做数据拆分!')
            return
        selectExcelFileName = FileUtil.getFilePathWithName(
            str(self.selectExcelFileLineEdit.text()))
        for i in xrange(len(allExcelDataList)):
            excelFileName = str(selectExcelFileName) + str("_") + str(
                (i + 1) * interval) + str(".xls")
            # print 'excelFileName: ', excelFileName
            workbook = xlwt.Workbook(encoding='utf-8')
            sheetData = workbook.add_sheet("split_data")
            for cellData in allExcelDataList[i]:
                # print 'cellData===', cellData
                sheetData.write(cellData.lineNo, cellData.columnNo,
                                cellData.value)
            workbook.save(unicode(excelFileName))
        log_call_back(u'excel文件拆分完毕!')

    # 打开文件夹
    def openDirMethod(self):
        excelFilePath = str(self.selectExcelFileLineEdit.text())
        if not excelFilePath:
            logMsg = u'请先选择Excel 文件'
            self.appendLog(logMsg)
            return
        parentPath = unicode(FileUtil.getFileDir(excelFilePath))
        # print 'parentPath: %s' % parentPath
        os.startfile(parentPath)

    # 显示操作日志
    def appendLog(self, logTxt):
        self.LogTextEdit.append(_translateUtf8(logTxt))

    # 解决在子线程中刷新UI 的问题。' QWidget::repaint: Recursive repaint detected '
    def appendLogSignal(self, logTxt):
        pass

    def emitAppendLogSignal(self, logTxt):
        self.LogTextEdit.emit(QtCore.SIGNAL('appendLogSignal(QString)'),
                              logTxt)

    # 托盘消息
    def showTrayMsg(self, trayMsg):
        self.tray.show()
        # show 5 min
        self.tray.showMsg(trayMsg)

    def showTrayMsgSignal(self, trayMsg):
        pass

    def emitTrayMsgSignal(self, trayMsg):
        self.tray.emit(QtCore.SIGNAL('showTrayMsgSignal(QString)'), trayMsg)

    def keyPressEvent(self, event):
        # 设置 "Ctrl+w" 快捷键,用于关闭 tab
        if event.key() == QtCore.Qt.Key_W and event.modifiers(
        ) == QtCore.Qt.ControlModifier:
            self.close()
예제 #10
0
import sys

from PyQt5.QtWidgets import QApplication

from MainWindow import RelaxWindow
from TrayIcon import TrayIcon

if __name__ == '__main__':
    app = QApplication(sys.argv)

    # 主界面
    relaxWindow = RelaxWindow()
    relaxWindow.show()

    # 托盘图标
    tray_icon = TrayIcon(relaxWindow)
    tray_icon.show()

    # 事件驱动
    sys.exit(app.exec_())
예제 #11
0
    def __init__(self, config, root, app):
        # mainwindow 初始化 ======================================================================
        super().__init__()
        self.app = app
        # 保存传入的初始化数据
        Add('config')
        Space["config"] = config
        Add('root')
        Space["root"] = root

        TrayIcon_img = dir_mix(Space["root"],
                               Space["config"]['cover'])  # 用人物预览图作为托盘图标 和 显示图标

        with open(dir_mix(Space["root"], Space["config"]['Script']),
                  'r',
                  encoding='utf-8') as f:
            Add('Script')
            Space["Script"] = json.loads(f.read())  # 获取Script的参数
        Setting = Space["Script"]["Setting"]  # 获取Setting的数据集合

        self.ImageSize = Setting["ImageSize"]
        Add('Change')
        Space['Change'] = Setting["Change"]

        try:
            self.sound_Actions = Space["Script"]["sound"]
        except:
            pass

        Add('Info')
        Space['Info'] = {}
        Space['Info']["Play_complete"] = {}  # 播放组件是否播放完毕设置
        Space['Info']["Move"] = {}
        Space['Info']["Move"]["Window"] = {}

        Add('Control_Api')
        Space['Control_Api'] = {}

        # 核心控制器类
        Add("CoreControl")
        Space["CoreControl"] = Special_Control.CoreControl()

        self.setupUi(self)  # 创建标准窗口
        self.setAttribute(QtCore.Qt.WA_TranslucentBackground)  # 设置窗口背景透明
        self.setWindowTitle(
            Space["config"]['Name'])  # 把窗口名称设置成config.json中的Name键的值
        self.setWindowIcon(QtGui.QIcon(TrayIcon_img))  # 设置Icon

        self.Cache = {}  # 图片缓存字典

        # 组件创建
        self.label = Special_Label(self)  # 创建特殊的Label
        self.PlayBoard = PlayBoard()  # 创建播放器
        self.PlayBoard.play.connect(self.graph)
        self.Find = Find()  # 实例化指令查询插件
        self.sound = QtMultimedia.QMediaPlayer()  # 创立音频播放组件

        Space['BGMPlayer'] = QtMultimedia.QMediaPlayer()
        Space['BGMPlaylist'] = QtMultimedia.QMediaPlaylist()

        self.User = User()  # User组件 (会创建CommonSet,在Setbox前加载)

        self.Setbox = Setbox(self)

        self.ChangeWindowFlags(True)

        # 核心控制器绑定组件 ============================================
        Space["CoreControl"].play.connect(self.PlayNew)
        Space["CoreControl"].sound.connect(self.soundPlay)
        Space["CoreControl"].ChangeSize.connect(self.ChangeSize)
        Space["CoreControl"].Move.connect(self.MovePeson)

        Space["CoreControl"].clean.connect(self.PlayBoard.terminate)
        Space["CoreControl"].clean.connect(self.Setbox.close)
        Space["CoreControl"].clean.connect(self.close)
        Space["CoreControl"].clean.connect(self.app.exit)

        # Special_Label组件事件绑定 ============================================
        self.label.LeftButton_release.connect(
            self.LeftButton_release)  # 绑定鼠标左键点击事件[松开左键]
        self.label.LeftButton_click.connect(
            self.LeftButton_click)  # 绑定鼠标左键点击事件[松开左键]

        self.label.RightButton_release.connect(
            self.RightButton_release)  # 绑定鼠标右键点击事件[松开右键]
        self.label.RightButton_Move.connect(self.RightButton_Move)

        # 设置事件绑定 ===========================
        self.Setbox.MovePeson.connect(self.MovePeson)
        self.Setbox.ResetWindowFlag.connect(self.ChangeWindowFlags)
        # TrayIcon 组件 =====================================
        self.TrayIcon = TrayIcon(self)
        self.TrayIcon.setIcon(QtGui.QIcon(TrayIcon_img))
        self.TrayIcon.show()
        self.TrayIcon.AddActions("退出", self.close_)
        self.TrayIcon.AddActions("设置", self.Setbox.show)

        # 线程启动
        self.PlayBoard.start()

        if Space['CommonSet']["Change"] != None:
            Space['Change'] = Space['CommonSet']["Change"]
        self.ChangeSize()  # 设置窗口初始大小

        # Importer
        plugin.Importer()
예제 #12
0
class window_graphics(QtWidgets.QMainWindow, graphics_window):
    def __init__(self, config, root, app):
        # mainwindow 初始化 ======================================================================
        super().__init__()
        self.app = app
        # 保存传入的初始化数据
        Add('config')
        Space["config"] = config
        Add('root')
        Space["root"] = root

        TrayIcon_img = dir_mix(Space["root"],
                               Space["config"]['cover'])  # 用人物预览图作为托盘图标 和 显示图标

        with open(dir_mix(Space["root"], Space["config"]['Script']),
                  'r',
                  encoding='utf-8') as f:
            Add('Script')
            Space["Script"] = json.loads(f.read())  # 获取Script的参数
        Setting = Space["Script"]["Setting"]  # 获取Setting的数据集合

        self.ImageSize = Setting["ImageSize"]
        Add('Change')
        Space['Change'] = Setting["Change"]

        try:
            self.sound_Actions = Space["Script"]["sound"]
        except:
            pass

        Add('Info')
        Space['Info'] = {}
        Space['Info']["Play_complete"] = {}  # 播放组件是否播放完毕设置
        Space['Info']["Move"] = {}
        Space['Info']["Move"]["Window"] = {}

        Add('Control_Api')
        Space['Control_Api'] = {}

        # 核心控制器类
        Add("CoreControl")
        Space["CoreControl"] = Special_Control.CoreControl()

        self.setupUi(self)  # 创建标准窗口
        self.setAttribute(QtCore.Qt.WA_TranslucentBackground)  # 设置窗口背景透明
        self.setWindowTitle(
            Space["config"]['Name'])  # 把窗口名称设置成config.json中的Name键的值
        self.setWindowIcon(QtGui.QIcon(TrayIcon_img))  # 设置Icon

        self.Cache = {}  # 图片缓存字典

        # 组件创建
        self.label = Special_Label(self)  # 创建特殊的Label
        self.PlayBoard = PlayBoard()  # 创建播放器
        self.PlayBoard.play.connect(self.graph)
        self.Find = Find()  # 实例化指令查询插件
        self.sound = QtMultimedia.QMediaPlayer()  # 创立音频播放组件

        Space['BGMPlayer'] = QtMultimedia.QMediaPlayer()
        Space['BGMPlaylist'] = QtMultimedia.QMediaPlaylist()

        self.User = User()  # User组件 (会创建CommonSet,在Setbox前加载)

        self.Setbox = Setbox(self)

        self.ChangeWindowFlags(True)

        # 核心控制器绑定组件 ============================================
        Space["CoreControl"].play.connect(self.PlayNew)
        Space["CoreControl"].sound.connect(self.soundPlay)
        Space["CoreControl"].ChangeSize.connect(self.ChangeSize)
        Space["CoreControl"].Move.connect(self.MovePeson)

        Space["CoreControl"].clean.connect(self.PlayBoard.terminate)
        Space["CoreControl"].clean.connect(self.Setbox.close)
        Space["CoreControl"].clean.connect(self.close)
        Space["CoreControl"].clean.connect(self.app.exit)

        # Special_Label组件事件绑定 ============================================
        self.label.LeftButton_release.connect(
            self.LeftButton_release)  # 绑定鼠标左键点击事件[松开左键]
        self.label.LeftButton_click.connect(
            self.LeftButton_click)  # 绑定鼠标左键点击事件[松开左键]

        self.label.RightButton_release.connect(
            self.RightButton_release)  # 绑定鼠标右键点击事件[松开右键]
        self.label.RightButton_Move.connect(self.RightButton_Move)

        # 设置事件绑定 ===========================
        self.Setbox.MovePeson.connect(self.MovePeson)
        self.Setbox.ResetWindowFlag.connect(self.ChangeWindowFlags)
        # TrayIcon 组件 =====================================
        self.TrayIcon = TrayIcon(self)
        self.TrayIcon.setIcon(QtGui.QIcon(TrayIcon_img))
        self.TrayIcon.show()
        self.TrayIcon.AddActions("退出", self.close_)
        self.TrayIcon.AddActions("设置", self.Setbox.show)

        # 线程启动
        self.PlayBoard.start()

        if Space['CommonSet']["Change"] != None:
            Space['Change'] = Space['CommonSet']["Change"]
        self.ChangeSize()  # 设置窗口初始大小

        # Importer
        plugin.Importer()

    def ChangeWindowFlags(self, init=True):
        Flags = 0
        for i in Space['WindowFlags']:
            Flags = Flags | i
        self.setWindowFlags(QtCore.Qt.WindowType(Flags))
        if init:
            return
        if not self.isVisible():
            self.setVisible(True)

    def MovePeson(self):
        self.move(Space['Info']["Move"]["Window"]['PersonX'],
                  Space['Info']["Move"]["Window"]['PersonY'])
        # 同步移动,拖动窗口时候同时移动人物

    def show(self):
        super().show()

        Space['Info']["Move"]["Window"]['PersonX'] = self.pos().x()
        Space['Info']["Move"]["Window"]['PersonY'] = self.pos().y()

        # 在标准窗口show()后才可以获取窗口的x,y坐标

    def PlayNew(self, name):  # 播放新的动作
        self.PlayBoard.Action = name
        self.PlayBoard.stop = True

    def close_(self):
        Space["CoreControl"].clean.emit()

    def soundPlay(self, sound_name):
        path = dir_mix(Space["root"],
                       path_read(self.sound_Actions[sound_name]["path"]))

        url = QtCore.QUrl.fromLocalFile(path)
        self.sound.setMedia(QtMultimedia.QMediaContent(url))
        self.sound.play()

    def RightButton_release(self):
        self.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))

        # 拖动完成必然松开右键才能操作别的,只同步最新拖动后的人物x,y数据,节省资源
        Space['Info']["Move"]["Window"]['PersonX'] = self.pos().x()
        Space['Info']["Move"]["Window"]['PersonY'] = self.pos().y()

    def RightButton_Move(self, x, y):
        Space["CoreControl"].stopAllAction.emit()
        self.move(x, y)
        self.setCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))

        if self.Setbox.MoveWithPerson:
            self.Setbox.move(x - 800, y)

    def LeftButton_click(self, x, y):
        self.Find.LeftClick(x, y, Space['Change'])

    def LeftButton_release(self, x, y):
        self.Find.LeftRelease(x, y, Space['Change'])
        # self.PlayBoard.stop = True

    def ChangeSize(self):
        # Space['Change']:图片缩放系数,>0 [理论是多大都可以,但是你改100看我不 *%*&%]

        width = int(self.ImageSize[0] * Space['Change'])
        height = int(self.ImageSize[1] * Space['Change'])
        self.resize(width, height)
        self.label.setGeometry(0, 0, width, height)

    def graph(self, paths):
        hash_ = hash(paths)
        if Space["CommonSet"]["Cache"]:
            if hash_ not in self.Cache.keys():
                #print(hash(paths))
                self.Cache[hash_] = QtGui.QImage(paths)
            self.label.setPixmap(
                QtGui.QPixmap.fromImage(self.Cache[hash_].scaled(
                    self.label.width(), self.label.height()).mirrored(
                        Space['CommonSet']["mirrored"], False)))
        else:
            self.Cache.clear()
            self.label.setPixmap(
                QtGui.QPixmap.fromImage(
                    QtGui.QImage(paths).scaled(
                        self.label.width(), self.label.height()).mirrored(
                            Space['CommonSet']["mirrored"], False)))
예제 #13
0
파일: __init__.py 프로젝트: Ciemaar/oaf
 def OnInit(self):
     self.sysIcon = TrayIcon(self)
     self.oafRoot.putNotifier("tray", self.sysIcon)
     return True
예제 #14
0
 def create_tray(self):
     self.tray = TrayIcon(self)
     self.tray.setVisible(True)
     self.app.processEvents()
예제 #15
0
class ToolTabWidget(QtGui.QTabWidget):
    def __init__(self, app, args=None, host=None, port=None):
        QtGui.QTabWidget.__init__(self)
        self.app = app
        if args:
            if args.lang:
                self.lang = args.lang

        self.setContentsMargins(0, 0, 0, 0)
        self.init_variables()

        # Initialization GUI variables
        self.VarsGui = DataVarsGui()
        self.VarsGui.importGui()
        self.VarsGui.flIniFile()

        ClientObj = ApiClient(app, self)
        self.FirstWidget = ClientObj.MainWidget

        self.PlusWidget = QtGui.QWidget(self)

        self.tabbar = MyTabBar(self)
        self.setTabBar(self.tabbar)

        QtGui.QIcon.setThemeName("Calculate")
        self.gui_icon = QtGui.QIcon.fromTheme("video-display")

        self.other_icon = QtGui.QIcon.fromTheme("list-add")
        if self.other_icon.isNull():
            self.other_icon = QtGui.QIcon.fromTheme("preferences-desctop")

        self.addTab(self.FirstWidget, self.gui_icon, self.new_con_txt)
        self.addTab(self.PlusWidget, self.other_icon, "")

        self.last_close_index = -1
        self.tabCloseRequested.connect(self.close_tab)
        self.selected.connect(self.add_tab)

        self.selected.connect(self.changeWindowTitle)

        self.setTabsClosable(True)
        self.tabbar.tabButton(1, QtGui.QTabBar.ButtonPosition.RightSide).hide()

        if not self.get_size():
            # definition of screen resolution
            prim_screen = self.app.desktop().primaryScreen()
            d_size = self.app.desktop().screenGeometry(prim_screen).size()

            # resize main widget
            if d_size.height() < 768:
                self.resize(900, 560)
            else:
                self.resize(900, 700)
        self.setMinimumHeight(100)
        self.setMinimumWidth(500)

        self.setWindowTitle(self.Name)
        self.setStyleSheet(
            """
        QTabBar::tab:last {
        background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
                                    stop: 0 #E1E1E1, stop: 0.4 #DDDDDD,
                                    stop: 0.5 #D8D8D8, stop: 1.0 #D3D3D3);
        border: 2px solid #C4C4C3;
        border-bottom-color: #C2C7CB; border-top-left-radius: 4px;
        border-top-right-radius: 4px; padding-left: 3px;

        margin-left: 3px; margin-bottom: 5px; margin-top: 2px; width: 18px;}
        QTabBar::tab:last::hover {background: 
                            qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
                            stop: 0 #E9E9E9, stop: 0.4 #E5E5E5,
                            stop: 0.5 #E1E1E1, stop: 1.0 #DDDDDD);}
                            """
        )
        self.setWindowIcon(QtGui.QIcon("/usr/share/pixmaps/calculate-console-offline.png"))

        self.show()
        self.app.processEvents()

        self.connect_dict = {}
        self.connect_count = 0

        if not host or host == "localhost":
            host = "127.0.0.1"
        self.FirstWidget.connect_to_localhost(host, port)
        if self.FirstWidget.ClientObj.client:
            if host in ["127.0.0.1", "localhost"]:
                self.localhost_ClientObj = self.FirstWidget.ClientObj
            if not host in self.connect_dict:
                self.connect_dict[host] = [port]
            else:
                if port:
                    if not port in self.connect_dict[host]:
                        self.connect_dict[host].append(port)
        self.create_tray()
        if self.FirstWidget.ClientObj.client:
            self.tray.set_icon(True)

    def connect_count_changed(self, host, port, count):
        if count:
            if not host in self.connect_dict:
                self.connect_dict[host] = [port]
            else:
                if port:
                    if not port in self.connect_dict[host]:
                        self.connect_dict[host].append(port)
        else:
            if host in self.connect_dict:
                if port in self.connect_dict[host]:
                    self.connect_dict[host].remove(port)
                if not self.connect_dict[host]:
                    self.connect_dict.pop(host)

        if self.connect_dict:
            self.setWindowIcon(QtGui.QIcon("/usr/share/pixmaps/calculate-console-online.png"))
            if hasattr(self, "tray"):
                self.tray.set_icon(True)
        else:
            self.setWindowIcon(QtGui.QIcon("/usr/share/pixmaps/calculate-console-offline.png"))
            if hasattr(self, "tray"):
                self.tray.set_icon(False)

    def init_variables(self):
        try:
            self.Version = self.VarsGui.Get("cl_ver")
        except:
            self.Version = ""

        try:
            self.Name = self.VarsGui.Get("cl_name")
        except:
            self.Name = "Calculate Console"

        self.new_con_txt = _("New connection")
        self.sys_update_pid = None

    def close_tab(self, cur_num=None, hard=False):
        exit_flag = 0
        if cur_num == None:
            cur_num = self.currentIndex()

        if cur_num != self.count() - 1:
            # for delete widget
            self.setCurrentIndex(cur_num)
            wgt = self.currentWidget()

            if wgt == self.FirstWidget and not hard:
                return exit_flag
            if wgt._closeEvent():
                wgt.close()

                self.last_close_index = cur_num
                if cur_num:
                    self.setCurrentIndex(cur_num - 1)
                else:
                    self.setCurrentIndex(0)
                self.removeTab(cur_num)
                exit_flag = 1
        if self.count() < 2:
            self.add_tab()
        return exit_flag

    def add_tab(self):
        if self.currentIndex() == self.count() - 1:
            # not add if exists clean tab
            for tab_num in range(self.count() - 1):
                self.setCurrentIndex(tab_num)
                if not self.currentWidget().ClientObj.client:
                    return 0

            ClientObj = ApiClient(self.app, self)
            widget = ClientObj.MainWidget
            widget.cur_window_title = self.Name

            self.insertTab(self.count() - 1, widget, self.gui_icon, self.new_con_txt)
            self.setCurrentIndex(self.count() - 2)
        if self.currentWidget().ClientObj.client:
            self.tabbar.setTabEnabled(self.count() - 1, True)
        else:
            self.tabbar.setTabEnabled(self.count() - 1, False)

    def rename_tab(self, text=None, ind=None):
        if not text:
            text = self.new_con_txt
        if not ind:
            ind = self.currentIndex()
        self.setTabText(ind, text)

    def changeWindowTitle(self, tab_num):
        try:
            text = self.currentWidget().cur_window_title
            self.setWindowTitle(text)
        except AttributeError:
            pass

    def setWindowTitle(self, title):
        self.currentWidget().cur_window_title = title
        super(ToolTabWidget, self).setWindowTitle(title)

    def create_tray(self):
        self.tray = TrayIcon(self)
        self.tray.setVisible(True)
        self.app.processEvents()

    def translate(self, lang=None):
        self.new_con_txt = _("New connection")
        self.new_con_txt = self.new_con_txt.decode("utf-8")

        current = self.currentIndex()
        # not add if exists clean tab
        for tab_num in range(self.count() - 1):
            self.setCurrentIndex(tab_num)
            if not self.currentWidget().ClientObj.client:
                self.setTabText(tab_num, self.new_con_txt)
        self.setCurrentIndex(current)

        if hasattr(self, "tray"):
            self.tray.translate()

    def set_localhost(self, ClientObj):
        self.localhost_ClientObj = ClientObj

    #        if ClientObj:
    #            self.connect_dict[ClientObj.host_name] = \
    #                             [ClientObj, self.currentIndex()]
    #        self.tabbar.tabButton(self.currentIndex(), \
    #                              QtGui.QTabBar.ButtonPosition.RightSide).hide()

    def find_host(self, host_name, port):
        ind = self.currentIndex()
        for i in xrange(self.count() - 1):
            self.setCurrentIndex(i)
            wgt = self.currentWidget()
            if hasattr(wgt, "ClientObj"):
                ClientObj = wgt.ClientObj
                if host_name == ClientObj.host_name and port == ClientObj.port and ClientObj.client:
                    self.removeTab(ind)
                    return 1

        self.setCurrentIndex(ind)
        return 0

    def closeEvent(self, event):
        self.cur_pos = self.pos()
        self.hide()
        event.ignore()

    def _closeEvent(self):
        for tab_num in range(self.count()):
            if not self.close_tab(0, True):
                return 1
        self.set_size()
        save_path = os.path.join("/tmp", "calculate-" + pwd.getpwuid(os.getuid()).pw_name)
        if os.path.isdir(save_path):
            shutil.rmtree(save_path)
        self.app.exit()

    def get_size(self):
        conf_path = self.VarsGui.Get("cl_gui_config_path")
        homePath = self.VarsGui.Get("ur_home_path")
        self.user_config = conf_path.replace("~", homePath)
        self.config = ConfigParser.ConfigParser()
        self.config.read(self.user_config)
        try:
            size = self.config.get("gui", "size")
        except (ConfigParser.NoOptionError, ConfigParser.NoSectionError):
            return False
        tup_size = map(lambda x: int(x), size.split(","))
        self.resize(tup_size[0], tup_size[1])
        return True

    def set_size(self):
        self.config = ConfigParser.ConfigParser()
        self.config.read(self.user_config)
        try:
            self.config.set("gui", "size", ",".join(map(lambda x: str(x), self.size().toTuple())))
            self.config.write(open(self.user_config, "w"))
        except (ConfigParser.NoOptionError, ConfigParser.NoSectionError):
            return False

    def keyPressEvent(self, e):
        if e.key() == QtCore.Qt.Key_Return:
            self.currentWidget().keyPressEvent(e)
        else:
            QtGui.QTabWidget.keyPressEvent(self, e)