Exemple #1
0
class WAtQtMain(CgAt):
    def __init__(self):
        super().__init__()
        self.wn_init()

    def wn_init(self):
        self.wu_wgt = QMainWindow()
        self.wu_wgt.setWindowTitle(GC_APP_NM)
        self.wu_cw = QWidget()
        self.wu_lo = QVBoxLayout()
        self.wu_tv = QTableView()
        self.wu_tv.verticalHeader().hide()
        self.wu_tv.horizontalHeader().setStretchLastSection(True)
        self.wu_tv.setModel(HSpellout(32345678))
        self.wu_tv.scrollToBottom()
        self.wu_lo.addWidget(self.wu_tv)
        self.wu_cw.setLayout(self.wu_lo)
        self.wu_wgt.setCentralWidget(self.wu_cw)
        self.wu_wgt.resize(777, 333)
        self.wu_wgt.show()
        self.wu_wgt.raise_()
        self.wn_move_center()

    def wn_move_center(self):
        nu_cp = QDesktopWidget().availableGeometry().center()  # center point
        self.wu_wgt.move(nu_cp.x() - self.wu_wgt.width() / 2,
                         nu_cp.y() - self.wu_wgt.height() / 2)
Exemple #2
0
class WQtMain(CgQo, TgWai):
    def __init__(self):
        super().__init__()
        self.wn_init()

    def wn_init(self):
        JC_LOG.info(self.tm_wai('Initializing ...'))
        self.wu_mw = QMainWindow()
        self.wu_mw.setWindowTitle(GC_APP_NM)
        self.wu_mw.showEvent = lambda _: self.wn_shown()
        self.wu_mw.closeEvent = lambda _: self.wn_quit()
        self.wu_cw = QWidget()
        self.wu_lo = QVBoxLayout()
        self.wu_pb = QPushButton()
        self.wu_pb.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        self.wu_pb.pressed.connect(self.wn_change_font)
        self.wu_lb = QLabel()
        self.wu_lb.setAlignment(Qt.AlignCenter)
        for bu2_qo in [QWidget(), self.wu_pb, self.wu_lb]:
            self.wu_lo.addWidget(bu2_qo)
        self.wu_cw.setLayout(self.wu_lo)
        self.wu_fnt_families = QFontDatabase().families()
        self.wv_fnt_idx = len(self.wu_fnt_families) - 1
        self.wv_msg = ''
        self.wu_mw.setCentralWidget(self.wu_cw)
        self.wu_mw.resize(650, 200)
        self.wu_mw.show()
        self.wu_mw.raise_()
        self.wn_move_center()
        self.wn_change_font()
        self.startTimer(100)

    def timerEvent(self, x_ev):
        self.wn_change_font()

    def wn_change_font(self):
        if self.wv_fnt_idx >= len(self.wu_fnt_families): self.wv_fnt_idx = 0
        nu_fnt_nm = self.wu_fnt_families[self.wv_fnt_idx]
        if self.wv_msg != '': JC_LOG.info(f'[Qt] {self.wv_msg}')
        nu_nt = f'({self.wv_fnt_idx+1}/{len(self.wu_fnt_families)})'
        self.wv_msg = f'0^0 {nu_nt} ({nu_fnt_nm})'
        self.wu_pb.setText(f"Say '{self.wv_msg}'")
        self.wu_pb.setFont(QFont(nu_fnt_nm, 17))
        self.wu_lb.setText(f'{nu_nt} Font name : {nu_fnt_nm}')
        self.wv_fnt_idx += 1
        self.wn_move_center()

    def wn_move_center(self):
        nu_cp = QDesktopWidget().availableGeometry().center()  # center point
        self.wu_mw.move(nu_cp.x() - self.wu_mw.width() / 2,
                        nu_cp.y() - self.wu_mw.height() / 2)

    def wn_shown(self):
        JC_LOG.info('Widget shown ...')

    def wn_quit(self):
        JC_LOG.info(self.tm_wai('About to quit ...'))
        jp_request_exit(GC_EC_SUCCESS)
Exemple #3
0
    def appendedRowsIfNeeded(self):
        # L.debug("appended row if neened")
        self.height = QMainWindow.height(self)
        visibleRows = self.height / self.rowHeight
        rowsToAdd = ceil(visibleRows - g.quoteModel.rowCount())
        rowsToAdd = max(rowsToAdd, 0)

        for _ in range(rowsToAdd):
            g.quoteModel.appendRow()
class ShowLogWindow():
    log_content = ''
    logwin = None

    def __init__(self, log_content):
        self.log_content = log_content
        self.logwin = QMainWindow()

    def show_log_window(self):
        self.logwin.resize(869, 618)
        palette = QPalette()
        pix = QPixmap('../icons/dream.jpg')
        pix = pix.scaled(self.logwin.width(), self.logwin.height())
        palette.setBrush(QPalette.Background, QBrush(pix))
        self.logwin.setPalette(palette)
        lg = LogWindow.Ui_MainWindow()
        lg.setupUi(self.logwin)
        lg.additional_operations(self.log_content)
        self.logwin.show()
    def __init__(self, mainWindow: QMainWindow):
        super(myLoading_UI, self).__init__()
        self.setupUi(self)

        # 获取主窗口的坐标
        self.m_winX = mainWindow.x()
        self.m_winY = mainWindow.y()

        self.m_win_w = mainWindow.width()
        self.m_win_h = mainWindow.height()

        self.move((self.m_winX + self.m_win_w) / 2,
                  self.m_winY + self.m_win_h / 2)  # 移动加载界面到主窗口的中心
        # 设置窗口无边框|对话框|置顶模式
        self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
        # 设置背景透明
        self.setAttribute(Qt.WA_TranslucentBackground)
        # 加载动画
        self.loading_gif = QMovie('../ico/5-160914192R6-51.gif')
        self.label.setMovie(self.loading_gif)
        self.loading_gif.start()
class MainWindow(Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.main_window = QMainWindow()
        self.setupUi(self.main_window)
        self.main_window.setFixedSize(self.main_window.width(), self.main_window.height())
        self.msg = QMessageBox()
        self.set_slot()
        self.qr = self.main_window.frameGeometry()  # move to center of screen
        self.cp = QDesktopWidget().availableGeometry().center()
        self.qr.moveCenter(self.cp)
        self.main_window.move(self.qr.topLeft())
        self.text_edit_urls.setAcceptRichText(False)

    def set_slot(self):
        self.button_download.clicked.connect(self.get_info)
        self.action_about.triggered.connect(self.show_about)
        self.action_file_path.triggered.connect(self.set_file_path)
        self.action_check_for_updates.triggered.connect(self.check_for_updates)
        self.action_report_bugs.triggered.connect(self.report_bugs)

    def get_info(self):
        mconfig.set_default()
        self.button_download.setEnabled(False)
        self.urls = (str(self.text_edit_urls.toPlainText())).split(';')
        mlog.debug(self.urls[0])

        self.m_thread = GetVideoInfoThread(self.urls, **mconfig.kwargs)
        self.m_thread.finish_signal.connect(self.finish_get_info)
        self.m_thread.start()

    def finish_get_info(self, ls, can_download):
        mlog.debug('finish_get_info: ' + str(can_download))
        self.button_download.setEnabled(True)
        if can_download:
            self.files_list_dialog = FilesListDialog()
            self.files_list_dialog.update_files_list(ls)
            mconfig.set_urls(self.urls)
        else:
            self.show_msg(QMessageBox.Critical, 'Failed ', 'Can not get the files list (╯°Д°)╯︵ ┻━┻')

    def show_about(self):
        mlog.debug('show about widget')
        self.about_widget = AboutWdiget()
        self.about_widget.about_widget.move(self.qr.topLeft())
        self.about_widget.about_widget.show()

    def set_file_path(self):
        fname = QFileDialog.getExistingDirectory(self.main_window, caption='Select Path', directory='',
                                                 options=QFileDialog.ShowDirsOnly)
        if fname:
            mconfig.set_file_path(fname)
            mlog.debug('changed file path to ' + mconfig.get_file_path())
            self.show_msg(QMessageBox.Information, 'Tip', 'Changed file path to:\n' + str(fname))
        else:
            mconfig.set_file_path(mconfig.base_dir)
            self.show_msg(QMessageBox.Information, 'Tip', 'Default file path:\n' + str(mconfig.base_dir))

    def show_msg(self, icon, title, text):
        self.msg.setWindowTitle(title)
        self.msg.setIcon(icon)
        self.msg.setText(text)
        self.msg.setStandardButtons(QMessageBox.Ok)
        self.msg.show()

    def check_for_updates(self):
        mlog.debug('check_for_updates')
        try:
            with request.urlopen('https://raw.githubusercontent.com/ingbyr/GUI-YouGet/master/version.json') as f:
                raw_inf = str(f.read())[2:-1]
                mlog.debug(str(f.read())[2:-1])
                remote_inf = json.loads(raw_inf)
                mlog.debug('remote version is ' + remote_inf['version'])
        except Exception:
            for item in sys.exc_info():
                mlog.error(str(item))
                self.show_msg(QMessageBox.Critical, 'Failed', 'Check for updates failed')
            return

        if mconfig.version >= remote_inf['version']:
            self.show_msg(QMessageBox.Information, 'Check for updates', 'No available updates')
        else:
            self.show_msg(QMessageBox.Information, 'Check for updates', 'There is a new version')
            self.do_updates()

    def do_updates(self):
        QDesktopServices.openUrl(QUrl('http://www.ingbyr.tk/2016/05/16/youget/'))

    def report_bugs(self):
        QDesktopServices.openUrl(QUrl('https://github.com/ingbyr/GUI-YouGet/issues'))
 def saveWindowSettings(self, ui: QWidget, window: QMainWindow):
     self.set('WINDOW', 'width', str(window.width()))
     self.set('WINDOW', 'height', str(window.height()))
     for i in range(0, ui.treeWidget.header().count() + 1):
         self.set('WINDOW', 'section' + str(i),
                  str(ui.treeWidget.header().sectionSize(i)))
Exemple #8
0
class MyApp(QMainWindow):
    def __init__(self):
        super().__init__()
        # Ui_MainWindow.__init__(self)
        # self.setupUi(self)

        self.initializeVariables()

        rows = 3
        cols = 17
        self.rows = rows
        self.columns = cols
        self.MainWindowWidth = 1000
        lenghtOfWord = 10
        defaultLength = 100
        self.sentencewidget = QMainWindow(self)
        # hbox = QHBoxLayout()
        splitter = QSplitter(Qt.Horizontal)

        #显示原始句子的Widght
        widget = QMainWindow(self)
        self.sentenceshow = CommonTableWidget(self)
        # cols = int(widgetWidth/defaultLength) - 1
        # self.setTableWidgetColumns(self.sentenceshow,itemWidth=defaultLength)
        self.sentenceshow.setRowCount(rows)
        self.sentenceshow.setColumnCount(cols)
        self.sentenceshow.verticalHeader().setVisible(False)

        self.sentenceshow.setSelectionMode(QAbstractItemView.MultiSelection)
        self.sentenceshow.setShowGrid(False)
        self.sentenceshow.doubleClicked.connect(
            self.doubleClickedOnTableWidget)

        # self.sentenceshow.columnWidth(defaultLength)
        # self.sentenceshow.setItem(0,0,QTableWidgetItem("dgaghrehrehreherherheeheherher"))

        # self.showSentence("Tim bought Eric a gecko, because he followed him.")

        self.sentenceshow.resizeRowsToContents()
        self.sentenceshow.resizeColumnsToContents()
        self.sentenceshow.setEditTriggers(QAbstractItemView.NoEditTriggers)
        # self.sentenceshow.resize(self.MainWindowWidth,150)
        # self.sentenceshow.setMinimumHeight(100)
        # self.sentenceshow.setMinimumWidth(int(self.MainWindowWidth * 0.8))

        widget.setCentralWidget(self.sentenceshow)
        # self.sentenceshow.addItem("dgagerr")
        self.constantListWidget = ConstantListWidget(self)
        # self.buttonAddSomeWords = QPushButton(self)
        # self.buttonAddSomeWords.setText("确定")
        # self.buttonAddSomeWords.clicked.connect(self.addSomeWords)
        # self.buttonAddSomeWords.resize(self.buttonAddSomeWords.sizeHint())
        splitter.addWidget(widget)
        splitter.addWidget(self.constantListWidget)
        splitter.setStretchFactor(0, 5)
        splitter.setStretchFactor(1, 3)

        # hbox.addWidget(self.buttonAddSomeWords)
        # self.sentencewidget.setLayout(hbox)
        self.sentencewidget.setCentralWidget(splitter)
        # self.sentencewidget.resize(self.MainWindowWidth,300)

        #显示已生成的短语的Widget
        self.typeGroupssplitter = QSplitter(Qt.Horizontal)
        self.verbListwidget = ComListWidget(
            self, "verbTab",
            WidgetType.VERB)  #CommonListWidget(self,"verbTab")
        self.conjunctionwidget = ComListWidget(self, "conjunctionTab",
                                               WidgetType.CONJUNCTION)
        # self.prepositionwidget = ComListWidget(self,"prepositionTab",WidgetType.PREPOSITION)
        # self.nounwidget = ComListWidget(self,"nounTab",WidgetType.NOUN)
        # self.pronounwidget = ComListWidget(self,"pronounTab",WidgetType.PRONOUN)

        self.typeGroupssplitter.addWidget(self.verbListwidget)
        self.typeGroupssplitter.addWidget(self.conjunctionwidget)
        # self.typeGroupssplitter.setFixedHeight(150)
        # self.typeGroupssplitter.addWidget(self.prepositionwidget)
        # self.typeGroupssplitter.addWidget(self.nounwidget)
        # self.typeGroupssplitter.addWidget(self.pronounwidget)

        #用来连接列表框和tab框
        self.listWidgetDictByWidgetType = {
            WidgetType.VERB: "verbListwidget",
            WidgetType.CONJUNCTION: "conjunctionwidget",
            WidgetType.NOUN: "nounwidget"
        }
        # self.typeGroups.addItem("garh")

        #用于设置动词、连词、介词、名词等相应内容的Widget
        self.contentTabs = QTabWidget(self)

        self.verbTab = VerbTabWidget(self)
        self.conjunctionTab = ConjunctionTabWidget(self)
        # self.prepositionTab = QWidget()
        # self.nounTab = BasicTabWidget(self,WidgetType.NOUN)
        # self.pronounTab = QWidget()
        # self.contentTabs.addTab(self.prepositionTab,"介词")
        self.contentTabs.addTab(self.verbTab, "Verbs")
        self.contentTabs.addTab(self.conjunctionTab, "Conjunctions")
        # self.contentTabs.addTab(self.nounTab,"名词")
        # self.contentTabs.addTab(self.pronounTab,"代词")

        self.tabWidgetDictByWidgetType = {
            WidgetType.VERB: "verbTab",
            WidgetType.CONJUNCTION: "conjunctionTab",
            WidgetType.NOUN: "nounTab"
        }

        self.contentTabs.resize(self.MainWindowWidth, 600)

        self.preButton = getButton("Last Sentence",
                                   width=140,
                                   event=self.preButtonClickedEvent)
        self.sureButton = getButton("Save",
                                    width=140,
                                    event=self.sureButtonClickedEvent)
        self.tempSureButton = getButton("Hold",
                                        width=140,
                                        event=self.tempSureButtonClickedEvent)
        self.nextButton = getButton("Next Sentence",
                                    width=140,
                                    event=self.nextButtonClickedEvent)

        self.verticalSplitter = QSplitter(Qt.Vertical)
        self.verticalSplitter.addWidget(self.sentencewidget)
        self.verticalSplitter.addWidget(self.typeGroupssplitter)
        self.verticalSplitter.addWidget(self.contentTabs)
        self.verticalSplitter.addWidget(
            addWidgetInHBoxLayout([
                self.preButton, self.tempSureButton, self.sureButton,
                self.nextButton
            ], True))

        # self.verticalSplitter.addWidget()

        # self.verticalSplitter.setStretchFactor(0,3)
        # self.verticalSplitter.setStretchFactor(1,6)
        # self.verticalSplitter.setStretchFactor(2,5)
        self.setCentralWidget(self.verticalSplitter)

        # self.horizon = QVBoxLayout()

        # self.qbt = QPushButton(self)
        # self.qbt.setText("button")
        # self.qbt.setFixedSize(QSize(50,50))

        # self.qbt1 = QPushButton(self)
        # self.qbt1.setText("button1")
        # self.qbt1.setFixedSize(QSize(50,50))

        # self.qtab = QTabWidget(self)
        # self.qtab.resize(100,100)
        # self.qtab.addTab(self.qbt,"a")
        # self.qtab.addTab(self.qbt1,"b")

        # self.qbt2 = QPushButton(self)
        # self.qbt2.setText("button2")
        # self.qbt2.setFixedSize(QSize(50,50))

        # self.horizon.addWidget(self.qtab)
        # self.horizon.addWidget(self.qbt2)

        # self.setLayout(self.horizon)

        # self.setGeometry(300,300,300,150)
        self.resize(self.MainWindowWidth, 800)
        self.center()
        # self.setWindowFlags(Qt.WindowMinimizeButtonHint|Qt.WindowCloseButtonHint)
        self.show()
        self.run()

    def initializeVariables(self):
        self.currentSentence = None
        self.dataDir = []

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

    def run(self):

        self.sentenceStores = []
        self.storeIndex = 0  #当前值代表待存储的位置,取前一句话要减一,如果变成负的,则表示要从已经标注的文件中取,此次的内存中已经到最前面了
        self.currentSavedFile = None  #当前处理的句子保存到外存中的文件名

        self.currentHandledFile = None
        if not self.dataDir:
            self.sentenceGenerator = self.readFile()

        try:
            self.sentence = self.sentenceGenerator.__next__()
        except StopIteration:
            QMessageBox.information(self, "Prompt",
                                    "Thanking for annotating the whole data.",
                                    QMessageBox.Ok, QMessageBox.Ok)

        self.nextButtonClickedEvent()

    def setTableWidgetColumns(self, table, itemWidth=100, eachWidth=None):
        def setColumns(items):

            for col in items:
                pass

        minWidth = 10
        if eachWidth is None:
            cols = int(self.MainWindowWidth / itemWidth)
            items = [itemWidth] * cols
            diff = self.MainWindowWidth - itemWidth * cols
            if diff >= minWidth:
                items.append(diff)

        setColumns(items)

    def resizeEvent(self, event):
        self.sentenceshow.resize(self.sentencewidget.width(),
                                 self.sentencewidget.height() * 0.8)

    def showSentence(self, sentence=None):
        # row = 0
        # col = 0
        # for word in sentence.split(" "):
        # self.sentenceshow.setItem(row,col,QTableWidgetItem(word+" "))
        # col += 1
        # if col >= self.sentenceshow.columnCount() :
        #     row += 1
        #     col = 0
        # if row >= self.sentenceshow.rowCount() :
        #     self.sentenceshow.insertRow(row)
        if sentence is not None:
            showContentInTableWidget(self.sentenceshow, sentence.split(" "))

    def getSelectedWords(self):
        s = ""
        items = self.sentenceshow.selectedItems()
        items = sorted(items, key=lambda x: (x.row(), x.column()))
        index = None
        if items:
            index = self.sentenceshow.row(
                items[0]) * self.rows + self.sentenceshow.column(items[0]) + 1

            s = "_".join([item.text().strip() for item in items])
            s = s.replace(",", "").replace(".", "").replace("?", "")
        return s, index

    def addSomeWords(self):
        s, index = self.getSelectedWords()
        if s == "":
            return
        isSelected = addWordsToSelectedTextEdit(s, CONSTANT.noItemID, index)
        if isSelected:
            self.sentenceshow.clearSelection()
        # messagecontainer = MessageContainer()
        # selectedRoleContent = messagecontainer.getMessage("selectedRoleContent")
        # if selectedRoleContent is not None :
        #     selectedRoleContent.setText(s)

    def doubleClickedOnTableWidget(self):
        self.addSomeWords()

    def sureButtonClickedEvent(self):
        listWindow = self.conjunctionwidget.listWindow
        count = listWindow.count()
        results = {}
        formalSentences = []
        if count == 1:
            directFlag = True
        else:
            directFlag = False
        for index in range(count):
            item = listWindow.item(index)
            if not (item.checkState() or directFlag):
                continue
            lexicon = searchLexiconByID(item.itemID)

            print("string ", lexicon.getFormatString())
            # continue
            if lexicon is None:
                print("not found")
                continue
            lexicon.getFormat(results, [])
            formalSentences.append(lexicon.getFormatString())

        # print("results ",results)
        if results:
            results['formalSentences'] = formalSentences
            results['rawSentence'] = self.currentSentence

            sentenceMD5 = hashlib.md5(
                self.currentSentence.encode("utf-8")).hexdigest()
            sentenceSHA1 = hashlib.sha1(
                self.currentSentence.encode("utf-8")).hexdigest()
            filename = "result/{}.xml".format(sentenceMD5 + sentenceSHA1)
            # flag = True
            # if filename not in self.multifiles['hashFile'].tolist() :
            #     print("not exists")
            #     pass
            # else:
            #     if self.currentSentence in self.multifiles['sentence'].tolist() :
            #         filename = self.multifiles.loc[self.multifiles['sentence']==self.currentSentence]['hashFile'].tolist()[0]
            #         print("exists")
            #         flag = False
            #     else:
            #         filename += str(int(time.time()))
            # if flag :
            #     self.multifiles = self.multifiles.append(pd.Series({"sentence":self.currentSentence,"hashFile":filename}),ignore_index=True)
            #     self.multifiles.to_csv("res/sentenceFileMap.csv")
            self.checkDefault(filename)
            # print("results   ",results)
            results['filename'] = filename
            self.currentSavedFile = filename
            if writeFile(results):
                open("usedDatas/{}".format(self.currentHandledFile),
                     'a+').write(self.currentSentence + "\n")
            else:
                QMessageBox.warning(
                    self, "Warning",
                    "Please you have annotated all necessary information.",
                    QMessageBox.Ok, QMessageBox.Ok)

        else:
            QMessageBox.warning(
                self, "Warning",
                "Please choose a semantic representation in Conjunction form to save.",
                QMessageBox.Ok, QMessageBox.Ok)

    def checkUsingPandas(self, filename):
        flag = True
        if filename not in self.multifiles['hashFile'].tolist():
            print("not exists")
            pass
        else:
            if self.currentSentence in self.multifiles['sentence'].tolist():
                filename = self.multifiles.loc[
                    self.multifiles['sentence'] ==
                    self.currentSentence]['hashFile'].tolist()[0]
                print("exists")
                flag = False
            else:
                filename += str(int(time.time()))
        if flag:
            self.multifiles = self.multifiles.append(pd.Series({
                "sentence":
                self.currentSentence,
                "hashFile":
                filename
            }),
                                                     ignore_index=True)
            self.multifiles.to_csv("res/sentenceFileMap.csv")

    def checkDefault(self, filename):
        flag = True
        if filename not in self.multifiles['hashFile']:
            print("not exists")
            pass
        else:
            if self.currentSentence in self.multifiles['sentence']:
                index = self.multifiles['sentence'].index(self.currentSentence)
                filename = self.multifiles['hashFile'][index]
                print("exists")
                flag = False
            else:
                filename += str(int(time.time()))
        if flag:
            self.multifiles['sentence'] = self.currentSentence
            self.multifiles['hashFile'] = filename
            open(self.sentenceFilePair,
                 'a+').write(self.currentSentence + "\t" + filename + "\n")

    def tempSureButtonClickedEvent(self):
        if self.currentSentence not in self.sentencesNotSure:
            self.sentencesNotSure.append(self.currentSentence)
            open(self.notsureFile, 'a+').write(self.currentSentence + "\n")
            #需要检查暂存中的是否已经标注过了
        self.currentSavedFile = None
        self.nextButtonClickedEvent()

    def preButtonClickedEvent(self):

        # self.storeIndex = 1
        self.storeIndex -= 1

        if self.storeIndex < 0:
            QMessageBox.warning(self, "Warning", "No sentences")
            self.storeIndex = 0
        else:
            if self.storeIndex >= len(self.sentenceStores):
                print(
                    "wrong in get data from sentenceStores for out of the length"
                )
                QMessageBox.warning(self, "Warning", "Can not get a sentence")
                return
            sentence = self.sentenceStores[self.storeIndex]
            # sentence = ["agaerwgew","result/32c7dd219ea12a810e94aa221cb1e583c458e366a2e692ca92829f095c07459420e33d19.xml"]
            self.showPreviousSentence(sentence)
        self.sentenceStores.append(
            (self.currentSentence, self.currentSavedFile))

    def showPreviousSentence(self, sentence):
        def verbWidgetInitialize(widgetIndex,
                                 verb,
                                 signalEmit=True,
                                 Datas=None):
            '''
                从XML文件中恢复动词widget内容
            '''
            widget = self.verbTab.tabWindow.widget(widgetIndex)
            widget.verbContent.setText(verb[0])
            roles = []
            contents = []
            for role in verb[1]:
                roles.append(role[0])
                contents.append(role[1])
            print(contents)
            if Datas is not None:
                ref = Datas['variables'] if "variables" in Datas else None
                widget.updateRoleLabel(roles, contents=contents, ref=ref)
            else:
                widget.updateRoleLabel(roles, contents=contents)
            attrib = verb[2]
            if "belong" in attrib:
                widget.belong = attrib['belong']
            if "isleft" in attrib:
                widget.isleft = attrib['isleft']
            if "indexOfPlace" in attrib:
                print("indexOfPlace ", attrib['indexOfPlace'],
                      type(attrib['indexOfPlace']))
                widget.setMainWordIndexOfPlace(attrib['indexOfPlace'])
            if "isNegative" in attrib:
                widget.isNegative = attrib['isNegative'] == "True"
            if len(verb) >= 4:
                widget.originVerb = verb[3]
            if signalEmit:
                widget.buttonSaver.clicked.emit()

        # def AddVerbWidget(verbs):
        #     verbIndex = 0
        #     for widgetIndex in range(self.verbTab.tabWindow.count()-1) :
        #         print(widgetIndex)
        #         verbWidgetInitialize(widgetIndex,verbs[verbIndex])
        #         verbIndex += 1

        #     if verbIndex < len(verbs) :
        #         N = len(verbs)-verbIndex
        #         for _ in range(N) :
        #             self.verbTab.addTab()
        #             widgetIndex = self.verbTab.tabWindow.count()-2
        #             verbWidgetInitialize(widgetIndex,verbs[verbIndex])
        #             verbIndex += 1

        def conjunctionWidgetInitialize(widgetIndex,
                                        conjunction,
                                        signalEmit=True):
            widget = self.conjunctionTab.tabWindow.widget(widgetIndex)
            widget.initializeContents(conjunction, self.verbListwidget)
            print("set conjunction")

        def AddWidgets(datas, attrib, Datas=None):
            obj = getattr(self, attrib)
            index = 0
            for widgetIndex in range(obj.tabWindow.count() - 1):
                print(widgetIndex)
                if attrib == "verbTab":
                    verbWidgetInitialize(widgetIndex,
                                         datas[index],
                                         Datas=Datas)
                elif attrib == "conjunctionTab":
                    conjunctionWidgetInitialize(widgetIndex, datas[index])
                index += 1

            if index < len(datas):
                N = len(datas) - index
                for _ in range(N):
                    if attrib == "verbTab":
                        self.verbTab.addTab()
                        widgetIndex = obj.tabWindow.count() - 2
                        verbWidgetInitialize(widgetIndex,
                                             datas[index],
                                             Datas=Datas)
                    elif attrib == "conjunctionTab":
                        widgetIndex = obj.tabWindow.count() - 2
                        conjunctionWidgetInitialize(widgetIndex, datas[index])

                    index += 1

        self.showSentence(sentence[0])

        if sentence[1] is not None:
            results = extractXMLData(sentence[1])

            if results is None:
                self.resetWidget()
                return

            print(results)
            self.resetWidget()
            print("count ", self.verbTab.tabWindow.count())
            # AddVerbWidget(results['verbs'])
            # AddConjunctionWidget(results['conjunctions'])
            AddWidgets(results['verbs'], "verbTab", results)
            AddWidgets(results['conjunctions'], "conjunctionTab")
        else:
            self.resetWidget()

    def nextButtonClickedEvent(self):
        def getNextSentence():
            if self.currentSentence is not None:
                self.sentenceStores.append(
                    (self.currentSentence, self.currentSavedFile))
                self.currentSavedFile = None
                self.storeIndex += 1
            sentence = self.sentence.__next__()
            print("sentence ", sentence, "  currentsavedfile ",
                  self.currentSavedFile)
            self.currentSentence = self.wordsFilter(sentence)
            self.showSentence(self.currentSentence)
            self.resetWidget()

        try:
            if self.storeIndex >= len(self.sentenceStores):
                # if self.currentSentence is not None :
                #     self.sentenceStores.append((self.currentSentence,self.currentSavedFile))
                #     self.currentSavedFile = None
                #     self.storeIndex += 1
                # sentence = self.sentence.__next__()
                # self.currentSentence = self.wordsFilter(sentence)
                # self.showSentence(self.currentSentence)
                # self.resetWidget()
                getNextSentence()
            else:
                self.storeIndex += 1
                # print("current store index ",self.storeIndex)
                # print("length of sentenceStores ",len(self.sentenceStores))
                if self.storeIndex < len(self.sentenceStores):
                    self.showPreviousSentence(
                        self.sentenceStores[self.storeIndex])
                else:
                    getNextSentence()
        except StopIteration:
            self.run()

    def readFile(self):
        def read(filename, exists=False):
            if exists:
                try:
                    with open("usedDatas/{}".format(filename)) as f:
                        sentences = f.read().strip().split("\n")
                    print("exists sentences ", sentences)
                except Exception:
                    pass
            else:
                sentences = []
            with open("datas/{}".format(filename), 'r', encoding='utf-8') as f:
                for line in f:
                    line = line.strip()
                    line = self.wordsFilter(line)
                    if line in sentences or line in self.sentencesNotSure:
                        continue
                    yield line

        if not os.path.exists("datas/"):
            return
        if not os.path.exists("usedDatas"):
            os.mkdir("usedDatas")
        dataDir = os.listdir("datas")
        self.dataDir = list(dataDir)
        usedDataDir = os.listdir("usedDatas")
        for filename in dataDir:
            self.currentHandledFile = filename
            self.resetResFile()
            if filename not in usedDataDir:
                yield read(filename)
            else:
                yield read(filename, True)

        # print(dataDir,usedDataDir)

    def wordsFilter(self, sentence):
        sentence = re.sub(r'\d+\.\s+', "", sentence)
        return sentence

    def resetResFile(self):
        def readSentenceFileMap(filename):
            try:
                with open(filename, 'r') as f:
                    contents = {'sentence': [], "hashFile": []}
                    for line in f:
                        arr = line.strip().split("\t")
                        contents['sentence'].append(arr[0])
                        contents['hashFile'].append(arr[1])

                    return contents
            except Exception:
                QMessageBox.warning(self, "Error",
                                    "Error when reading configure files")
                traceback.print_exc()

        def read(filename):
            try:
                with open(filename, 'r') as f:
                    contents = []
                    for line in f:
                        contents.append(line.strip())
                    return contents
            except Exception:
                QMessageBox.warning(self, "Error",
                                    "Error when reading configure files")
                traceback.print_exc()

        filename = re.sub(r'\.txt', "", self.currentHandledFile)

        # filename = "res/sentenceFileMap.csv"
        # filename = "res/sentenceFileMap.txt"
        self.sentenceFilePair = "res/{}_sentence_file_pair.txt".format(
            filename)
        if not os.path.exists(self.sentenceFilePair):
            # self.multifiles = pd.DataFrame({"sentence":[],"hashFile":[]})
            self.multifiles = {"sentence": [], "hashFile": []}
        else:
            # self.multifiles = pd.read_csv(filename,index_col=0)
            self.multifiles = readSentenceFileMap(self.sentenceFilePair)
        # print(self.multifiles)
        # print(self.multifiles.loc[self.multifiles['hashFile']=="result/a.xml"]['sentence'].tolist())

        self.notsureFile = "res/{}_notsure.txt".format(filename)
        if not os.path.exists(self.notsureFile):
            self.sentencesNotSure = []
        else:
            self.sentencesNotSure = read(self.notsureFile)
        # print(self.sentencesNotSure)

    def resetWidget(self):
        self.verbListwidget.resetWidget()
        self.conjunctionwidget.resetWidget()
        self.verbTab.resetWidget()
        self.conjunctionTab.resetWidget()
        self.conjunctionTab.addTab()
        self.verbTab.addTab()
        self.contentTabs.setCurrentIndex(0)
Exemple #9
0
#        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
#        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton.setText(_translate("MainWindow", "确认评分"))
        self.label_3.setText(_translate("MainWindow", "考试科目:"))
        self.label.setText(_translate("MainWindow", "考生姓名:"))
        self.label_2.setText(_translate("MainWindow", "准考证号:"))
        self.pushButton_2.setText(_translate("MainWindow", "申请重新评分"))
        self.comboBox.setItemText(0, _translate("MainWindow", "考官1"))
        self.comboBox.setItemText(1, _translate("MainWindow", "考官2"))
        self.comboBox.setItemText(2, _translate("MainWindow", "考官3"))
        self.comboBox.setItemText(3, _translate("MainWindow", "考官4"))
        self.comboBox.setItemText(4, _translate("MainWindow", "考官5"))


if __name__ == '__main__':
    app = QApplication(sys.argv)
    MainWindow = QMainWindow()
    ui = Ui_MainWindow2()
    ui.setupUi(MainWindow)
    MainWindow.show()
    MainWindow.setFixedSize(MainWindow.width(), MainWindow.height())
    sys.exit(app.exec_())
Exemple #10
0
class MainWindow(Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.main_window = QMainWindow()
        self.setupUi(self.main_window)
        self.main_window.setFixedSize(self.main_window.width(), self.main_window.height())
        self.msg = QMessageBox()
        self.qr = self.main_window.frameGeometry()  # move to center of screen
        self.cp = QDesktopWidget().availableGeometry().center()
        self.qr.moveCenter(self.cp)
        self.main_window.move(self.qr.topLeft())
        self.text_edit_urls.setAcceptRichText(False)

        self.config = QSettings('config.ini', QSettings.IniFormat)
        self.init_config()
        self.set_slot()

    def init_config(self):
        # 读取设置
        mconfig.set_file_path(self.config.value(mconfig.file_path, mconfig.base_dir))
        enable_proxy = self.config.value('enable_proxy', False)

        # 界面更新
        self.file_path_label.setText(mconfig.get_file_path())
        self.proxy_checkBox.setChecked(s2b(enable_proxy))

    def set_slot(self):
        self.button_download.clicked.connect(self.get_info)
        self.check_update_button.clicked.connect(self.check_for_updates)
        self.about_button.clicked.connect(self.show_about)
        self.set_path_button.clicked.connect(self.set_file_path)
        self.set_proxy_button.clicked.connect(self.show_proxy_dialog)

        self.proxy_checkBox.stateChanged.connect(self.save_config)

        self.action_about.triggered.connect(self.show_about)
        self.action_file_path.triggered.connect(self.set_file_path)
        self.action_check_for_updates.triggered.connect(self.check_for_updates)
        self.action_report_bugs.triggered.connect(self.report_bugs)
        self.action_supported_sites.triggered.connect(self.get_supported_sites)

    def get_supported_sites(self):
        QDesktopServices.openUrl(QUrl('https://github.com/ingbyr/GUI-YouGet/wiki/Supported-Sites'))

    def get_info(self):
        mconfig.set_default()
        set_default()
        clear_buffer()

        self.button_download.setEnabled(False)
        self.urls = (str(self.text_edit_urls.toPlainText())).split(';')
        mlog.debug(self.urls[0])

        self.m_thread = GetVideoInfoThread(self.urls, **mconfig.kwargs)
        self.m_thread.finish_signal.connect(self.finish_get_info)
        self.m_thread.start()

    def finish_get_info(self, ls, can_download):
        mlog.debug('finish_get_info: ' + str(can_download))
        self.button_download.setEnabled(True)
        if can_download:
            self.files_list_dialog = FilesListDialog()
            self.files_list_dialog.update_files_list(ls)
            mconfig.set_urls(self.urls)
        else:
            # self.show_msg(QMessageBox.Critical, 'Failed ', 'Can not get the files list (╯°Д°)╯︵ ┻━┻')
            self.show_msg(QMessageBox.Critical, 'Failed ', ls)

    def show_about(self):
        mlog.debug('show about widget')
        self.about_widget = AboutWdiget()
        self.about_widget.about_widget.move(self.qr.topLeft())
        self.about_widget.about_widget.show()

    def set_file_path(self):
        fname = QFileDialog.getExistingDirectory(self.main_window, caption='Select Path', directory='',
                                                 options=QFileDialog.ShowDirsOnly)
        if fname:
            self.config.setValue(mconfig.file_path, fname)
            self.file_path_label.setText(fname)
            set_file_path(fname)
            mlog.debug('changed file path to ' + mconfig.get_file_path())
        else:
            set_file_path(mconfig.base_dir)
            self.file_path_label.setText(mconfig.base_dir)
            self.config.setValue(mconfig.file_path, mconfig.base_dir)

    def show_msg(self, icon, title, text):
        self.msg.setWindowTitle(title)
        self.msg.setWindowIcon(QIcon(':/res/favicon.ico'))
        self.msg.setIcon(icon)
        self.msg.setText(text)
        self.msg.setStandardButtons(QMessageBox.Ok)
        self.msg.show()

    def check_for_updates(self):
        try:
            with request.urlopen('https://raw.githubusercontent.com/ingbyr/GUI-YouGet/master/version.json') as f:
                raw_inf = str(f.read())[2:-1]
                mlog.debug(str(f.read())[2:-1])
                remote_inf = json.loads(raw_inf)
                mlog.debug('remote version is ' + remote_inf['version'])
        except Exception as e:
            mlog.exception(e)
            self.show_msg(QMessageBox.Critical, 'Failed', 'Check for updates failed')
            return

        if mconfig.version >= remote_inf['version']:
            self.show_msg(QMessageBox.Information, 'Check for updates', 'No available updates')
        else:
            self.show_msg(QMessageBox.Information, 'Check for updates', 'There is a new version')
            self.do_updates()

    def do_updates(self):
        QDesktopServices.openUrl(QUrl('https://github.com/ingbyr/GUI-YouGet/releases'))

    def report_bugs(self):
        QDesktopServices.openUrl(QUrl('https://github.com/ingbyr/GUI-YouGet/issues'))

    def get_more_infomation(self):
        QDesktopServices.openUrl(QUrl('https://github.com/ingbyr/GUI-YouGet'))

    def show_proxy_dialog(self):
        self.proxy_dialog = ProxyDialog()

    def save_config(self):
        enable_proxy = self.proxy_checkBox.isChecked()
        self.config.setValue('enable_proxy', enable_proxy)
        is_http_proxy = self.config.value('is_http_proxy')
        is_socks_proxy = self.config.value('is_socks_proxy')

        if is_http_proxy is None or is_socks_proxy is None:
            self.show_proxy_dialog()
Exemple #11
0
class MainWindow(Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.main_window = QMainWindow()
        self.setupUi(self.main_window)
        self.main_window.setFixedSize(self.main_window.width(),
                                      self.main_window.height())
        self.msg = QMessageBox()
        self.set_slot()
        self.qr = self.main_window.frameGeometry()  # move to center of screen
        self.cp = QDesktopWidget().availableGeometry().center()
        self.qr.moveCenter(self.cp)
        self.main_window.move(self.qr.topLeft())
        self.text_edit_urls.setAcceptRichText(False)

    def set_slot(self):
        self.button_download.clicked.connect(self.get_info)
        self.action_about.triggered.connect(self.show_about)
        self.action_file_path.triggered.connect(self.set_file_path)
        self.action_check_for_updates.triggered.connect(self.check_for_updates)
        self.action_report_bugs.triggered.connect(self.report_bugs)

    def get_info(self):
        mconfig.set_default()
        self.button_download.setEnabled(False)
        self.urls = (str(self.text_edit_urls.toPlainText())).split(';')
        mlog.debug(self.urls[0])

        self.m_thread = GetVideoInfoThread(self.urls, **mconfig.kwargs)
        self.m_thread.finish_signal.connect(self.finish_get_info)
        self.m_thread.start()

    def finish_get_info(self, ls, can_download):
        mlog.debug('finish_get_info: ' + str(can_download))
        self.button_download.setEnabled(True)
        if can_download:
            self.files_list_dialog = FilesListDialog()
            self.files_list_dialog.update_files_list(ls)
            mconfig.set_urls(self.urls)
        else:
            self.show_msg(QMessageBox.Critical, 'Failed ',
                          'Can not get the files list (╯°Д°)╯︵ ┻━┻')

    def show_about(self):
        mlog.debug('show about widget')
        self.about_widget = AboutWdiget()
        self.about_widget.about_widget.move(self.qr.topLeft())
        self.about_widget.about_widget.show()

    def set_file_path(self):
        fname = QFileDialog.getExistingDirectory(
            self.main_window,
            caption='Select Path',
            directory='',
            options=QFileDialog.ShowDirsOnly)
        if fname:
            mconfig.set_file_path(fname)
            mlog.debug('changed file path to ' + mconfig.get_file_path())
            self.show_msg(QMessageBox.Information, 'Tip',
                          'Changed file path to:\n' + str(fname))
        else:
            mconfig.set_file_path(mconfig.base_dir)
            self.show_msg(QMessageBox.Information, 'Tip',
                          'Default file path:\n' + str(mconfig.base_dir))

    def show_msg(self, icon, title, text):
        self.msg.setWindowTitle(title)
        self.msg.setIcon(icon)
        self.msg.setText(text)
        self.msg.setStandardButtons(QMessageBox.Ok)
        self.msg.show()

    def check_for_updates(self):
        mlog.debug('check_for_updates')
        try:
            with request.urlopen(
                    'https://raw.githubusercontent.com/ingbyr/GUI-YouGet/master/version.json'
            ) as f:
                raw_inf = str(f.read())[2:-1]
                mlog.debug(str(f.read())[2:-1])
                remote_inf = json.loads(raw_inf)
                mlog.debug('remote version is ' + remote_inf['version'])
        except Exception:
            for item in sys.exc_info():
                mlog.error(str(item))
                self.show_msg(QMessageBox.Critical, 'Failed',
                              'Check for updates failed')
            return

        if mconfig.version >= remote_inf['version']:
            self.show_msg(QMessageBox.Information, 'Check for updates',
                          'No available updates')
        else:
            self.show_msg(QMessageBox.Information, 'Check for updates',
                          'There is a new version')
            self.do_updates()

    def do_updates(self):
        QDesktopServices.openUrl(
            QUrl('http://www.ingbyr.tk/2016/05/16/youget/'))

    def report_bugs(self):
        QDesktopServices.openUrl(
            QUrl('https://github.com/ingbyr/GUI-YouGet/issues'))
class AnimateXY(AbstractTool):
    def __init__(self, parent):
        super(AnimateXY, self).__init__(parent)
        self._name = "Animate X-Y"
        self._parent = parent
        self._filename = ""
        self._settings = {}

        # --- Initialize the GUI --- #
        self._animateWindow = QMainWindow()
        self._animateGUI = Ui_Animate()
        self._animateGUI.setupUi(self._animateWindow)

        self._animateGUI.buttonBox.accepted.connect(self.callback_apply)
        self._animateGUI.buttonBox.rejected.connect(self._animateWindow.close)

        self._has_gui = True
        self._need_selection = True
        self._min_selections = 1
        self._max_selections = 3
        self._redraw_on_exit = False

    def apply_settings(self):
        self._settings["local"] = self._animateGUI.radioButton.isChecked()
        self._settings["global"] = self._animateGUI.radioButton_2.isChecked()
        self._settings["lim"] = float(self._animateGUI.lim.text())
        self._settings["fps"] = int(self._animateGUI.fps.text())

    @staticmethod
    def get_bunch_in_local_frame(datasource, step):
        x = np.array(datasource["Step#{}".format(step)]["x"])
        y = np.array(datasource["Step#{}".format(step)]["y"])
        x_mean = np.mean(x)
        y_mean = np.mean(y)

        px_mean = np.mean(np.array(datasource["Step#{}".format(step)]["px"]))
        py_mean = np.mean(np.array(datasource["Step#{}".format(step)]["py"]))

        theta = np.arccos(py_mean /
                          np.sqrt(np.square(px_mean) + np.square(py_mean)))

        if px_mean < 0:
            theta = -theta

        # Center the beam
        x -= x_mean
        y -= y_mean

        # Rotate the beam and return
        temp_x = x
        temp_y = y

        return temp_x * np.cos(theta) - temp_y * np.sin(
            theta), temp_x * np.sin(theta) + temp_y * np.cos(theta)

    def callback_apply(self):
        self.apply_settings()
        self._animateWindow.close()
        self.run_animation()

    def run_animation(self):

        self._parent.send_status("Setting up animation...")

        plt.rc('font', **{'family': 'serif', 'serif': ['Computer Modern']})
        plt.rc('text', usetex=True)
        plt.rc('grid', linestyle=':')

        animate_all = []

        for dataset in self._selections:

            # dataset = self._selections[0]
            datasource = dataset.get_datasource()
            nsteps = dataset.get_nsteps()

            # TODO: Total hack, but I want to tag certain particles RIGHT NOW -DW
            # tag_step = 568
            # tag_y_lim = 5.0 * 1.0e-3  # m
            # _x, _y = self.get_bunch_in_local_frame(datasource, tag_step)
            # tag_idx = np.where(_y >= tag_y_lim)
            # pids = np.array(datasource["Step#{}".format(tag_step)]["id"][tag_idx])

            animate = {}

            for step in range(nsteps):

                animate["Step#{}".format(step)] = {
                    "x": np.array(datasource["Step#{}".format(step)]["x"]),
                    "y": np.array(datasource["Step#{}".format(step)]["y"]),
                    "id": np.array(datasource["Step#{}".format(step)]["id"])
                }

                if self._settings["local"]:

                    animate["Step#{}".format(step)]["x"], animate["Step#{}".format(step)]["y"] = \
                        self.get_bunch_in_local_frame(datasource, step)

            animate_all.append(animate)

        n_ds = len(animate_all)

        # Handle animations
        # fig = plt.figure()
        fig, ax = plt.subplots(1, n_ds)
        if n_ds == 1:
            ax = [ax]

        lines = []

        j = 0
        for _ax in ax:
            _ax.set_xlim(-self._settings["lim"], self._settings["lim"])
            _ax.set_ylim(-self._settings["lim"], self._settings["lim"])

            # ax = plt.axes(xlim=(-self._settings["lim"], self._settings["lim"]),
            #               ylim=(-self._settings["lim"], self._settings["lim"]))

            line1, = _ax.plot([], [], 'ko', ms=0.1, alpha=0.8)
            # line2, = ax.plot([], [], 'ko', ms=0.1, alpha=0.8, color='red')  # Tagging

            lines.append(line1)

            # plt.grid()
            _ax.grid()

            _ax.set_aspect('equal')

            if self._settings["local"]:
                _ax.set_xlabel("Horizontal (mm)")
                _ax.set_ylabel("Longitudinal (mm)")
            else:
                _ax.set_xlabel("X (mm)")
                _ax.set_ylabel("Y (mm)")

            _ax.set_title(r"{}: Step \#0".format(
                self._selections[j].get_name()))
            _ax.get_xaxis().set_major_locator(LinearLocator(numticks=13))
            _ax.get_yaxis().set_major_locator(LinearLocator(numticks=13))

            plt.tight_layout()

            j += 1

        def init():
            for _line in lines:
                _line.set_data([], [])
            # line2.set_data([], [])
            return lines,  # line2,

        def update(i):

            k = 0
            for _animate, _line in zip(animate_all, lines):

                # tags = np.isin(animate["Step#{}".format(i)]["id"], pids)
                tags = np.zeros(len(_animate["Step#{}".format(i)]["x"]),
                                dtype=bool)

                # Regular Data
                x = 1000.0 * _animate["Step#{}".format(i)]["x"][np.invert(
                    tags.astype(bool))]
                y = 1000.0 * _animate["Step#{}".format(i)]["y"][np.invert(
                    tags.astype(bool))]

                # Tagged Data
                xt = 1000.0 * _animate["Step#{}".format(i)]["x"][tags.astype(
                    bool)]
                yt = 1000.0 * _animate["Step#{}".format(i)]["y"][tags.astype(
                    bool)]

                _line.set_data(x, y)
                # line2.set_data(xt, yt)

                ax[k].set_title(r"{}: Step \#{}".format(
                    self._selections[k].get_name(), i))
                k += 1

            completed = int(100 * (i / (nsteps - 1)))
            self._parent.send_status(
                "Animation progress: {}% complete".format(completed))

            # return line1, line2, ax
            return lines, ax

        ani = animation.FuncAnimation(fig,
                                      update,
                                      frames=nsteps,
                                      init_func=init,
                                      repeat=False)

        # Save animation
        writer1 = animation.writers['ffmpeg']
        writer2 = writer1(fps=self._settings["fps"], bitrate=1800)
        ani.save(self._filename[0] + ".mp4", writer=writer2)
        ani._stop()
        self._parent.send_status("Animation saved successfully!")

    def run(self):
        # --- Calculate the positions to center the window --- #
        screen_size = self._parent.screen_size()
        _x = 0.5 * (screen_size.width() - self._animateWindow.width())
        _y = 0.5 * (screen_size.height() - self._animateWindow.height())

        # --- Show the GUI --- #
        self._animateWindow.show()
        self._animateWindow.move(_x, _y)

    def open_gui(self):

        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog

        self._filename = QFileDialog.getSaveFileName(
            caption="Saving animation...",
            options=options,
            filter="Video (*.mp4)")

        self.run()
class GeneratorGUI(object):
    def __init__(self, parent):
        self._parent = parent

        # Initialize GUI
        self._generate_main = QMainWindow()
        self._generate_mainGUI = Ui_Generate_Main()
        self._generate_mainGUI.setupUi(self._generate_main)
        self._generate_envelope = QMainWindow()
        self._generate_envelopeGUI = Ui_Generate_Envelope()
        self._generate_envelopeGUI.setupUi(self._generate_envelope)
        self._generate_twiss = QMainWindow()
        self._generate_twissGUI = Ui_Generate_Twiss()
        self._generate_twissGUI.setupUi(self._generate_twiss)
        self._generate_error = QMainWindow()
        self._generate_errorGUI = Ui_Generate_Error()
        self._generate_errorGUI.setupUi(self._generate_error)

        # Connect buttons and signals
        self._settings = {}
        self.apply_settings_main()
        self._generate_mainGUI.buttonBox.accepted.connect(self.callback_ok_main)
        self._generate_mainGUI.buttonBox.rejected.connect(self._generate_main.close)
        self._generate_envelopeGUI.buttonBox.accepted.connect(self.callback_ok_envelope)
        self._generate_envelopeGUI.buttonBox.rejected.connect(self._generate_envelope.close)
        self._generate_twissGUI.buttonBox.accepted.connect(self.callback_ok_twiss)
        self._generate_twissGUI.buttonBox.rejected.connect(self._generate_twiss.close)
        self._generate_errorGUI.buttonBox.accepted.connect(self._generate_error.close)
        self._generate_envelopeGUI.zpos.currentIndexChanged.connect(self.change_zpos_envelope)
        self._generate_envelopeGUI.zmom.currentIndexChanged.connect(self.change_zmom_envelope)
        self._generate_envelopeGUI.xydist.currentIndexChanged.connect(self.change_xy_envelope)
        self._generate_twissGUI.zpos.currentIndexChanged.connect(self.change_zpos_twiss)
        self._generate_twissGUI.zmom.currentIndexChanged.connect(self.change_zmom_twiss)
        self._generate_twissGUI.xydist.currentIndexChanged.connect(self.change_xy_twiss)
        self._generate_envelopeGUI.checkBox.stateChanged.connect(self.sym_envelope)
        self._generate_twissGUI.checkBox.stateChanged.connect(self.sym_twiss)

        self.data = {}

    def apply_settings_main(self):

        # Number of particles:
        self._settings["numpart"] = self._generate_mainGUI.lineEdit.text()

        # Species:
        info = str(self._generate_mainGUI.comboBox.currentText())
        if info == "Proton":
            self._settings["species"] = "proton"
        elif info == "Electron":
            self._settings["species"] = "electron"
        elif info == "Dihydrogen cation":
            self._settings["species"] = "H2_1+"
        elif info == "Alpha particle":
            self._settings["species"] = "4He_2+"

        # Energy:
        self._settings["energy"] = self._generate_mainGUI.energy.text()

        # Input parameter type:
        self._settings["type"] = str(self._generate_mainGUI.comboBox_2.currentText())

    def apply_settings_envelope(self):
        # Longitudinal parameters
        self._settings["zpos"] = str(self._generate_envelopeGUI.zpos.currentText())
        self._settings["zmom"] = str(self._generate_envelopeGUI.zmom.currentText())
        self._settings["ze"] = self._generate_envelopeGUI.ze.text()
        self._settings["zr"] = self._generate_envelopeGUI.zr.text()
        self._settings["zstddev"] = [self._generate_envelopeGUI.zpstddev.text(),
                                     self._generate_envelopeGUI.zmstddev.text()]

        # Transverse parameters
        self._settings["xydist"] = str(self._generate_envelopeGUI.xydist.currentText())
        self._settings["eps"] = [self._generate_envelopeGUI.xe.text(), self._generate_envelopeGUI.ye.text()]
        self._settings["r"] = [self._generate_envelopeGUI.xr.text(), self._generate_envelopeGUI.yr.text()]
        self._settings["rp"] = [self._generate_envelopeGUI.xrp.text(), self._generate_envelopeGUI.yrp.text()]
        self._settings["xystddev"] = [self._generate_envelopeGUI.xstddev.text(),
                                      self._generate_envelopeGUI.xpstddev.text(),
                                      self._generate_envelopeGUI.ystddev.text(),
                                      self._generate_envelopeGUI.ypstddev.text()]

    def apply_settings_twiss(self):

        # Convert from Twiss to envelope
        zp_beta = self._generate_twissGUI.zpb.text()
        ze = self._generate_twissGUI.ze.text()

        if zp_beta != "" and ze != "":
            zp_beta = float(zp_beta)
            ze = float(ze)
            rz = np.sqrt(zp_beta * ze)
        else:
            rz = float(self._generate_twissGUI.length.text())

        xa = float(self._generate_twissGUI.xa.text())
        xb = float(self._generate_twissGUI.xb.text())
        xe = float(self._generate_twissGUI.xe.text())

        rx = np.sqrt(xb * xe)
        rxp = -xa * rx / xb

        ya = float(self._generate_twissGUI.ya.text())
        yb = float(self._generate_twissGUI.yb.text())
        ye = float(self._generate_twissGUI.ye.text())

        ry = np.sqrt(yb * ye)
        ryp = -ya * ry / yb

        # Longitudinal parameters
        self._settings["zpos"] = str(self._generate_twissGUI.zpos.currentText())
        self._settings["zmom"] = str(self._generate_twissGUI.zmom.currentText())
        self._settings["ze"] = ze
        self._settings["zr"] = rz
        self._settings["zstddev"] = [self._generate_envelopeGUI.zpstddev.text(),
                                     self._generate_envelopeGUI.zmstddev.text()]

        # Transverse parameters
        self._settings["xydist"] = str(self._generate_twissGUI.xydist.currentText())
        self._settings["eps"] = [xe, ye]
        self._settings["r"] = [rx, ry]
        self._settings["rp"] = [rxp, ryp]
        if self._generate_twissGUI.xydist.currentText() == "Gaussian":
            self._settings["xystddev"] = [self._generate_twissGUI.xstddev.text(),
                                          self._generate_twissGUI.xpstddev.text(),
                                          self._generate_twissGUI.ystddev.text(),
                                          self._generate_twissGUI.ypstddev.text()]

    def callback_ok_main(self):
        self.apply_settings_main()
        if self._settings["numpart"] == "" or self._settings["energy"] == "":
            self.run_error()
        else:
            # Open either Twiss or Envelope menu
            if self._settings["type"] == "Envelope":
                self.run_envelope()
            elif self._settings["type"] == "Twiss":
                self.run_twiss()
            self._generate_main.close()

    def callback_ok_envelope(self):
        self.apply_settings_envelope()
        if self._settings["eps"] == ["", ""] or self._settings["r"] == ["", ""] or self._settings["rp"] == ["", ""]:
            self.run_error()
        else:
            if self._settings["zpos"] == "Constant" and self._settings["zmom"] == "Constant":
                g = GenerateDistribution(self._settings["numpart"], self._settings["species"],
                                         self._settings["energy"], self._settings["zpos"], self._settings["zmom"],
                                         self._settings["zr"])
            elif self._settings["zpos"] == "Gaussian on ellipse" or self._settings["zmom"] == "Gaussian on ellipse":
                g = GenerateDistribution(self._settings["numpart"], self._settings["species"],
                                         self._settings["energy"], self._settings["zpos"], self._settings["zmom"],
                                         self._settings["zr"], self._settings["ze"],
                                         self._settings["zstddev"])
            else:
                g = GenerateDistribution(self._settings["numpart"], self._settings["species"],
                                         self._settings["energy"], self._settings["zpos"], self._settings["zmom"],
                                         self._settings["zr"], self._settings["ze"])
            if self._settings["xydist"] == "Uniform":
                self.data = g.generate_uniform(self._settings["r"], self._settings["rp"], self._settings["eps"])
            elif self._settings["xydist"] == "Gaussian":
                self.data = g.generate_gaussian(self._settings["r"], self._settings["rp"], self._settings["eps"],
                                                self._settings["xystddev"])
            elif self._settings["xydist"] == "Waterbag":
                self.data = g.generate_waterbag(self._settings["r"], self._settings["rp"], self._settings["eps"])
            elif self._settings["xydist"] == "Parabolic":
                self.data = g.generate_parabolic(self._settings["r"], self._settings["rp"], self._settings["eps"])
            self._generate_envelope.close()
            self._parent.add_generated_dataset(data=self.data, settings=self._settings)

    def callback_ok_twiss(self):
        self.apply_settings_twiss()
        if self._settings["eps"] == ["", ""] or self._settings["r"] == ["", ""] or self._settings["rp"] == ["", ""]:
            self.run_error()
        else:
            if self._settings["zpos"] == "Constant" and self._settings["zmom"] == "Constant":
                g = GenerateDistribution(self._settings["numpart"], self._settings["species"],
                                         self._settings["energy"], self._settings["zpos"], self._settings["zmom"],
                                         self._settings["zr"])
            elif self._settings["zpos"] == "Gaussian on ellipse" or self._settings["zmom"] == "Gaussian on ellipse":
                g = GenerateDistribution(self._settings["numpart"], self._settings["species"],
                                         self._settings["energy"], self._settings["zpos"], self._settings["zmom"],
                                         self._settings["zr"], self._settings["ze"],
                                         self._settings["zstddev"])
            else:
                g = GenerateDistribution(self._settings["numpart"], self._settings["species"],
                                         self._settings["energy"], self._settings["zpos"], self._settings["zmom"],
                                         self._settings["zr"], self._settings["ze"])
            if self._settings["xydist"] == "Uniform":
                self.data = g.generate_uniform(self._settings["r"], self._settings["rp"], self._settings["eps"])
            elif self._settings["xydist"] == "Gaussian":
                self.data = g.generate_gaussian(self._settings["r"], self._settings["rp"], self._settings["eps"],
                                                self._settings["xystddev"])
            elif self._settings["xydist"] == "Waterbag":
                self.data = g.generate_waterbag(self._settings["r"], self._settings["rp"], self._settings["eps"])
            elif self._settings["xydist"] == "Parabolic":
                self.data = g.generate_parabolic(self._settings["r"], self._settings["rp"], self._settings["eps"])
            self._generate_twiss.close()
            self._parent.add_generated_dataset(data=self.data, settings=self._settings)

    def change_zpos_envelope(self):
        info = str(self._generate_envelopeGUI.zpos.currentText())
        if info != "Constant" and info != "Uniform along length":
            self._generate_envelopeGUI.ze.setEnabled(True)
            if info == "Gaussian on ellipse":
                self._generate_envelopeGUI.zpstddev.setEnabled(True)
            else:
                self._generate_envelopeGUI.zpstddev.setDisabled(True)
        else:
            self._generate_envelopeGUI.ze.setDisabled(True)
            self._generate_envelopeGUI.zpstddev.setDisabled(True)

    def change_zmom_envelope(self):
        info = str(self._generate_envelopeGUI.zmom.currentText())
        if info != "Constant" and info != "Uniform along length":
            self._generate_envelopeGUI.ze.setEnabled(True)
            if info == "Gaussian on ellipse":
                self._generate_envelopeGUI.zmstddev.setEnabled(True)
            else:
                self._generate_envelopeGUI.zmstddev.setDisabled(True)
        else:
            self._generate_envelopeGUI.ze.setDisabled(True)
            self._generate_envelopeGUI.zmstddev.setDisabled(True)

    def change_xy_envelope(self):
        info = str(self._generate_envelopeGUI.xydist.currentText())
        if info == "Gaussian":
            self._generate_envelopeGUI.xstddev.setEnabled(True)
            self._generate_envelopeGUI.xpstddev.setEnabled(True)
            self._generate_envelopeGUI.ystddev.setEnabled(True)
            self._generate_envelopeGUI.ypstddev.setEnabled(True)
        else:
            self._generate_envelopeGUI.xstddev.setDisabled(True)
            self._generate_envelopeGUI.xpstddev.setDisabled(True)
            self._generate_envelopeGUI.ystddev.setDisabled(True)
            self._generate_envelopeGUI.ypstddev.setDisabled(True)

    def change_zpos_twiss(self):
        info = str(self._generate_twissGUI.zpos.currentText())
        if info != "Constant" and info != "Uniform along length":
            self._generate_twissGUI.ze.setEnabled(True)
            self._generate_twissGUI.zpa.setEnabled(True)
            self._generate_twissGUI.zpb.setEnabled(True)
            self._generate_twissGUI.length.setDisabled(True)
            if info == "Gaussian on ellipse":
                self._generate_twissGUI.zpstddev.setEnabled(True)
            else:
                self._generate_twissGUI.zpstddev.setDisabled(True)
        else:
            self._generate_twissGUI.ze.setDisabled(True)
            self._generate_twissGUI.zpa.setDisabled(True)
            self._generate_twissGUI.zpb.setDisabled(True)
            self._generate_twissGUI.length.setEnabled(True)
            self._generate_twissGUI.zpstddev.setDisabled(True)

    def change_zmom_twiss(self):
        info = str(self._generate_twissGUI.zmom.currentText())
        if info != "Constant" and info != "Uniform along length":
            self._generate_twissGUI.ze.setEnabled(True)
            if info == "Gaussian on ellipse":
                self._generate_twissGUI.zmstddev.setEnabled(True)
            else:
                self._generate_twissGUI.zmstddev.setDisabled(True)
        else:
            self._generate_twissGUI.ze.setDisabled(True)
            self._generate_twissGUI.zmstddev.setDisabled(True)

    def change_xy_twiss(self):
        info = str(self._generate_twissGUI.xydist.currentText())
        if info == "Gaussian":
            self._generate_twissGUI.xstddev.setEnabled(True)
            self._generate_twissGUI.xpstddev.setEnabled(True)
            self._generate_twissGUI.ystddev.setEnabled(True)
            self._generate_twissGUI.ypstddev.setEnabled(True)
        else:
            self._generate_twissGUI.xstddev.setDisabled(True)
            self._generate_twissGUI.xpstddev.setDisabled(True)
            self._generate_twissGUI.ystddev.setDisabled(True)
            self._generate_twissGUI.ypstddev.setDisabled(True)

    def sym_envelope(self):
        info = self._generate_envelopeGUI.checkBox.isChecked()
        if info:
            self.apply_settings_envelope()
            self._generate_envelopeGUI.yr.setText(self._settings["r"][0])
            self._generate_envelopeGUI.yrp.setText(self._settings["rp"][0])
            self._generate_envelopeGUI.ye.setText(self._settings["eps"][0])
        else:
            self._generate_envelopeGUI.yr.setText("")
            self._generate_envelopeGUI.yrp.setText("")
            self._generate_envelopeGUI.ye.setText("")

    def sym_twiss(self):
        info = self._generate_twissGUI.checkBox.isChecked()
        if info:
            xa = self._generate_twissGUI.xa.text()
            self._generate_twissGUI.ya.setText(xa)
            xb = self._generate_twissGUI.xb.text()
            self._generate_twissGUI.yb.setText(xb)
            xe = self._generate_twissGUI.xe.text()
            self._generate_twissGUI.ye.setText(xe)
        else:
            self._generate_twissGUI.ya.setText("")
            self._generate_twissGUI.yb.setText("")
            self._generate_twissGUI.ye.setText("")

    def run(self):
        # --- Calculate the positions to center the window --- #
        screen_size = self._parent.screen_size()
        _x = 0.5 * (screen_size.width() - self._generate_main.width())
        _y = 0.5 * (screen_size.height() - self._generate_main.height())

        # --- Show the GUI --- #
        self._generate_main.show()
        self._generate_main.move(_x, _y)

    def run_error(self):
        # --- Calculate the positions to center the window --- #
        screen_size = self._parent.screen_size()
        _x = 0.5 * (screen_size.width() - self._generate_error.width())
        _y = 0.5 * (screen_size.height() - self._generate_error.height())

        # --- Show the GUI --- #
        self._generate_error.show()
        self._generate_error.move(_x, _y)

    def run_envelope(self):
        # --- Calculate the positions to center the window --- #
        screen_size = self._parent.screen_size()
        _x = 0.5 * (screen_size.width() - self._generate_envelope.width())
        _y = 0.5 * (screen_size.height() - self._generate_envelope.height())

        # --- Show the GUI --- #
        self._generate_envelope.show()
        self._generate_envelope.move(_x, _y)

    def run_twiss(self):
        # --- Calculate the positions to center the window --- #
        screen_size = self._parent.screen_size()
        _x = 0.5 * (screen_size.width() - self._generate_twiss.width())
        _y = 0.5 * (screen_size.height() - self._generate_twiss.height())

        # --- Show the GUI --- #
        self._generate_twiss.show()
        self._generate_twiss.move(_x, _y)
class BeamChar(AbstractTool):
    def __init__(self, parent):
        super(BeamChar, self).__init__(parent)
        self._name = "Beam Characteristics"
        self._parent = parent
        self._filename = ""
        self._settings = {}

        # --- Initialize the GUI --- #
        self._beamCharWindow = QMainWindow()
        self._beamCharGUI = Ui_BeamChar()
        self._beamCharGUI.setupUi(self._beamCharWindow)

        self._beamCharGUI.buttonBox.accepted.connect(self.callback_apply)
        self._beamCharGUI.buttonBox.rejected.connect(
            self._beamCharWindow.close)

        self._has_gui = True
        self._need_selection = True
        self._min_selections = 1
        self._max_selections = None
        self._redraw_on_exit = False

    def apply_settings(self):
        self._settings["rms"] = self._beamCharGUI.rms.isChecked()
        self._settings["halo"] = self._beamCharGUI.halo.isChecked()
        self._settings["centroid"] = self._beamCharGUI.centroid.isChecked()
        self._settings["turnsep"] = self._beamCharGUI.turnsep.isChecked()
        self._settings["energyHist"] = self._beamCharGUI.ehist.isChecked()
        self._settings["intensity"] = self._beamCharGUI.intens.isChecked()
        self._settings["xz"] = self._beamCharGUI.xz.isChecked()

    def callback_apply(self):
        self.apply_settings()
        self._beamCharWindow.close()
        self._parent.send_status("Creating plot(s)...")

        plots = {}
        num = 0
        largepos = 1.0e36

        for dataset in self._selections:

            corrected = {}
            name = dataset.get_name()
            nsteps, npart = dataset.get_nsteps(), dataset.get_npart()

            plot_data = {
                "name": name,
                "xRMS": np.array([]),
                "yRMS": np.array([]),
                "zRMS": np.array([]),
                "xHalo": np.array([]),
                "yHalo": np.array([]),
                "zHalo": np.array([]),
                "xCentroid": np.ones(nsteps) * largepos,
                "yCentroid": np.ones(nsteps) * largepos,
                "turnSep": np.array([]),
                "R": np.array([]),
                "energy": np.array([]),
                "power": np.array([]),
                "coords": []
            }

            azimuths = np.ones(nsteps) * largepos
            r_temps = np.ones(nsteps) * largepos

            datasource = dataset.get_datasource()

            index = 0

            save_r = True
            r_tsep = []

            # --- Try to find the .o file corresponding to the dataset

            # Hardcoded defaults
            q_macro = 1.353 * 1.0e-15  # fC  --> C (1e5 particles @ 6.65 mA and f_cyclo below)
            f_cyclo = 49.16 * 1.0e6  # MHz --> Hz
            duty_factor = 0.9  # assumed IsoDAR has 90% duty factor

            self._parent.send_status(
                "Attempting to read frequency and macro-charge from .o file..."
            )

            _fn = dataset.get_filename()
            path = os.path.split(_fn)[0]

            # Let's be lazy and find the .o file automatically using regex
            template = re.compile('[.]o[0-9]{8}')
            _fns = [
                f for f in os.listdir(path)
                if os.path.isfile(os.path.join(path, f)) and template.search(f)
            ]

            if len(_fns) > 0:

                _fn = _fns[0]
                with open(os.path.join(path, _fn), 'r') as infile:
                    lines = infile.readlines()

                have_charge = False
                have_freq = False
                for line in lines:
                    if "Qi" in line:
                        _, _, _, _, _, _, _, _, qi, unit = line.strip().split()
                        q_macro = float(qi) * 1.0e-15  # fC  --> C
                        # TODO Check for unit, if exception is thrown, need to allow for different units -DW
                        assert unit == "[fC]", "Expected units of fC, got {}. Aborting!".format(
                            unit)
                        have_charge = True

                    if "FREQUENCY" in line:
                        _, _, _, freq, unit = line.strip().split()
                        f_cyclo = float(freq) * 1.0e6  # MHz --> Hz
                        # TODO Check for unit, if exception is thrown, need to allow for different units -DW
                        assert unit == "MHz", "Expected units of MHz, got {}. Aborting!".format(
                            unit)
                        have_freq = True

                    if have_charge and have_freq:
                        break

                assert have_charge and have_freq, "Found .o file, but couldn't determine frequency and/or macrocharge!"

                self._parent.send_status(
                    "Found f = {:.4f} MHz and Qi = {:.4f} fC in file {}".
                    format(f_cyclo * 1e-6, q_macro * 1e15, _fn))
                print("Found f = {:.4f} MHz and Qi = {:.4f} fC in file {}".
                      format(f_cyclo * 1e-6, q_macro * 1e15, _fn))

            else:
                self._parent.send_status(
                    "Couldn't find .o file in dataset folder! Falling back to hardcoded values."
                )
                print(
                    "Couldn't find .o file in dataset folder! Falling back to hardcoded values."
                )

            spt = 1

            for step in range(int(nsteps / spt)):

                step *= spt

                m_amu = 2.01510  # Rest mass of individual H2+, in amu
                m_mev = 1876.9729554  # Rest mass of individual H2+, in MeV/c^2

                if self._settings["rms"] or self._settings["halo"]:
                    px_val = np.array(datasource["Step#{}".format(step)]["px"])
                    py_val = np.array(datasource["Step#{}".format(step)]["py"])
                    pz_val = np.array(datasource["Step#{}".format(step)]["pz"])
                    betagamma = np.sqrt(
                        np.square(px_val) + np.square(py_val) +
                        np.square(pz_val))
                    energy = np.mean((np.sqrt(
                        np.square(betagamma * m_mev) + np.square(m_mev)) -
                                      m_mev) / m_amu)
                    plot_data["energy"] = np.append(plot_data["energy"],
                                                    energy)

                if nsteps > 1:
                    completed = int(100 * (step / (nsteps - 1)))
                    self._parent.send_status(
                        "Plotting progress: {}% complete".format(completed))

                corrected["Step#{}".format(step)] = {}

                x_val = np.array(datasource["Step#{}".format(step)]["x"])
                y_val = np.array(datasource["Step#{}".format(step)]["y"])
                z_val = np.array(datasource["Step#{}".format(step)]["z"])

                if self._settings["xz"]:

                    r = np.sqrt(np.square(x_val) + np.square(y_val))

                    plot_data["coords"] = np.append(plot_data["coords"], z_val)
                    plot_data["R"] = np.append(plot_data["R"], r)

                px_mean = np.mean(
                    np.array(datasource["Step#{}".format(step)]["px"]))
                py_mean = np.mean(
                    np.array(datasource["Step#{}".format(step)]["py"]))
                theta = np.arccos(py_mean / np.linalg.norm([px_mean, py_mean]))

                if px_mean < 0:
                    theta = -theta

                # Center the beam
                corrected["Step#{}".format(step)]["x"] = x_val - np.mean(x_val)
                corrected["Step#{}".format(step)]["y"] = y_val - np.mean(y_val)
                corrected["Step#{}".format(step)]["z"] = z_val - np.mean(z_val)

                # Rotate the beam
                temp_x = corrected["Step#{}".format(step)]["x"]
                temp_y = corrected["Step#{}".format(step)]["y"]
                corrected["Step#{}".format(step)][
                    "x"] = temp_x * np.cos(theta) - temp_y * np.sin(theta)
                corrected["Step#{}".format(step)][
                    "y"] = temp_x * np.sin(theta) + temp_y * np.cos(theta)

                # Calculate RMS
                if self._settings["rms"]:
                    plot_data["xRMS"] = np.append(
                        plot_data["xRMS"], 1000.0 *
                        self.rms(corrected["Step#{}".format(step)]["x"]))
                    plot_data["yRMS"] = np.append(
                        plot_data["yRMS"], 1000.0 *
                        self.rms(corrected["Step#{}".format(step)]["y"]))
                    plot_data["zRMS"] = np.append(
                        plot_data["zRMS"], 1000.0 *
                        self.rms(corrected["Step#{}".format(step)]["z"]))

                # Calculate halo parameter
                if self._settings["halo"]:
                    plot_data["xHalo"] = np.append(
                        plot_data["xHalo"],
                        self.halo(corrected["Step#{}".format(step)]["x"]))
                    plot_data["yHalo"] = np.append(
                        plot_data["yHalo"],
                        self.halo(corrected["Step#{}".format(step)]["y"]))
                    plot_data["zHalo"] = np.append(
                        plot_data["zHalo"],
                        self.halo(corrected["Step#{}".format(step)]["z"]))

                # Calculate energy
                if self._settings["energyHist"] or self._settings["intensity"]:
                    m_amu = 2.01510  # Rest mass of individual H2+, in amu
                    m_mev = 1876.9729554  # Rest mass of individual H2+, in MeV/c^2

                    px_val = np.array(datasource["Step#{}".format(step)]["px"])
                    py_val = np.array(datasource["Step#{}".format(step)]["py"])
                    pz_val = np.array(datasource["Step#{}".format(step)]["pz"])

                    betagamma = np.sqrt(
                        np.square(px_val) + np.square(py_val) +
                        np.square(pz_val))
                    energy = (np.sqrt(
                        np.square(betagamma * m_mev) + np.square(m_mev)) -
                              m_mev) / m_amu  # MeV/amu

                    plot_data["energy"] = np.append(plot_data["energy"],
                                                    energy)

                    if self._settings["intensity"]:

                        # Power deposition of a single h2+ particle (need to use full energy here!) (W)
                        power = q_macro * f_cyclo * energy * 1e6 * m_amu * duty_factor
                        plot_data["power"] = np.append(plot_data["power"],
                                                       power)

                        # Radii (m)
                        r = np.sqrt(np.square(x_val) + np.square(y_val))
                        plot_data["R"] = np.append(plot_data["R"], r)

                # Add centroid coordinates
                if self._settings["centroid"] or self._settings["turnsep"]:

                    plot_data["xCentroid"][step] = np.mean(x_val)
                    plot_data["yCentroid"][step] = np.mean(y_val)

                    # Calculate turn separation (as close as possible to pos x-axis for now, arbitrary angle later? -DW)
                    if self._settings["turnsep"]:
                        azimuth = np.rad2deg(
                            np.arctan2(plot_data["yCentroid"][step],
                                       plot_data["xCentroid"][step]))
                        azimuths[step] = azimuth
                        r_temp = np.sqrt(
                            np.square(plot_data["xCentroid"][step]) +
                            np.square(plot_data["yCentroid"][step]))
                        r_temps[step] = r_temp

                        if azimuth > 0 and save_r:
                            save_r = False
                            r_tsep.append(r_temp)
                        if azimuth < 0:
                            save_r = True

                # if step >= (16 * 95) + 6 and step % 16 == 6 and self._settings["turnsep"]:
                #     r = np.sqrt(np.square(np.mean(x_val)) + np.square(np.mean(y_val)))
                #     plot_data["R"] = np.append(plot_data["R"], r)
                # if step > (16 * 95) + 6 and step % 16 == 6 and self._settings["turnsep"]:
                #     index += 1
                #     difference = np.abs(plot_data["R"][index-1] - plot_data["R"][index])
                #     plot_data["turnSep"] = np.append(plot_data["turnSep"], difference)

            plots["plot_data{}".format(num)] = plot_data

            num += 1

        self._parent.send_status("Saving plot(s)...")
        # Save plots as separate images, with appropriate titles

        if self._settings["rms"]:
            _xlim = 62.2
            _ylim = 6.0
            _figsize = (7, 5)
            _fs = 12

            fig = plt.figure(figsize=_figsize)
            plt.rc(
                'font', **{
                    'family': 'serif',
                    'serif': ['Computer Modern'],
                    'weight': 100,
                    'size': _fs
                })
            plt.rc('text', usetex=True)
            plt.rc('grid', linestyle=':')
            plt.rc('ytick', labelsize=_fs)
            plt.rc('xtick', labelsize=_fs)

            ax1 = plt.subplot(311)
            plt.title("RMS Beam Size (mm)")
            for n in range(num):
                plt.plot(plots["plot_data{}".format(n)]["energy"],
                         plots["plot_data{}".format(n)]["xRMS"],
                         lw=0.8,
                         label=plots["plot_data{}".format(n)]["name"])
                # print("Mean x RMS: {}".format(np.mean(plots["plot_data{}".format(n)]["xRMS"][40:])))
            ax1.get_yaxis().set_major_locator(LinearLocator(numticks=5))
            ax1.get_yaxis().set_major_formatter(FormatStrFormatter('%.1f'))
            ax1.tick_params(labelbottom=False)
            ax1.set_xlim([0, _xlim])
            # ax1.set_ylim([0, _ylim])
            ax1.set_ylim([0, 4.0])
            plt.grid()
            plt.ylabel("Transversal")

            ax2 = plt.subplot(312, sharex=ax1)
            for n in range(num):
                plt.plot(plots["plot_data{}".format(n)]["energy"],
                         plots["plot_data{}".format(n)]["yRMS"],
                         lw=0.8,
                         label=plots["plot_data{}".format(n)]["name"])
                # print("Mean y RMS: {}".format(np.mean(plots["plot_data{}".format(n)]["yRMS"][40:])))
            plt.legend(loc=9)
            ax2.get_yaxis().set_major_locator(LinearLocator(numticks=5))
            ax2.get_yaxis().set_major_formatter(FormatStrFormatter('%.1f'))
            ax2.tick_params(labelbottom=False)
            ax2.set_xlim([0, _xlim])
            ax2.set_ylim([0, _ylim])
            plt.grid()
            plt.ylabel("Longitudinal")

            ax3 = plt.subplot(313, sharex=ax1)
            for n in range(num):
                plt.plot(plots["plot_data{}".format(n)]["energy"],
                         plots["plot_data{}".format(n)]["zRMS"],
                         lw=0.8,
                         label=plots["plot_data{}".format(n)]["name"])
                # print("Mean z RMS: {}".format(np.mean(plots["plot_data{}".format(n)]["zRMS"][40:])))
            ax3.get_yaxis().set_major_locator(LinearLocator(numticks=5))
            ax3.get_yaxis().set_major_formatter(FormatStrFormatter('%.1f'))
            ax3.set_xlim([0, _xlim])
            ax3.set_ylim([0, _ylim])
            plt.grid()
            plt.xlabel("Energy (MeV/amu)")
            plt.ylabel("Vertical")
            # fig.tight_layout()
            fig.savefig(self._filename[0] + '_rmsBeamSize.png',
                        dpi=1200,
                        bbox_inches='tight')

        if self._settings["halo"]:
            _xlim = 62.2
            _ylim = 7.0
            _figsize = (7, 5)
            _fs = 12

            fig = plt.figure(figsize=_figsize)
            plt.rc(
                'font', **{
                    'family': 'serif',
                    'serif': ['Computer Modern'],
                    'weight': 100,
                    'size': _fs
                })
            plt.rc('text', usetex=True)
            plt.rc('grid', linestyle=':')
            plt.rc('ytick', labelsize=_fs)
            plt.rc('xtick', labelsize=_fs)

            ax1 = plt.subplot(311)
            plt.title("Halo Parameter")
            for n in range(num):
                plt.plot(plots["plot_data{}".format(n)]["energy"],
                         plots["plot_data{}".format(n)]["xHalo"],
                         lw=0.8,
                         label=plots["plot_data{}".format(n)]["name"])
            ax1.get_yaxis().set_major_locator(LinearLocator(numticks=5))
            ax1.tick_params(labelbottom=False)
            ax1.set_ylim([0, _ylim])
            ax1.set_xlim([0, _xlim])
            plt.grid()
            plt.ylabel("Transversal")

            ax2 = plt.subplot(312, sharex=ax1)
            for n in range(num):
                plt.plot(plots["plot_data{}".format(n)]["energy"],
                         plots["plot_data{}".format(n)]["yHalo"],
                         lw=0.8,
                         label=plots["plot_data{}".format(n)]["name"])
            plt.legend(loc=9)
            ax2.get_yaxis().set_major_locator(LinearLocator(numticks=5))
            ax2.tick_params(labelbottom=False)
            ax2.set_ylim([0, _ylim])
            ax2.set_xlim([0, _xlim])
            plt.grid()
            plt.ylabel("Longitudinal")

            ax3 = plt.subplot(313, sharex=ax1)
            for n in range(num):
                plt.plot(plots["plot_data{}".format(n)]["energy"],
                         plots["plot_data{}".format(n)]["zHalo"],
                         lw=0.8,
                         label=plots["plot_data{}".format(n)]["name"])
            ax3.get_yaxis().set_major_locator(LinearLocator(numticks=5))
            ax3.set_ylim([0, _ylim])
            ax3.set_xlim([0, _xlim])
            plt.grid()
            plt.xlabel("Energy (MeV/amu)")
            plt.ylabel("Vertical")
            # fig.tight_layout()
            fig.savefig(self._filename[0] + '_haloParameter.png',
                        bbox_inches='tight',
                        dpi=1200)

        if self._settings["centroid"]:
            fig = plt.figure()
            plt.rc('font', **{'family': 'serif', 'serif': ['Computer Modern']})
            plt.rc('text', usetex=True)
            plt.rc('grid', linestyle=':')

            plt.title("Top-down view of Centroid Position")
            for n in range(num):
                plt.plot(plots["plot_data{}".format(n)]["xCentroid"],
                         plots["plot_data{}".format(n)]["yCentroid"],
                         'o',
                         ms=0.5,
                         label=plots["plot_data{}".format(n)]["name"])
            plt.legend()
            ax = plt.gca()
            ax.set_aspect('equal')
            plt.grid()
            plt.xlabel("Horizontal (m)")
            plt.ylabel("Longitudinal (m)")
            fig.tight_layout()
            fig.savefig(self._filename[0] + '_centroidPosition.png',
                        bbox_inches='tight',
                        dpi=1200)

        # TODO: Fix turn separation to allow any number of steps
        if self._settings["turnsep"]:
            fig = plt.figure()
            plt.rc('font', **{'family': 'serif', 'serif': ['Computer Modern']})
            plt.rc('text', usetex=True)
            plt.rc('grid', linestyle=':')

            plt.title("Turn Separation")

            plt.plot(1000.0 * np.diff(r_tsep))

            # plt.plot(range(96, 105), 1000.0 * plot_data["turnSep"], 'k', lw=0.8)
            plt.grid()
            plt.xlabel("Turn Number")
            plt.ylabel("Separation (mm)")
            fig.savefig(self._filename[0] + '_turnSeparation.png',
                        bbox_inches='tight',
                        dpi=1200)

        if self._settings["energyHist"]:
            fig = plt.figure()
            plt.rc('font', **{'family': 'serif', 'serif': ['Computer Modern']})
            plt.rc('text', usetex=True)
            plt.rc('grid', linestyle=':')

            plt.title("Particle Energy")

            for n in range(num):

                plt.hist(
                    plots["plot_data{}".format(n)]["energy"],
                    bins=100,
                    histtype='step',
                    # weights=np.full_like(plots["plot_data{}".format(n)]["energy"], 6348),
                    label="{}, total particles = {}".format(
                        plots["plot_data{}".format(n)]["name"],
                        len(plots["plot_data{}".format(n)]["energy"])))
            plt.legend()
            plt.grid()
            plt.xlabel("Energy (MeV/amu)")
            plt.ylabel(r"Particle Density (a.u.)")

            fig.tight_layout()

            fig.savefig(self._filename[0] + '_energy.png',
                        bbox_inches='tight',
                        dpi=1200)

        if self._settings["intensity"]:
            fig = plt.figure()
            plt.rc('font', **{'family': 'serif', 'serif': ['Computer Modern']})
            plt.rc('text', usetex=True)
            plt.rc('grid', linestyle=':')

            plt.title("Histogram of the Beam Power (0.5 mm Bins)")

            bin_width = 0.5  # mm

            for n in range(num):

                radii = plots["plot_data{}".format(n)]["R"] * 1.0e3  # m --> mm

                r_len = radii.max() - radii.min()
                n_bins = int(np.round(r_len / bin_width, 0))

                print("Numerical bin width = {:.4f} mm".format(r_len / n_bins))

                power, bins = np.histogram(
                    radii,
                    bins=n_bins,
                    weights=plots["plot_data{}".format(n)]["power"])

                # temp_bins = bins[200:-1]
                # temp_power = power[200:]
                #
                # idx = np.where(temp_bins <= 1935)  # 1940 for Probe25
                #
                # temp_bins = temp_bins[idx]
                # temp_power = temp_power[idx]
                #
                # print("Min R =", temp_bins[np.where(temp_power == np.min(temp_power))], "mm\n")
                # print("Min P =", temp_power[np.where(temp_power == np.min(temp_power))], "W\n")

                plt.hist(bins[:-1],
                         bins,
                         weights=power,
                         label=plots["plot_data{}".format(n)]["name"],
                         alpha=0.3,
                         log=True)

            plt.gca().axhline(200.0,
                              linestyle="--",
                              color="black",
                              linewidth=1.0,
                              label="200 W Limit")
            plt.legend(loc=2)
            plt.grid()
            plt.xlabel("Radius (mm)")
            plt.ylabel("Beam Power (W)")
            fig.tight_layout()
            fig.savefig(self._filename[0] + '_power.png',
                        bbox_inches='tight',
                        dpi=1200)

        if self._settings["xz"]:
            fig = plt.figure()
            plt.rc('font', **{'family': 'serif', 'serif': ['Computer Modern']})
            plt.rc('text', usetex=True)
            plt.rc('grid', linestyle=':')

            plt.title("Probe Scatter Plot")
            ax = plt.gca()

            for n in range(num):

                plt.plot(
                    plots["plot_data{}".format(n)]["R"] * 1000.0,  # m --> mm
                    plots["plot_data{}".format(n)]["coords"] *
                    1000.0,  # m --> mm
                    'o',
                    alpha=0.6,
                    markersize=0.005,
                    label=plots["plot_data{}".format(n)]["name"])

            plt.grid()
            ax.set_aspect('equal')
            plt.xlabel("Radius (mm)")
            plt.ylabel("Vertical (mm)")
            fig.tight_layout()
            fig.savefig(self._filename[0] + '_RZ.png',
                        bbox_inches='tight',
                        dpi=1200)

        self._parent.send_status("Plot(s) saved successfully!")

    @staticmethod
    def rms(nparray):
        mean_sqrd = np.mean(np.square(nparray))
        return np.sqrt(mean_sqrd)

    @staticmethod
    def halo(nparray):
        mean_sqrd = np.mean(np.square(nparray))
        mean_frth = np.mean(np.square(np.square(nparray)))
        return mean_frth / (np.square(mean_sqrd)) - 1.0

    def run(self):
        # --- Calculate the positions to center the window --- #
        screen_size = self._parent.screen_size()
        _x = 0.5 * (screen_size.width() - self._beamCharWindow.width())
        _y = 0.5 * (screen_size.height() - self._beamCharWindow.height())

        # --- Show the GUI --- #
        self._beamCharWindow.show()
        self._beamCharWindow.move(_x, _y)

    def open_gui(self):

        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog

        self._filename = QFileDialog.getSaveFileName(caption="Saving plots...",
                                                     options=options,
                                                     filter="Image (*.png)")

        self.run()
class SmartMirrorForm(QMainWindow):
    def __init__(self, parent=None):

        super(SmartMirrorForm, self).__init__(parent)
        self.widgetsList = []
        self.mainWindow = QMainWindow()
        desktopWidget = QApplication.desktop()
        numScreens = desktopWidget.screenCount()
        screenQRect = desktopWidget.screenGeometry(numScreens - 1)
        self.mainWindow.move(screenQRect.left(), screenQRect.top())
        self.mainWindow.resize(screenQRect.width(), screenQRect.height())
        self.mainWindow.showFullScreen()

        self.centralWidget = QWidget(self.mainWindow)
        self.centralWidget.setStyleSheet('background-color:black')
        self.centralWidget.resize(self.mainWindow.width(),
                                  self.mainWindow.height())

        self.mainWindow.setCentralWidget(self.centralWidget)
        QMetaObject.connectSlotsByName(self.mainWindow)

        self.create_time_widget()
        self.create_news_widget()
        self.create_weather_widget()

    def create_time_widget(self):

        self.timeWidget = QWidget(self.centralWidget)
        self.timeWidgetLocation = 'topLeft'
        self.timeWidget.setObjectName('timeWidget')
        self.widgetsList.append(self.timeWidget)
        self.timeWidget.setGeometry(
            QRect(0, 0,
                  self.centralWidget.width() / 2,
                  (self.centralWidget.width() / 2) / 2.7))
        self.timeLabel = QLabel(self.timeWidget)
        self.timeLabel.setGeometry(
            QRect(0, 0, self.timeWidget.width(),
                  (self.timeWidget.height() / 3) * 2))
        self.timeLabel.setStyleSheet(
            "color:rgb(255, 255, 255); font-family:Century Gothic,arial,sans-serif; font-weight: bold;"
        )
        timeLabelFont = self.timeLabel.font()
        timeLabelFont.setPixelSize(((self.timeWidget.height() / 3) * 2) - 5)
        self.timeLabel.setFont(timeLabelFont)
        self.timeLabel.setText('17:53:59')

        self.dayLabel = QLabel(self.timeWidget)
        self.dayLabel.setGeometry(
            QRect(0, (self.timeWidget.height() / 3) * 2,
                  self.timeWidget.width(), (self.timeWidget.height() / 3)))
        self.dayLabel.setStyleSheet(
            "color:rgb(255, 255, 255); font-family:Century Gothic,arial,sans-serif;"
        )
        dayLabelFont = self.dayLabel.font()
        dayLabelFont.setPixelSize((self.timeWidget.height() / 3) - 5)
        self.dayLabel.setFont(dayLabelFont)
        self.dayLabel.setText('Mon, 08 Apr')

    def create_news_widget(self):

        self.newsWidget = QWidget(self.centralWidget)
        self.newsWidgetLocation = 'topLeft'
        self.newsWidget.setObjectName('newsWidget')
        self.widgetsList.append(self.newsWidget)
        self.newsWidget.setGeometry(
            QRect(0, 0,
                  self.centralWidget.width() / 2,
                  (self.centralWidget.width() / 2) / 2.5))
        self.newsWidget.setStyleSheet(
            "color:rgb(255, 255, 255); font-family:Century Gothic,arial,sans-serif;"
        )

        self.newsHeader = QLabel(self.newsWidget)
        self.newsHeader.setStyleSheet("font-size: 30px; font-weight: bold;")
        self.newsHeader.setGeometry(
            QRect(0, 0,
                  self.centralWidget.width() / 2, 30))

        self.newsItem1Header = QLabel(self.newsWidget)
        self.newsItem1Header.setStyleSheet(
            "font-size: 20px; font-weight: bold;")
        self.newsItem1Header.setGeometry(
            QRect(0, 40,
                  self.centralWidget.width() / 2, 24))

        self.newsItem2Header = QLabel(self.newsWidget)
        self.newsItem2Header.setStyleSheet(
            "font-size: 20px; font-weight: bold;")
        self.newsItem2Header.setGeometry(
            QRect(0, 70,
                  self.centralWidget.width() / 2, 24))

        self.newsItem3Header = QLabel(self.newsWidget)
        self.newsItem3Header.setStyleSheet(
            "font-size: 20px; font-weight: bold;")
        self.newsItem3Header.setGeometry(
            QRect(0, 100,
                  self.centralWidget.width() / 2, 24))

        self.newsItem4Header = QLabel(self.newsWidget)
        self.newsItem4Header.setStyleSheet(
            "font-size: 20px; font-weight: bold;")
        self.newsItem4Header.setGeometry(
            QRect(0, 130,
                  self.centralWidget.width() / 2, 24))

        self.newsItem5Header = QLabel(self.newsWidget)
        self.newsItem5Header.setStyleSheet(
            "font-size: 20px; font-weight: bold;")
        self.newsItem5Header.setGeometry(
            QRect(0, 160,
                  self.centralWidget.width() / 2, 24))

    def create_weather_widget(self):

        self.weatherWidget = QWidget(self.centralWidget)
        self.weatherWidgetLocation = 0
        self.weatherWidget.setObjectName('weatherWidget')
        self.widgetsList.append(self.weatherWidget)
        self.weatherWidget.setGeometry(
            QRect(0, 0,
                  self.centralWidget.width() / 2, 181))
        self.weatherWidget.setStyleSheet(
            "color:rgb(255, 255, 255); font-family:Century Gothic,arial,sans-serif;"
        )

        # Forecast 1
        self.forecast1WeatherTitle = QLabel(self.weatherWidget)
        self.forecast1WeatherTitle.setStyleSheet(
            "font-size: 22px; font-weight: bold; text-align: centre;")
        self.forecast1WeatherTitle.setGeometry(QRect(0, 0, 90, 40))
        self.forecast1WeatherIcon = QLabel(self.weatherWidget)
        self.forecast1WeatherIcon.setGeometry(QRect(0, 41, 90, 100))
        self.forecast1WeatherTemp = QLabel(self.weatherWidget)
        self.forecast1WeatherTemp.setStyleSheet(
            "font-size: 20px; text-align: centre;")
        self.forecast1WeatherTemp.setGeometry(QRect(0, 142, 90, 30))

        # Forecast 2
        self.forecast2WeatherTitle = QLabel(self.weatherWidget)
        self.forecast2WeatherTitle.setStyleSheet(
            "font-size: 22px; font-weight: bold; text-align: centre;")
        self.forecast2WeatherTitle.setGeometry(
            QRect((self.weatherWidget.width() / 5) * 1, 0, 100, 40))
        self.forecast2WeatherIcon = QLabel(self.weatherWidget)
        self.forecast2WeatherIcon.setGeometry(
            QRect((self.weatherWidget.width() / 5) * 1, 41, 90, 100))
        self.forecast2WeatherTemp = QLabel(self.weatherWidget)
        self.forecast2WeatherTemp.setStyleSheet(
            "font-size: 20px; text-align: centre;")
        self.forecast2WeatherTemp.setGeometry(
            QRect((self.weatherWidget.width() / 5) * 1, 142, 90, 30))

        # Forecast 3
        self.forecast3WeatherTitle = QLabel(self.weatherWidget)
        self.forecast3WeatherTitle.setStyleSheet(
            "font-size: 22px; font-weight: bold; text-align: centre;")
        self.forecast3WeatherTitle.setGeometry(
            QRect((self.weatherWidget.width() / 5) * 2, 0, 90, 40))
        self.forecast3WeatherIcon = QLabel(self.weatherWidget)
        self.forecast3WeatherIcon.setGeometry(
            QRect((self.weatherWidget.width() / 5) * 2, 41, 90, 100))
        self.forecast3WeatherTemp = QLabel(self.weatherWidget)
        self.forecast3WeatherTemp.setStyleSheet(
            "font-size: 20px; text-align: centre;")
        self.forecast3WeatherTemp.setGeometry(
            QRect((self.weatherWidget.width() / 5) * 2, 142, 90, 30))

        # Forecast 4
        self.forecast4WeatherTitle = QLabel(self.weatherWidget)
        self.forecast4WeatherTitle.setStyleSheet(
            "font-size: 22px; font-weight: bold; text-align: centre;")
        self.forecast4WeatherTitle.setGeometry(
            QRect((self.weatherWidget.width() / 5) * 3, 0, 90, 40))
        self.forecast4WeatherIcon = QLabel(self.weatherWidget)
        self.forecast4WeatherIcon.setGeometry(
            QRect((self.weatherWidget.width() / 5) * 3, 41, 90, 100))
        self.forecast4WeatherTemp = QLabel(self.weatherWidget)
        self.forecast4WeatherTemp.setStyleSheet(
            "font-size: 20px; text-align: centre;")
        self.forecast4WeatherTemp.setGeometry(
            QRect((self.weatherWidget.width() / 5) * 3, 142, 90, 30))
        # Forecast 5
        self.forecast5WeatherTitle = QLabel(self.weatherWidget)
        self.forecast5WeatherTitle.setStyleSheet(
            "font-size: 22px; font-weight: bold; text-align: centre;")
        self.forecast5WeatherTitle.setGeometry(
            QRect((self.weatherWidget.width() / 5) * 4, 0, 90, 40))
        self.forecast5WeatherIcon = QLabel(self.weatherWidget)
        self.forecast5WeatherIcon.setGeometry(
            QRect((self.weatherWidget.width() / 5) * 4, 41, 90, 100))
        self.forecast5WeatherTemp = QLabel(self.weatherWidget)
        self.forecast5WeatherTemp.setStyleSheet(
            "font-size: 20px; text-align: centre;")
        self.forecast5WeatherTemp.setGeometry(
            QRect((self.weatherWidget.width() / 5) * 4, 142, 90, 30))

    def move_top_left(self, widget):
        widget.setGeometry(QRect(0, 0, widget.width(), widget.height()))
        widget.setParent(self.centralWidget)

    def move_top_right(self, widget):
        widget.setGeometry(
            QRect(self.centralWidget.width() / 2, 0, widget.width(),
                  widget.height()))
        widget.setParent(self.centralWidget)

    def move_bottom_left(self, widget):
        widget.setGeometry(
            QRect(0,
                  self.centralWidget.height() - widget.height(),
                  widget.width(), widget.height()))
        widget.setParent(self.centralWidget)

    def move_bottom_right(self, widget):
        widget.setGeometry(
            QRect(self.centralWidget.width() / 2,
                  self.centralWidget.height() - widget.height(),
                  widget.width(), widget.height()))
        widget.setParent(self.centralWidget)

    def toggle_visibility(self, widget):
        if widget.isVisible():
            widget.setVisible(False)
        else:
            widget.setVisible(True)
Exemple #16
0
class NotesEditing(Notes):
    def __init__(self):
        super().__init__()

        self.list_icons_dict = {}
        self.tabwidget_icons_dict = {}

        self.listchanges = []
        self.tabchanges = []

        self.status = True

        self.example = 'ExampleNotebook'

        self.deftabico = 'icons/tabred.png'
        self.defaultListIcon = 'icons/notebookgrey.png'

        self.MainWindow = QMainWindow()
        self.setupUi(self.MainWindow)

        # Menubar

        self.menu_file_action.triggered.connect(self.createFile)
        self.new_notebook_action.triggered.connect(self.itemMenu)
        self.open_file_action.triggered.connect(self.openNote)
        self.save_file_action.triggered.connect(self.save)

        self.undo_edit_action.triggered.connect(self.undo)
        self.redo_edit_action.triggered.connect(self.redo)
        self.copy_edit_action.triggered.connect(self.copy)
        self.cut_edit_action.triggered.connect(self.cut)
        self.paste_edit_action.triggered.connect(self.paste)
        self.image_edit_action.triggered.connect(self.insertimage)
        self.table_edit_action.triggered.connect(self.tableDialog)
        self.time_edit_action.triggered.connect(self.time)
        self.date_edit_action.triggered.connect(self.date)

        self.fontcolor_format_action.triggered.connect(self.fontColorSelect)
        self.fontbgcolor_format_action.triggered.connect(self.fontBackground)
        self.font_format_action.triggered.connect(self.selectFont)
        self.leftalign_format_action.triggered.connect(self.textAlignLeft)
        self.centeralign_format_action.triggered.connect(self.textAlignCenter)
        self.rightalign_format_action.triggered.connect(self.textAlignRight)
        self.alignjustify_format_action.triggered.connect(
            self.textAlignJustify)

        # Toolbar

        self.addnew.triggered.connect(self.itemMenu)
        self.addtab.triggered.connect(self.tabContents)
        self.saveAction.triggered.connect(self.save)
        self.newFile.triggered.connect(self.createFile)
        self.printcfg.triggered.connect(self.exportPDF)
        self.openAction.triggered.connect(self.open)
        self.copyAction.triggered.connect(self.copy)
        self.pasteAction.triggered.connect(self.paste)
        self.cutAction.triggered.connect(self.cut)
        self.undoAction.triggered.connect(self.undo)
        self.redoAction.triggered.connect(self.redo)
        self.leftAlign.triggered.connect(self.textAlignLeft)
        self.rightAlign.triggered.connect(self.textAlignRight)
        self.centerAlign.triggered.connect(self.textAlignCenter)
        self.justifyAlign.triggered.connect(self.textAlignJustify)
        self.dateAction.triggered.connect(self.date)
        self.timeAction.triggered.connect(self.time)
        self.tableAction.triggered.connect(self.tableDialog)
        self.bulletAction.triggered.connect(self.listBullets)
        self.numberAction.triggered.connect(self.listNumbered)
        self.imageAction.triggered.connect(self.insertimage)
        self.fontcolorAction.triggered.connect(self.fontColorSelect)
        self.fontBackgroundAction.triggered.connect(self.fontBackground)
        self.fontAction.triggered.connect(self.selectFont)
        self.HRAction.triggered.connect(self.insertHR)

        self.list.customContextMenuRequested.connect(self.listMenu)
        self.list.itemClicked.connect(self.list_clicked)
        self.stack.customContextMenuRequested.connect(self.tabMenu)

        self.MainWindow.closeEvent = self.closeEvent

        self.loadcheck()

    def closeEvent(self, event):

        self.active = QApplication.activeWindow()

        if self.archive != None:

            if self.status:

                split = os.path.splitext(self.archive)[0]

                if os.path.exists(split):

                    shutil.rmtree(split)
                    event.accept()

                else:
                    event.accept()

                self.active.close()

            else:

                reply = QMessageBox.question(
                    self.MainWindow, 'Message',
                    "It looks like you have some unsaved changes to your notes. Are you sure to quit?",
                    QMessageBox.Yes | QMessageBox.No | QMessageBox.Save)

                if reply == QMessageBox.Yes:
                    try:

                        split = os.path.splitext(self.archive)[0]
                        if os.path.exists(split):

                            shutil.rmtree(split)
                            event.accept()
                            self.active.close()

                        else:
                            event.accept()

                            self.active.close()

                    except:
                        self.active.close()

                elif reply == QMessageBox.Save:
                    self.save()

                    split = os.path.splitext(self.archive)[0]

                    if os.path.exists(split):

                        shutil.rmtree(split)

                    event.accept()
                    self.active.close()
                    #event.ignore()

                elif reply == QMessageBox.No:
                    event.ignore()

        else:
            self.active.close()

    def currentEdit(self):

        self.stack_currWid = self.stack.currentWidget()
        self.tab_currWid = self.stack_currWid.currentWidget()
        self.tab_currWid = self.tab_currWid
        self.activeEdit = self.tab_currWid
        return self.activeEdit

    def tableDialog(self):

        self.table_dialog = QDialog()

        self.tablediag_layout = QFormLayout()

        self.lbl_rows = QLabel('Rows :')
        self.lbl_cols = QLabel('Cols :')
        self.lbl_spacing = QLabel('Spacing :')
        self.lbl_padding = QLabel('Padding :')

        self.sb_rows = QSpinBox()
        self.sb_cols = QSpinBox()
        self.sb_spacing = QSpinBox()
        self.sb_padding = QSpinBox()

        self.btn_insert = QPushButton('Insert Table')
        self.btn_insert.clicked.connect(self.table)

        self.table_dialog.setLayout(self.tablediag_layout)
        self.tablediag_layout.addRow(self.lbl_rows, self.sb_rows)
        self.tablediag_layout.addRow(self.lbl_cols, self.sb_cols)
        self.tablediag_layout.addRow(self.lbl_spacing, self.sb_spacing)
        self.tablediag_layout.addRow(self.lbl_padding, self.sb_padding)
        self.tablediag_layout.addRow(self.btn_insert)

        self.table_dialog.show()

    def table(self):

        self.tableRows = self.sb_rows.text()
        self.tableCols = self.sb_cols.text()
        self.tableSpacing = self.sb_spacing.text()
        self.tablePadding = self.sb_padding.text()

        tableFormatting = QTextTableFormat()
        tableFormatting.setCellPadding(int(self.tablePadding))
        tableFormatting.setCellSpacing(int(self.tableSpacing))

        cursor = self.currentEdit().textCursor()

        table = cursor.insertTable(int(self.tableRows), int(self.tableCols),
                                   tableFormatting)

    def copy(self):
        cursor = self.currentEdit().textCursor()
        txtSelected = cursor.selectedText()
        self.copyTxt = txtSelected

    def paste(self):
        self.currentEdit().append(self.copyTxt)

    def cut(self):
        self.currentEdit().cut()

    def fontColorSelect(self):
        color = QColorDialog.getColor()

        self.currentEdit().setTextColor(color)

    def undo(self):
        self.currentEdit().undo()

    def redo(self):
        self.currentEdit().redo()

    def textAlignLeft(self):

        self.currentEdit().setAlignment(Qt.AlignLeft)

    def textAlignRight(self):
        self.currentEdit().setAlignment(Qt.AlignRight)

    def textAlignCenter(self):

        self.currentEdit().setAlignment(Qt.AlignCenter)

    def textAlignJustify(self):
        self.currentEdit().setAlignment(Qt.AlignJustify)

    def date(self):
        currentDate = QDate.currentDate()
        cursor = self.currentEdit().textCursor()
        # insert at cursor
        cursor.insertText(currentDate.toString(Qt.DefaultLocaleLongDate))

    def time(self):
        currentTime = QTime.currentTime()
        cursor = self.currentEdit().textCursor()

        cursor.insertText(currentTime.toString(Qt.DefaultLocaleLongDate))

    def listBullets(self):

        cursor = self.currentEdit().textCursor()

        cursor.insertList(QTextListFormat.ListDisc)

    def listNumbered(self):

        cursor = self.currentEdit().textCursor()

        cursor.insertList(QTextListFormat.ListDecimal)

    def insertimage(self):
        filename = QFileDialog.getOpenFileName(
            self.MainWindow, 'Insert image', ".",
            "Images (*.png *.jpg *.bmp *.gif)")

        filename = str(filename[0])
        fext = os.path.splitext(filename)[1]

        fbase = os.path.basename(filename)

        afile = r'{}'.format(os.path.splitext(
            self.archive)[0]) + r'/res/{}'.format(fbase)

        if not os.path.exists(r'{}'.format(os.path.splitext(self.archive)[0]) +
                              r'/res'):

            os.makedirs(r'{}'.format(os.path.splitext(self.archive)[0]) +
                        r'/res')

        if filename and fbase != '':

            shutil.copyfile(
                r'{}'.format(filename),
                r'{}'.format(os.path.splitext(self.archive)[0]) +
                r'/res/{}'.format(fbase))

        img = QImage(afile)

        if img.isNull():
            return

        # if img.isNull():
        #     imgErrorMessage = QMessageBox(self.MainWindow, QMessageBox.Critical,
        #                     "Something Went Wrong",
        #                     "Could not load image file., Please make sure the file is an image file. (.png, .jpg, .bmp, .gif)",
        #                     QMessageBox.Ok,
        #                     self)
        #     popup.show()
        else:
            cursor = self.currentEdit().textCursor()
            cursor.insertImage(img, afile)

    def selectFont(self):

        font, ok = QFontDialog.getFont()

        if ok:
            self.currentEdit().setCurrentFont(font)

    def fontBackground(self):

        backgroundColor = QColorDialog.getColor()

        self.currentEdit().setTextBackgroundColor(backgroundColor)

    def open(self):

        self.noteFileOpen = QFileDialog.getOpenFileName(
            self.MainWindow, 'Open File')[0]

        self.openfile = os.path.splitext(self.noteFileOpen)[0]

        xml = ET.parse('settings/programSettings.xml')

        y = xml.find('recentfilepath')
        y.text = str(self.openfile)

        xml.write(open('settings/programSettings.xml', 'wb'))

        self.win = NotesEditing()

    def insertHR(self):

        c = self.currentEdit().textCursor()

        c.insertHtml("<hr style='color: red'></hr><br>")

    def exportPDF(self):

        savepdf = QFileDialog.getSaveFileName(self.MainWindow,
                                              "Export Current Note to PDF",
                                              None, "PDF files (.pdf)")

        qprint = QPrinter(QPrinter.HighResolution)
        qprint.setOutputFormat(QPrinter.PdfFormat)
        qprint.setOutputFileName(savepdf[0])

        self.currentEdit().document().print_(qprint)

    def list_clicked(self):
        self.item = self.list.currentItem()
        self.index = self.list.currentIndex()

        self.findSection = self.stack.findChild(QTabWidget, self.item.text())
        self.stack.setCurrentWidget(self.findSection)

    def notebookstatus(self):
        self.status = False

    def tabContents(self):
        self.dialog = QDialog()

        self.layout_tab = QFormLayout()

        self.label = QLabel("Enter tab name here:")

        self.le_text = QLineEdit()

        self.combo_tab = QCheckBox()
        self.combo_tab.stateChanged.connect(self.checkTabToggle)

        self.btn_icon = QPushButton('Choose Icon')
        self.btn_icon.clicked.connect(self.chooseTabIcon)
        self.btn_icon.setDisabled(True)

        self.le_tab_path = QLineEdit()
        self.le_tab_path.setReadOnly(True)

        buttonBox = QDialogButtonBox(QDialogButtonBox.Ok
                                     | QDialogButtonBox.Cancel)
        buttonBox.accepted.connect(self.tab_ok)
        buttonBox.rejected.connect(self.cancel)

        self.dialog.setLayout(self.layout_tab)
        self.layout_tab.addRow(self.label)
        self.layout_tab.addRow(self.le_text)
        self.layout_tab.addRow(self.combo_tab)
        self.layout_tab.addRow(self.btn_icon)
        self.layout_tab.addRow(self.le_tab_path)
        self.layout_tab.addRow(buttonBox)

        self.dialog.show()

    def itemMenu(self):
        self.item_dialog = QDialog()

        self.layout_item = QFormLayout()

        nbTitle = QLabel("Enter Notebook Title:")

        self.le_item = QLineEdit()

        self.check = QCheckBox()
        self.check.stateChanged.connect(self.checktoggle)

        self.btn_listIcon = QPushButton('Choose Icon')
        self.btn_listIcon.setEnabled(False)
        self.btn_listIcon.clicked.connect(self.chooseListIcon)

        self.le_path = QLineEdit()
        self.le_path.setReadOnly(True)

        buttonBox = QDialogButtonBox(QDialogButtonBox.Ok
                                     | QDialogButtonBox.Cancel)
        buttonBox.accepted.connect(self.item_ok)
        buttonBox.rejected.connect(self.cancel)

        self.item_dialog.setLayout(self.layout_item)
        self.layout_item.addRow(nbTitle)
        self.layout_item.addRow(self.le_item)
        self.layout_item.addRow(self.check)
        self.layout_item.addRow(self.btn_listIcon)
        self.layout_item.addRow(self.le_path)
        self.layout_item.addRow(buttonBox)

        self.item_dialog.show()

    def checkTabToggle(self):
        self.btn_icon.setEnabled(True)

    def checktoggle(self):
        self.btn_listIcon.setEnabled(True)

    def chooseListIcon(self):

        fname = QFileDialog.getOpenFileName(self.MainWindow, 'Open File',
                                            'images\icons')
        fname = str(fname[0])
        self.item_filename = fname
        self.le_path.setText(fname)

    def item_ok(self):

        self.checkInfo = self.check.isChecked()

        if self.checkInfo == False and self.le_item.text() != False:
            self.ico = QIcon()

            self.ico.addPixmap(QPixmap(self.defaultListIcon))

            item = QListWidgetItem()
            item.setIcon(self.ico)
            item_text = self.le_item.text()
            item.setText(item_text)
            self.list.addItem(item)
            deftabtitle = 'New Tab'
            self.tab_widget = QTabWidget()
            self.tab_widget.setMovable(True)
            self.tab_widget.setObjectName(item_text)

            self.sectioncontent = QTextEdit()
            self.sectioncontent.textChanged.connect(self.notebookstatus)
            self.tab_widget.addTab(self.sectioncontent, QIcon(self.deftabico),
                                   deftabtitle)

            self.stack.addWidget(self.tab_widget)

            self.list_icons_dict[item_text] = self.defaultListIcon

            # update tab icon dict as well since a default "New Tab" is being added.
            self.tabwidget_icons_dict[item_text] = {
                deftabtitle: self.deftabico
            }

        elif self.checkInfo == True and self.le_item.text() != False:

            self.ico = QIcon()
            self.ico_path = self.item_filename
            self.ico_path = self.item_filename
            self.ico.addPixmap(QPixmap(self.item_filename))
            item = QListWidgetItem()
            item.setIcon(self.ico)
            item_text = self.le_item.text()
            item.setText(item_text)
            self.list.addItem(item)
            self.tab_widget = QTabWidget()
            self.tab_widget.setMovable(True)
            self.tab_widget.setObjectName(item_text)
            self.stack.addWidget(self.tab_widget)

            self.list_icons_dict.update({item_text: self.ico})

        else:
            self.item_msg_box = QMessageBox(
                self.MainWindow, 'Message',
                'Please Enter a title for Notebook', QMessageBox.Ok)
            self.item_dialog.close()

        self.item_dialog.close()

    def chooseTabIcon(self):
        fname = QFileDialog.getOpenFileName(self.MainWindow, 'Open File',
                                            'images\icons')
        fname = str(fname[0])
        self.tabicon_filename = fname
        self.le_tab_path.setText(fname)

    def tab_ok(self):

        self.check_tab_icon = self.combo_tab.isChecked()

        if self.check_tab_icon == False and self.le_text.text() != False:

            self.newtabicon = QIcon()
            self.newtabicon.addPixmap(QPixmap(self.deftabico), QIcon.Normal,
                                      QIcon.On)

            self.newTabName = self.le_text.text()
            self.item = self.list.currentItem()
            self.curr_tab_wid = self.stack.findChild(QTabWidget,
                                                     self.item.text())
            self.newtabname_textedit = QTextEdit()

            self.newtabname_textedit.textChanged.connect(self.notebookstatus)

            self.newtabname_textedit.setObjectName(str(self.newTabName))
            self.curr_tab_wid.addTab(self.newtabname_textedit, self.newtabicon,
                                     self.newTabName)

            # below is working
            self.tabwidget_icons_dict[self.item.text()].update(
                {self.newTabName: self.deftabico})

        elif self.check_tab_icon == True and self.le_text.text() != False:

            self.tab_ico = self.tabicon_filename

            self.ico = QIcon()
            self.ico.addPixmap(QPixmap(self.tab_ico), QIcon.Normal, QIcon.On)

            self.newTabName = self.le_text.text()
            self.item = self.list.currentItem()
            self.curr_tab_wid = self.stack.findChild(QTabWidget,
                                                     self.item.text())
            self.curr_tab_wid.addTab(QTextEdit(), self.ico, self.newTabName)

            self.tabwidget_icons_dict[self.item.text()].update({{
                self.newTabName:
                self.tab_ico
            }})

        else:
            self.tab_msg_box = QMessageBox(self, 'Message',
                                           'Please Enter a title for TAb',
                                           QMessageBox.Ok)
            self.dialog.close()

        self.dialog.close()

    def cancel(self):
        self.dialog.close()

    def programcfg(self):
        if os.path.exists('settings/programSettings.xml'):
            xmlSettings_currpath = ET.parse(
                'settings/programSettings.xml').getroot()
            for p in xmlSettings_currpath.findall('recentfilepath'):
                self.currfile = p.text

        return self.currfile

    def tabMenu(self, event):
        self.tabContextMenu = QMenu()

        addTab = self.tabContextMenu.addAction('Add New Tab')
        deleteTab = self.tabContextMenu.addAction('Delete Tab')
        renameTab = self.tabContextMenu.addAction('Rename Tab')

        action = self.tabContextMenu.exec_(self.stack.mapToGlobal(event))

        if action == addTab:
            self.tabContents()
        if action == deleteTab:

            tabmsgbox = QMessageBox.question(
                self.MainWindow, 'Warning',
                'This Tab will be permanently deleted. Be sure to backup your notes file before continuing. Are you sure that you want to Delete this Tab?',
                QMessageBox.Ok, QMessageBox.Cancel)

            if tabmsgbox == QMessageBox.Ok:
                self.item = self.list.currentItem()
                self.curr_tab_wid = self.stack.findChild(
                    QTabWidget, self.item.text())
                self.curr_tab = self.curr_tab_wid.currentIndex()

                self.tabchanges.append(
                    self.programcfg() + '/' +
                    self.curr_tab_wid.tabText(self.curr_tab))

                del self.tabwidget_icons_dict[self.item.text()][
                    self.curr_tab_wid.tabText(self.curr_tab)]

                self.curr_tab_wid.removeTab(self.curr_tab)

        if action == renameTab:
            tabRename, ok = QInputDialog.getText(self.tab_widget,
                                                 'Input Dialog',
                                                 'Enter new tab name')
            if ok:
                self.item = self.list.currentItem()
                self.curr_tab_wid = self.stack.findChild(
                    QTabWidget, self.item.text())
                self.curr_tab = self.curr_tab_wid.currentIndex()

                print('curr_tab :', self.curr_tab_wid.tabText(self.curr_tab))

                self.tabchanges.append(
                    self.programcfg() + '/' + self.item.text() + '/' +
                    self.curr_tab_wid.tabText(self.curr_tab))

                print('tabrename :', tabRename)

                ti = self.tabwidget_icons_dict[self.item.text()].get(
                    self.curr_tab_wid.tabText(self.curr_tab))

                del self.tabwidget_icons_dict[self.item.text()][
                    self.curr_tab_wid.tabText(self.curr_tab)]

                self.tabwidget_icons_dict[self.item.text()].update(
                    {tabRename: ti})

                self.curr_tab_wid.setTabText(self.curr_tab, tabRename)

    def listMenu(self, event):
        self.contextMenu = QMenu()

        addListItem = self.contextMenu.addAction('Add New Notebook')
        deleteListItem = self.contextMenu.addAction('Delete Notebook')
        renameListItem = self.contextMenu.addAction('Rename Notebook')
        save = self.contextMenu.addAction('Save')

        action = self.contextMenu.exec_(self.list.mapToGlobal(event))

        if action == addListItem:
            self.itemMenu()
        elif action == deleteListItem:

            listmsgbox = QMessageBox.question(
                self.MainWindow, 'Warning',
                'This notebook will be permanently deleted. Be sure to backup your notes file before continuing. Are you sure that you want to Delete this Notebook?',
                QMessageBox.Ok, QMessageBox.Cancel)

            if listmsgbox == QMessageBox.Ok:

                self.fpath = self.list.currentItem().text()
                self.item = self.list.currentItem()
                self.y = self.list.takeItem(self.list.row(
                    self.item))  #pops the list item out

                self.r = self.stack.findChild(QTabWidget, self.item.text())
                sip.delete(self.r)

                self.listchanges.append(self.programcfg() + '/' + self.fpath)

                # delete nested dictionary from tabwidgets_icons_dict
                del self.tabwidget_icons_dict[self.fpath]

                del self.list_icons_dict[self.fpath]

        elif action == renameListItem:
            newItemName, ok = QInputDialog.getText(self.list, 'Input Dialog',
                                                   'Notebook Name:')
            if ok:
                self.item = self.list.currentItem()
                self.curr_item = self.stack.findChild(QTabWidget,
                                                      self.item.text())
                self.curr_item.setObjectName(newItemName)

                self.listchanges.append(self.programcfg() + '/' +
                                        self.item.text())

                self.list_icons_dict[newItemName] = self.list_icons_dict.pop(
                    self.item.text())

                print('ListIcons', self.list_icons_dict)

                # update root dict key in tabwidget
                popped = self.tabwidget_icons_dict.pop(self.item.text())
                # create the root dict key with the new listitem name and assign the previously popped nested dict to it
                self.tabwidget_icons_dict[newItemName] = popped

                self.item.setText(newItemName)

        elif action == save:
            self.save()

    def passwordmenu(self):

        self.passdialog = QDialog(self)

        self.passlayout = QFormLayout()

        self.passlbl = QLabel("Password :"******"":

            if not os.path.exists(self.saveFile):

                self.savefile_fn = os.path.split(self.saveFile)
                self.savefile_fnh = self.savefile_fn[0]
                self.savefile_fnt = self.savefile_fn[1]

                os.makedirs(self.savefile_fnh +
                            '/_{}'.format(self.savefile_fnt))
                self.saveFile = self.savefile_fnh + '/_{}'.format(
                    self.savefile_fnt)

                instance = self.saveFile

                subprocess.run([
                    r'7z\7-Zip\7z.exe', 'a', '-p{}'.format(self.pw),
                    '{}'.format(self.saveFile), '{}'.format(self.saveFile)
                ],
                               shell=False)

                root = ET.Element('programElements')
                tree = ElementTree(root)

                tree.write(open(self.saveFile + '/config.xml', 'wb'))

                xml = ET.parse('settings/programSettings.xml')

                rfp = xml.find('recentfilepath')
                rfp.text = str(self.saveFile)

                xml.write(open('settings/programSettings.xml', 'wb'))
                # might have to make the self.notewin a different name than the one below
                self.notewin = NotesEditing()

                self.creatediaglog.close()

        else:

            if not os.path.exists(self.saveFile):
                os.makedirs(self.saveFile)

            root = ET.Element('programElements')
            tree = ElementTree(root)

            tree.write(open(self.saveFile + '/config.xml', 'wb'))

            xml = ET.parse('settings/programSettings.xml')

            rfp = xml.find('recentfilepath')
            rfp.text = str(self.saveFile)

            xml.write(open('settings/programSettings.xml', 'wb'))

            self.notewin = NotesEditing()

            self.creatediaglog.close()

    def createcancel(self):

        self.creatediaglog.close()

    # def extractfile(self, pw, fp):

    #     if '_' in '{}'.format(fp):

    #         self.loadpass()

    #         # apparently it doesnt need the -o flag.
    #         zippw = subprocess.run([r'7z\7-Zip\7z.exe', 'x', '-p{}'.format(pw), '{}.7z'.format(fp)], shell=False)
    #         print('Return Code :', zippw.returncode)

    #         if zippw.returncode == 0:
    #             pass
    #         else:
    #             box = QMessageBox(self.MainWindow)
    #             box.setText("Wrong Password")
    #             box.setWindowTitle("File Error")
    #             box.exec()
    #             if box == QMessageBox.Ok:
    #                 self.loadpass()

    #     else:
    #         subprocess.run([r'7z\7-Zip\7z.exe', 'x', '{}.7z'.format(fp)], shell=False)

    # def storefile(self, pw, fp):

    #     if '_' in fp:

    #         subprocess.run([r'7z\7-Zip\7z.exe', 'a', '-p{}'.format(pw) , '{}'.format(fp), '-o{}'.format(fp)], shell=False)

    #     else:
    #         subprocess.run([r'7z\7-Zip\7z.exe', 'a', '{}'.format(fp), '{}'.format(fp)], shell=False)

    def save(self):

        self.uichanges()

        self.saveFile = self.archive

        root = ET.Element('programElements')
        tree = ElementTree(root)

        for i in range(self.list.count()):
            self.liTxt = self.list.item(i).text()
            listitem = ET.SubElement(root, 'listitem')
            licon = self.list_icons_dict[self.liTxt]
            listitem.set('item_icon', licon)
            listitem.text = self.liTxt
        for g in range(self.stack.count()):
            self.stackTab = self.stack.widget(g)
            tabwidgetName = ET.SubElement(root, 'tabwid_name')
            tabwidgetName.text = self.stackTab.objectName()
            for p in range(self.stackTab.count()):
                self.tabtext = self.stackTab.tabText(p)
                self.ticon = self.tabwidget_icons_dict[
                    self.stackTab.objectName()][self.tabtext]
                self.tabcontents = self.tabtext

                if not os.path.exists(
                        os.path.splitext(self.saveFile)[0] +
                        '/{}'.format(tabwidgetName.text) +
                        '/{}/'.format(self.tabcontents)):
                    os.makedirs(
                        os.path.splitext(self.saveFile)[0] +
                        '/{}'.format(tabwidgetName.text) +
                        '/{}/'.format(self.tabcontents))

                with open(
                        r'{}'.format(os.path.splitext(self.saveFile)[0]) +
                        r'/{}'.format(tabwidgetName.text) +
                        r'/{}/{}.html'.format(self.tabcontents,
                                              self.tabcontents), 'w') as file:
                    file.write(self.stackTab.widget(p).toHtml())
                file.close()

                tabName = ET.SubElement(tabwidgetName, 'tabName')
                tabName.set('content', str(self.tabcontents))
                tabName.set('tabIcon', self.ticon)
                tabName.text = self.tabtext

        tree.write(open(self.saveFile + '/config.xml', 'wb'))

        if '_' in self.saveFile:

            # used to add all files in the working directory with the -o flag and when i deleted it, it worked the way it should.....idk
            subprocess.run([
                r'7z\7-Zip\7z.exe', 'a', '-p{}'.format(self.pw), '{}'.format(
                    self.saveFile), '{}'.format(self.saveFile)
            ],
                           shell=False)

        else:
            subprocess.run([
                r'7z\7-Zip\7z.exe', 'a', '{}'.format(self.saveFile),
                '{}'.format(self.saveFile)
            ],
                           shell=False)

        self.programconfig(self.saveFile)

        self.status = True

    def loadpass(self):

        self.enterpass = QDialog()

        self.loadpass_layout = QFormLayout()

        self.lp_lbl = QLabel('Enter Password :'******'Cannot find any recently opened files. Would you like to open an existing Note file or create a new Note file?'
        )

        self.btn_choiceOpen = QPushButton('Open Note File')
        self.btn_choiceOpen.clicked.connect(self.openNote)

        self.btn_choiceNew = QPushButton('Create a new Note File')
        self.btn_choiceNew.clicked.connect(self.createNote)

        self.choice_dialog.setLayout(self.choice_layout)
        self.choice_layout.addRow(self.lbl_choice)
        self.choice_layout.addRow(self.btn_choiceOpen, self.btn_choiceNew)

        self.choice_dialog.exec(
        )  # .show() wont show only exec() seems to work

    def openNote(self):
        self.noteFileOpen = QFileDialog.getOpenFileName(
            self.MainWindow, 'Open File')[0]

        self.loadfile = os.path.splitext(self.noteFileOpen)[0]

        xml = ET.parse('settings/programSettings.xml')

        y = xml.find('recentfilepath')
        y.text = str(self.loadfile)

        xml.write(open('settings/programSettings.xml', 'wb'))

        self.loadcheck()
        self.choice_dialog.close()

    def createNote(self):
        self.createFile()

        self.choice_dialog.close()

    def loadcheck(self):

        if instance == '':

            if os.path.exists('settings/programSettings.xml'):
                self.xmlSettingsLoad = ET.parse('settings/programSettings.xml')
                #self.xmlSettingsLoad.getroot()

                for o in self.xmlSettingsLoad.findall('recentfilepath'):
                    recent = o.text
                    print('RECENT', recent)

                    if not recent:
                        #self.archive = None
                        self.load(self.example)
                        return

                    elif os.path.exists(str(recent) + '.7z'):
                        self.loadfile = o.text
                        # need to extract first
                        self.load(self.loadfile)

                    else:
                        print("cant find the file you are trying to open")
                        #self.archive = None
                        self.load(self.example)
                        return

        elif instance:

            self.load(instance)

    def load(self, x):

        self.archive = x

        if '_' in '{}'.format(self.archive):

            while True:

                self.loadpass()

                if self.pw != '':

                    # apparently it doesnt need the -o switch...
                    zippw = subprocess.run([
                        r'7z\7-Zip\7z.exe', 'x', '-p{}'.format(self.pw),
                        '{}.7z'.format(self.archive)
                    ],
                                           shell=False)

                    if zippw.returncode == 0:
                        break
                    else:
                        box = QMessageBox(self.MainWindow)
                        box.setText("Wrong Password")
                        box.setWindowTitle("File Error")
                        box.exec()
                else:
                    return False

        else:
            subprocess.run(
                [r'7z\7-Zip\7z.exe', 'x', '{}.7z'.format(self.archive)],
                shell=False)

        filename = ET.parse(r'{}{}'.format(
            os.path.splitext(self.archive)[0], r'/config.xml')).getroot()

        for listitem in filename.findall('listitem'):

            item = QListWidgetItem()
            icon = listitem.get('item_icon')
            self.ico = QIcon(icon)
            item.setIcon(self.ico)
            item.setText(listitem.text)
            self.list.addItem(item)

            self.list_icons_dict[listitem.text] = icon

        for tabwidget in filename.iter('tabwid_name'):
            self.tab_widget = QTabWidget()
            self.tab_widget.setObjectName(tabwidget.text)
            self.tab_widget.setMovable(True)
            self.stack.addWidget(self.tab_widget)
            self.tabwidget_icons_dict[tabwidget.text] = {}
            for tabname in tabwidget.iter('tabName'):
                self.id = self.stack.findChild(QTabWidget, tabwidget.text)
                self.tab_icon = tabname.get('tabIcon')
                self.tabico = QIcon(self.tab_icon)
                self.tabwidget_icons_dict[tabwidget.text].update(
                    {tabname.text: self.tab_icon})
                content = tabname.get('content')

                if os.path.exists(r'{}\{}'.format(
                        os.path.splitext(self.archive)[0],
                        self.tab_widget.objectName())):

                    tE = QTextEdit()
                    tE.setObjectName(content)
                    tE.textChanged.connect(self.notebookstatus)

                    with open(
                            r'{}/{}/{}/{}.html'.format(
                                os.path.splitext(x)[0],
                                self.tab_widget.objectName(), content,
                                content), 'r') as file:
                        tE.setText(file.read())
                    file.close()
                    self.id.addTab(tE, self.tabico, tabname.text)

                else:
                    msg_box = QMessageBox()
                    msg_box.setText("Error when loading file")
                    msg_box.setWindowTitle("File Error")
                    msg_box.setStandardButtons(QMessageBox.Ok
                                               | QMessageBox.Cancel)
                    msg_box.exec()

        if os.path.isfile('settings/programSettings.xml'):

            self.recentconfig = ET.parse(
                'settings/programSettings.xml').getroot()

        for i in self.recentconfig.findall('selfsize'):
            self.mws_x = i.get('x')
            self.mws_y = i.get('y')
            self.mw_width = i.get('width')
            self.mw_height = i.get('height')

        self.MainWindow.setGeometry(int(self.mws_x), int(self.mws_y),
                                    int(self.mw_width), int(self.mw_height))

        for ls in self.recentconfig.findall('listsize'):

            self.list_width = ls.get('width')

        for ss in self.recentconfig.findall('stacksize'):

            self.ssize = ss.get('width')

        self.splitter.setSizes([int(self.list_width), int(self.ssize)])
class CollimOPAL(AbstractTool):
    def __init__(self, parent):
        super(CollimOPAL, self).__init__(parent)
        self._name = "Generate Collimator"
        self._parent = parent
        self._filename = ""
        self._settings = {}
        self._datasource = None  # h5py datasource for orbit data

        # --- Initialize the GUI --- #
        self._collimOPALWindow = QMainWindow()
        self._collimOPALGUI = Ui_CollimOPAL()
        self._collimOPALGUI.setupUi(self._collimOPALWindow)

        self._collimOPALGUI.buttonBox.accepted.connect(self.callback_apply)
        self._collimOPALGUI.buttonBox.rejected.connect(self._collimOPALWindow.close)

        self._has_gui = True
        self._need_selection = True
        self._min_selections = 1
        self._max_selections = 1
        self._redraw_on_exit = False

        # Debug plotting:
        if DEBUG:
            self._fig = plt.figure()
            plt.rc('font', **{'family': 'serif', 'serif': ['Computer Modern']})
            plt.rc('text', usetex=True)
            plt.rc('grid', linestyle=':')
            self._ax = plt.gca()
            self._ax.set_xlabel("x (mm)")
            self._ax.set_ylabel("y (mm)")

    def apply_settings(self):
        self._settings["step"] = int(self._collimOPALGUI.step.text())
        self._settings["width"] = float(self._collimOPALGUI.gap.text())
        self._settings["length"] = float(self._collimOPALGUI.hl.text())
        self._settings["cwidth"] = float(self._collimOPALGUI.w.text())
        self._settings["label"] = int(self._collimOPALGUI.num.text())
        self._settings["nseg"] = int(self._collimOPALGUI.nseg.text())

    def callback_apply(self):

        self.apply_settings()

        script = ""
        script += self.gen_script()

        self._collimOPALGUI.textBrowser.setText(script)

        with open(os.path.join(os.environ.get("HOME", ""), "collim.txt"), 'w') as outfile:
            outfile.write(script)

        if DEBUG:
            plt.show()

    # @staticmethod
    # def read_data(fn):
    #
    #     with open(fn, 'r') as infile:
    #         lines = infile.readlines()
    #
    #     design_particle_lines = []
    #
    #     for line in lines:
    #         if "ID0" in line:
    #             design_particle_lines.append(line.strip())
    #
    #     npts = len(design_particle_lines)
    #
    #     x = np.zeros(npts)
    #     y = np.zeros(npts)
    #     px = np.zeros(npts)
    #     py = np.zeros(npts)
    #
    #     for i, line in enumerate(design_particle_lines):
    #         _, _x, _px, _y, _py, _, _ = line.split()
    #         x[i] = float(_x) * 1000.0
    #         y[i] = float(_y) * 1000.0
    #         px[i] = float(_px)
    #         py[i] = float(_py)
    #
    #     return np.array([x, px, y, py])

    def get_xy_mean_at_step_mm(self, step):

        x = 1e3 * np.mean(np.array(self._datasource["Step#{}".format(step)]["x"]))
        y = 1e3 * np.mean(np.array(self._datasource["Step#{}".format(step)]["y"]))

        return x, y

    def gen_script(self):
        script = ""
        letters = list(string.ascii_lowercase)

        # Central collimator placement
        x_cent, y_cent = self.get_xy_mean_at_step_mm(self._settings["step"])

        for n in range(self._settings["nseg"]):
            i = self._settings["step"]

            if n != 0:  # n = 0 indicates the central segment
                x_temp, y_temp = self.get_xy_mean_at_step_mm(i)
                if n % 2 == 1:  # n congruent to 1 mod 2 indicates placement ahead of the central segment
                    while np.sqrt(np.square(x_cent - x_temp) + np.square(y_cent - y_temp)) \
                            < (int(n / 2) + (n % 2 > 0)) * self._settings["cwidth"]:
                        i += 1
                        x_temp, y_temp = self.get_xy_mean_at_step_mm(i)
                else:  # n > 0 congruent to 0 mod 2 indicates placement behind of the central segment
                    while np.sqrt(np.square(x_cent - x_temp) + np.square(y_cent - y_temp)) \
                            < (int(n / 2) + (n % 2 > 0)) * self._settings["cwidth"]:
                        i -= 1
                        x_temp, y_temp = self.get_xy_mean_at_step_mm(i)

            x_new, y_new = self.get_xy_mean_at_step_mm(i)
            px_new = np.mean(np.array(self._datasource["Step#{}".format(i)]["px"]))
            py_new = np.mean(np.array(self._datasource["Step#{}".format(i)]["py"]))

            collim = self.gen_collim(x_new, y_new, px_new, py_new)

            script += "Collim_{}{}:CCOLLIMATOR, XSTART={}, YSTART={}, XEND={}, YEND={}, WIDTH={};\n\n" \
                .format(self._settings["label"], letters[2 * n], collim["x1a"], collim["y1a"], collim["x1b"],
                        collim["y1b"], self._settings["cwidth"])
            script += "Collim_{}{}:CCOLLIMATOR, XSTART={}, YSTART={}, XEND={}, YEND={}, WIDTH={};\n\n" \
                .format(self._settings["label"], letters[2 * n + 1], collim["x2a"], collim["y2a"], collim["x2b"],
                        collim["y2b"], self._settings["cwidth"])

            if DEBUG:
                plt.plot([collim["x1a"], collim["x1b"]], [collim["y1a"], collim["y1b"]])
                plt.plot([collim["x2a"], collim["x2b"]], [collim["y2a"], collim["y2b"]])

        if DEBUG:
            self._ax.set_title("Collimator at step {} in global frame".format(self._settings["step"]))
            self._ax.set_aspect('equal')
            x_plot = 1e3 * np.array(self._datasource["Step#{}".format(self._settings["step"])]["x"])
            y_plot = 1e3 * np.array(self._datasource["Step#{}".format(self._settings["step"])]["y"])
            plt.plot(x_plot, y_plot, 'o', alpha=0.8, markersize=0.01)

        return script

    def gen_collim(self, x, y, px, py):
        # Find angle to rotate collimator according to momentum
        theta = np.arccos(px/np.sqrt(np.square(px) + np.square(py)))
        if py < 0:
            theta = -theta
        theta1 = theta + np.pi/2
        theta2 = theta - np.pi/2

        # Calculate coordinates
        x1a = self._settings["width"] * np.cos(theta1) + x
        x2a = self._settings["width"] * np.cos(theta2) + x
        x1b = (self._settings["width"] + self._settings["length"]) * np.cos(theta1) + x
        x2b = (self._settings["width"] + self._settings["length"]) * np.cos(theta2) + x

        y1a = self._settings["width"] * np.sin(theta1) + y
        y2a = self._settings["width"] * np.sin(theta2) + y
        y1b = (self._settings["width"] + self._settings["length"]) * np.sin(theta1) + y
        y2b = (self._settings["width"] + self._settings["length"]) * np.sin(theta2) + y

        return {"x1a": x1a, "x2a": x2a, "x1b": x1b, "x2b": x2b, "y1a": y1a, "y2a": y2a, "y1b": y1b, "y2b": y2b}

    # @staticmethod
    # def read(filename):
    #     text_file = open("C:/Users/Maria/PycharmProjects/py_particle_processor"
    #                      "/py_particle_processor_qt/tools/CollimOPAL/{}.txt".format(filename), "r")
    #     lines = text_file.read().split(',')
    #     data = np.array(lines).astype(np.float)
    #     text_file.close()
    #     return data

    def run(self):
        # --- Calculate the positions to center the window --- #
        screen_size = self._parent.screen_size()
        _x = 0.5 * (screen_size.width() - self._collimOPALWindow.width())
        _y = 0.5 * (screen_size.height() - self._collimOPALWindow.height())

        # --- Show the GUI --- #
        self._collimOPALWindow.show()
        self._collimOPALWindow.move(_x, _y)

    def open_gui(self):

        # Get parent dataset/source for orbit data
        dataset = self._selections[0]
        self._datasource = dataset.get_datasource()

        self.run()
Exemple #18
0
root = QApplication([])
window = QMainWindow()
bg_new = 'background-color: rgb(%d,%d,%d);' % (random.randint(
    1, 255), random.randint(1, 255), random.randint(1, 255))

window.setStyleSheet(bg_new)
window.resize(900, 600)

title = QtWidgets.QLabel(window)
title.setStyleSheet("background-color: rgba(0,0,0,0%)")
IMG_TITLE = [QPixmap("static/img/title")]
change_img(title, IMG_TITLE, 0, 330, 430)
title.resize(450, 300)
title.move(window.width() // 2 - title.width() // 2,
           window.height() // 2 - 272)
title.move(-123, window.height() // 2 - 272)
title.LableOpacity(0.2)
window.layout().addWidget(title)
window.title = title
window.setWindowOpacity(0.9)

hand = QtWidgets.QLabel(window)
IMG_HANDS = [QPixmap("static/img/hand0.png"), QPixmap("static/img/hand1.png")]
bg_new = 'background-color: rgb(%d,%d,%d);' % (random.randint(
    1, 255), random.randint(1, 255), random.randint(1, 255))
hand.setStyleSheet("background-color: rgba(0,0,0,0%)")
# hand.setStyleSheet(bg_new)
hand.resize(100, 90)

hand.move(window.width() // 2 - hand.width() // 2 + 10,
Exemple #19
0
class SAL_app(salUI):
    def __init__(self):
        super().__init__()

        self.mainWindow = QMainWindow()
        self.mainWindow.setAcceptDrops(True)
        self.setupUI(self.mainWindow)

        # Menubar functions

        self.mb_newAction.triggered.connect(self.seriesDialog)

        # Toolbar functions

        self.addnewAction.triggered.connect(self.seriesDialog)
        self.editAction.triggered.connect(self.seriesEditDialog)
        self.deleteAction.triggered.connect(self.deleteSeries)
        self.infoAction.triggered.connect(self.applicationInfo)

        self.mainWindow.closeEvent = self.closeEvent

        # load function here
        self.dbLoad()

    # close event
    def closeEvent(self, event):

        reply = QMessageBox.question(self.mainWindow, 'Exit App',
                                     "Are you sure you want to quit?",
                                     QMessageBox.Yes | QMessageBox.No)

        if reply == QMessageBox.Yes:

            self.settings()

            event.accept()

            sys.exit()

        else:
            event.ignore()

    def getCurrentStack(self):
        pass

    def tableContextMenu(self, event):

        self.tableMenu = QMenu()

        # menu actions
        addSeries = self.tableMenu.addAction('Add New Series')
        editSeries = self.tableMenu.addAction('Edit This Entry')
        deleteSeries = self.tableMenu.addAction('Delete This Entry')

        # when stackwidget support is added this below would take the getCurrentStack function instead of just self.watchListTable
        tableAction = self.tableMenu.exec_(
            self.watchListTable.mapToGlobal(event))

        if tableAction == addSeries:
            self.seriesDialog()
        if tableAction == editSeries:
            self.seriesEditDialog()
        if tableAction == deleteSeries:
            self.deleteSeries()

    def deleteSeries(self):

        currentRow = self.watchListTable.currentIndex().row()

        if currentRow >= 0:

            delSeries = self.watchListTable.item(currentRow, 1).text()

            if delSeries != None:

                delete_msg = QMessageBox.question(
                    self.mainWindow, 'Delete - Are you sure?',
                    'Are you sure you want to delete this entry? It cannot be undone!',
                    QMessageBox.Ok | QMessageBox.Cancel)

                if delete_msg == QMessageBox.Ok:
                    conn = sqlite3.connect('saldb.sqlite')
                    cursor = conn.cursor()

                    cursor.execute("DELETE FROM watchlist WHERE Title = (?)",
                                   (delSeries, ))
                    conn.commit()
                    conn.close()

                    # delete the row from the qtablewidget
                    self.watchListTable.removeRow(currentRow)

    def seriesEditDialog(self):

        curr_row = self.watchListTable.currentIndex().row()

        if curr_row >= 0:

            #############################################################################################################################################################################
            #############################################################################################################################################################################

            # this query is just to get the info to fill in the QDialog

            curr_row = self.watchListTable.currentIndex().row()

            # column 2 should have the Title of the series which is also the unique primary key for the db
            pk_id = self.watchListTable.item(curr_row, 1).text()

            conn = sqlite3.connect('saldb.sqlite')
            conn.row_factory = sqlite3.Row
            cursor = conn.cursor()

            rowdata = cursor.execute(
                "SELECT Art, Title, English_Title, Format, Start_Date, Completion_Date, Series_Type FROM watchlist WHERE Title = ?;",
                (pk_id, ))

            for r in rowdata.fetchall():
                self.vals = dict(r)

            #THIS WORKS
            #print('ROWDATA', rowdata.fetchall()[0][0])

            conn.commit()

            conn.close()

            #############################################################################################################################################################################
            #############################################################################################################################################################################

            self.series_edit_dialog = QWidget()

            self.series_edit_dialog.setAcceptDrops(True)

            edit_dialog_layout = QGridLayout()

            # Labels
            self.artLabelEdit = QLabel()
            self.artLabelEdit.setScaledContents(True)
            self.pix = QPixmap()
            self.pix.loadFromData(self.vals['Art'])
            self.artLabelEdit.setPixmap(self.pix)
            #self.artLabel.setText("Drop Image")
            self.artLabelEdit.setAcceptDrops(True)
            self.artLabelEdit.setAlignment(Qt.AlignCenter)

            self.seriesTitleLabel = QLabel("Title :")
            self.seriesEnglishTitleLabel = QLabel("English Title :")
            self.seriesFormatLabel = QLabel("SUB/DUB :")
            self.startDateLabel = QLabel("Start Date :")
            self.completionDateLabel = QLabel("Completion Date :")
            self.seriesTypeLabel = QLabel("Series Type :")

            # LineEdits
            self.artLabel_le = QLineEdit()
            #self.artLabel_le.setPixmap(QPixmap(the blob data from the db. ))
            self.editSeriesTitle_le = QLineEdit()
            self.editSeriesTitle_le.setText(self.vals['Title'])
            self.editEnglishTitle_le = QLineEdit()
            self.editEnglishTitle_le.setText(self.vals['English_Title'])

            self.editFormat_cb = QComboBox()
            self.editFormat_cb.addItem("SUB")
            self.editFormat_cb.addItem("DUB")
            self.editFormat_cb.setCurrentText(self.vals['Format'])

            self.editStartDate_le = QLineEdit()
            self.editStartDate_le.setText(self.vals['Start_Date'])
            self.editCompletionDate_le = QLineEdit()
            self.editCompletionDate_le.setText(self.vals['Completion_Date'])
            self.editSeriesType_le = QLineEdit()
            self.editSeriesType_le.setText(self.vals['Series_Type'])

            # Buttons
            self.titleArtBtn = QPushButton("Fetch Series Title Art")
            self.titleArtBtn.clicked.connect(lambda: self.getSeriesArt(
                self.artLabelEdit, self.vals['Title']))
            self.submitEntryBtn = QPushButton("Submit")
            self.submitEntryBtn.clicked.connect(self.editEntrySubmit)
            self.chooseArtFile = QPushButton("Choose File")
            self.chooseArtFile.clicked.connect(
                lambda: self.insertArtFile(self.artLabelEdit))

            self.editStartDateBtn = QPushButton(
                "Insert Current Date"
            )  # Will be replaced with an icon, no text, tooltip
            self.editStartDateBtn.clicked.connect(self.editStartDate)

            self.editEndDateBtn = QPushButton(
                "Select Date"
            )  # Will be replaced with an icon, no text, tooltip
            self.editEndDateBtn.clicked.connect(self.selectEditEndDate)

            self.editFinishCurrentDateBtn = QPushButton(
                "Insert Current Date"
            )  # Will be replaced with an icon, no text, tooltip
            self.editFinishCurrentDateBtn.clicked.connect(self.editFinishDate)

            self.editFinishSelectionDateBtn = QPushButton(
                "Select Date"
            )  # Will be replaced with an icon, no text, tooltip
            self.editFinishSelectionDateBtn.clicked.connect(
                self.editFinishSelectionDate)

            # QFrames
            self.editButtonsFrame = QFrame()

            frameLayout = QHBoxLayout()
            self.editButtonsFrame.setLayout(frameLayout)

            frameLayout.addWidget(self.editStartDateBtn)
            frameLayout.addWidget(self.editEndDateBtn)

            self.editDateFinBtnsFrame = QFrame()
            finFrameLayout = QHBoxLayout()
            self.editDateFinBtnsFrame.setLayout(finFrameLayout)

            finFrameLayout.addWidget(self.editFinishCurrentDateBtn)
            finFrameLayout.addWidget(self.editFinishSelectionDateBtn)

            # drag event sequence functions

            def dragEnterEvent(self, event):
                if event.mimeData().hasImage:
                    event.accept()
                else:
                    event.ignore()
                    print('event ignored')

            def dragMoveEvent(self, event):
                if event.mimeData().hasImage:
                    event.accept()
                else:
                    event.ignore()
                    print('event ignored')

            def dropEvent(self, event):
                if event.mimeData().hasImage:
                    event.setDropAction(Qt.CopyAction)
                    img_fp = event.mimeData().urls()[0].toLocalFile()
                    print(img_fp)
                    self.artLabel.setPixmap(QPixmap(img_fp))

                    event.accept()
                else:
                    event.ignore()
                    print('drop event ignored')

            # Set Dialog Layout
            self.series_edit_dialog.setLayout(edit_dialog_layout)
            # column 1
            edit_dialog_layout.addWidget(self.artLabelEdit, 1, 1)
            edit_dialog_layout.addWidget(self.titleArtBtn, 2, 1)
            edit_dialog_layout.addWidget(self.chooseArtFile, 3, 1)
            edit_dialog_layout.addWidget(self.submitEntryBtn, 4, 1)
            # column 2
            edit_dialog_layout.addWidget(self.seriesTitleLabel, 1, 2)
            edit_dialog_layout.addWidget(self.seriesEnglishTitleLabel, 2, 2)
            edit_dialog_layout.addWidget(self.seriesFormatLabel, 3, 2)
            edit_dialog_layout.addWidget(self.startDateLabel, 4, 2)
            edit_dialog_layout.addWidget(self.completionDateLabel, 6, 2)
            edit_dialog_layout.addWidget(self.seriesTypeLabel, 8, 2)
            # column 3
            edit_dialog_layout.addWidget(self.editSeriesTitle_le, 1, 3)
            edit_dialog_layout.addWidget(self.editEnglishTitle_le, 2, 3)
            edit_dialog_layout.addWidget(self.editFormat_cb, 3, 3)
            edit_dialog_layout.addWidget(self.editStartDate_le, 4, 3)
            edit_dialog_layout.addWidget(self.editButtonsFrame, 5, 3)  #
            edit_dialog_layout.addWidget(self.editCompletionDate_le, 6, 3)
            edit_dialog_layout.addWidget(self.editDateFinBtnsFrame, 7, 3)
            edit_dialog_layout.addWidget(self.editSeriesType_le, 8, 3)  #

            self.series_edit_dialog.show()

    def editStartDate(self):
        date = QDate.currentDate()
        self.editStartDate_le.setText(date.toString(Qt.DefaultLocaleShortDate))

    def editFinishDate(self):
        date = QDate.currentDate()
        self.editCompletionDate_le.setText(
            date.toString(Qt.DefaultLocaleShortDate))

    def selectEditEndDate(self):
        pass

    def editFinishSelectionDate(self):
        pass

    def editEntrySubmit(self):

        if self.editSeriesTitle_le.text() != '':

            #########################################################################################################################################################
            #########################################################################################################################################################

            conn = sqlite3.connect('saldb.sqlite')
            cursor = conn.cursor()

            newart = self.artLabelEdit.pixmap()
            b_array = QByteArray()
            buffer = QBuffer(b_array)
            buffer.open(QIODevice.WriteOnly)
            newart.save(buffer, "JPG")
            blob = b_array.data()

            newValues = (self.editSeriesTitle_le.text(),
                         self.editEnglishTitle_le.text(),
                         self.editFormat_cb.currentText(),
                         self.editStartDate_le.text(),
                         self.editCompletionDate_le.text(),
                         self.editSeriesType_le.text())

            #cursor.execute("INSERT OR REPLACE INTO watchlist(Title, English_Title, Format, Start_Date, Completion_Date, Series_Type) VALUES (?, ?, ?, ?, ?, ?)", newValues)
            # cursor.execute("UPDATE watchlist SET Art = ?, Title = ?, English_Title = ?, Format = ?, Start_Date = ?, Completion_Date = ?, Series_Type = ? WHERE Title = ?", (self.vals['Art'] ,self.editSeriesTitle_le.text(), self.editEnglishTitle_le.text(), self.editFormat_cb.currentText(), self.editStartDate_le.text(), self.editCompletionDate_le.text(), self.editSeriesType_le.text(), self.vals['Title']))
            cursor.execute(
                "UPDATE watchlist SET Art = ?, Title = ?, English_Title = ?, Format = ?, Start_Date = ?, Completion_Date = ?, Series_Type = ? WHERE Title = ?",
                (blob, self.editSeriesTitle_le.text(),
                 self.editEnglishTitle_le.text(),
                 self.editFormat_cb.currentText(),
                 self.editStartDate_le.text(),
                 self.editCompletionDate_le.text(),
                 self.editSeriesType_le.text(), self.vals['Title']))

            conn.commit()
            conn.close()

            #########################################################################################################################################################
            #########################################################################################################################################################

            newValues = [
                self.artLabelEdit,
                self.editSeriesTitle_le.text(),
                self.editEnglishTitle_le.text(),
                self.editFormat_cb.currentText(),
                self.editStartDate_le.text(),
                self.editCompletionDate_le.text(),
                self.editSeriesType_le.text()
            ]

            curr_row = self.watchListTable.currentIndex().row()

            new_ctr = 0

            for c in range(self.watchListTable.columnCount()):
                if c == 0:

                    self.watchListTable.setCellWidget(curr_row, c,
                                                      newValues[c])

                else:

                    cell = self.watchListTable.item(curr_row, c).setText(
                        newValues[new_ctr])

                new_ctr += 1

        else:
            title_msg = QMessageBox(self.mainWindow)
            title_msg.setText("Title field can not be blank")
            title_msg.setWindowTitle("Missing Entry Title")

            title_msg.show()

        self.series_edit_dialog.close()

    def seriesDialog(self):

        self.series_dialog = QWidget()
        self.series_dialog.setAcceptDrops(True)

        dialog_layout = QGridLayout()

        # Labels
        self.artLabel = seriesArtLabel()
        #self.artLabel = QLabel()
        #self.artLabel.setText("Drop Image")
        #self.artLabel.setAcceptDrops(True)
        #self.artLabel.setAlignment(Qt.AlignCenter)

        self.seriesTitleLabel = QLabel("Title :")
        self.seriesEnglishTitleLabel = QLabel("English Title :")
        self.seriesFormatLabel = QLabel("SUB/DUB :")
        self.startDateLabel = QLabel("Start Date :")
        self.completionDateLabel = QLabel("Completion Date :")
        self.seriesTypeLabel = QLabel("Series Type :")

        # LineEdits
        self.artLabel_le = QLineEdit()
        self.seriesTitle_le = QLineEdit()
        self.seriesEnglishTitle_le = QLineEdit()

        self.startDate_le = QLineEdit()
        self.completionDate_le = QLineEdit()
        self.seriesType_le = QLineEdit()

        # Combobox
        self.seriesFormat_cb = QComboBox()
        self.seriesFormat_cb.addItem("SUB")
        self.seriesFormat_cb.addItem("DUB")

        # Buttons
        self.titleArtBtn = QPushButton("Fetch Series Title Art")
        self.titleArtBtn.clicked.connect(lambda: self.getSeriesArt(
            self.artLabel, self.seriesTitle_le.text()))

        self.addArtFile = QPushButton("Choose Art File")
        self.addArtFile.clicked.connect(
            lambda: self.insertArtFile(self.artLabel))

        self.submitEntryBtn = QPushButton("Submit")
        self.submitEntryBtn.clicked.connect(self.entrySubmit)

        self.currentStartDateBtn = QPushButton(
            "Insert Current Date"
        )  # Will be replaced with an icon, no text, tooltip
        self.currentStartDateBtn.clicked.connect(self.insertStartCurrentDate)

        self.startDateSelectionBtn = QPushButton(
            "Select Date")  # Will be replaced with an icon , no text, tooltip
        self.startDateSelectionBtn.clicked.connect(
            self.insertStartDateSelection)

        self.finishCurrentDateBtn = QPushButton(
            "Insert Current Date"
        )  # Will be replaced with an icon, no text, tooltip
        self.finishCurrentDateBtn.clicked.connect(self.finishCurrentDate)

        self.finishDateSelectionBtn = QPushButton(
            "Select Date")  # Will be replaced with an icon , no text, tooltip
        self.finishDateSelectionBtn.clicked.connect(self.finishDateSelection)

        # QFrames
        self.formButtonsFrame = QFrame()

        frameLayout = QHBoxLayout()
        self.formButtonsFrame.setLayout(frameLayout)

        frameLayout.addWidget(self.currentStartDateBtn)
        frameLayout.addWidget(self.startDateSelectionBtn)

        self.dateFinBtnsFrame = QFrame()
        finFrameLayout = QHBoxLayout()
        self.dateFinBtnsFrame.setLayout(finFrameLayout)

        finFrameLayout.addWidget(self.finishCurrentDateBtn)
        finFrameLayout.addWidget(self.finishDateSelectionBtn)

        # drag event sequence functions

        def dragEnterEvent(self, event):
            if event.mimeData().hasImage:
                event.accept()
            else:
                event.ignore()
                print('event ignored')

        def dragMoveEvent(self, event):
            if event.mimeData().hasImage:
                event.accept()
            else:
                event.ignore()
                print('event ignored')

        def dropEvent(self, event):
            if event.mimeData().hasImage:
                event.setDropAction(Qt.CopyAction)
                img_fp = event.mimeData().urls()[0].toLocalFile()
                print(img_fp)
                self.set_image(img_fp)

                event.accept()
            else:
                event.ignore()
                print('drop event ignored')

        def setImage(self, file_path):
            self.artLabel.setPixmap(QPixmap(file_path))

        # Set Dialog Layout
        self.series_dialog.setLayout(dialog_layout)
        # column 1
        dialog_layout.addWidget(self.artLabel, 1, 1)
        dialog_layout.addWidget(self.titleArtBtn, 2, 1)
        dialog_layout.addWidget(self.addArtFile, 3, 1)
        dialog_layout.addWidget(self.submitEntryBtn, 4, 1)
        # column 2
        dialog_layout.addWidget(self.seriesTitleLabel, 1, 2)
        dialog_layout.addWidget(self.seriesEnglishTitleLabel, 2, 2)
        dialog_layout.addWidget(self.seriesFormatLabel, 3, 2)
        dialog_layout.addWidget(self.startDateLabel, 4, 2)
        dialog_layout.addWidget(self.completionDateLabel, 6, 2)
        dialog_layout.addWidget(self.seriesTypeLabel, 8, 2)
        # column 3
        dialog_layout.addWidget(self.seriesTitle_le, 1, 3)
        dialog_layout.addWidget(self.seriesEnglishTitle_le, 2, 3)
        #dialog_layout.addWidget(self.seriesFormat_le, 3, 3)
        dialog_layout.addWidget(self.seriesFormat_cb, 3, 3)
        dialog_layout.addWidget(self.startDate_le, 4, 3)
        dialog_layout.addWidget(self.formButtonsFrame, 5, 3)  #QGroupBox
        dialog_layout.addWidget(self.completionDate_le, 6, 3)
        dialog_layout.addWidget(self.dateFinBtnsFrame, 7, 3)  #QGroupBox

        dialog_layout.addWidget(self.seriesType_le, 8, 3)

        self.series_dialog.show()

    def insertArtFile(self, lbl):
        artfn = QFileDialog.getOpenFileName(self.mainWindow,
                                            'Choose Title Art', ".",
                                            "Images (*.png *.jpg *.bmp)")

        filename = str(artfn[0])

        chosenart = lbl.setPixmap(QPixmap(filename))

        return chosenart

    def getSeriesArt(self, lbl, txt):
        #self.imgBytes = self.fetchInfo(self.seriesTitle_le.text())
        self.imgBytes = self.fetchInfo(txt)

        titleart = QPixmap()
        titleart.loadFromData(self.imgBytes)

        lbl.setPixmap(QPixmap(titleart))

    def insertStartCurrentDate(self):
        date = QDate.currentDate()
        self.startDate_le.setText(date.toString(Qt.DefaultLocaleShortDate))

    def insertStartDateSelection(self):
        # QCalendarWidget for selection
        pass

    def finishCurrentDate(self):
        date = QDate.currentDate()
        self.completionDate_le.setText(date.toString(
            Qt.DefaultLocaleShortDate))

    def finishDateSelection(self):
        # QCalendarWidget for selection
        pass

    def applicationInfo(self):
        pass

    def entrySubmit(self):

        if self.seriesTitle_le.text() != '':

            # get lineedit texts
            # get the art image
            self.title = self.seriesTitle_le.text()
            self.englishtitle = self.seriesEnglishTitle_le.text()

            self.language = self.seriesFormat_cb.currentText()

            self.start = self.startDate_le.text()
            self.fin = self.completionDate_le.text()
            self.type = self.seriesType_le.text()

            # execute sql insert

            conn = sqlite3.connect('saldb.sqlite')

            cursor = conn.cursor()

            if self.artLabel.pixmap() != None:

                pix = self.artLabel.pixmap()
                b_array = QByteArray()
                buffer = QBuffer(b_array)
                buffer.open(QIODevice.WriteOnly)
                pix.save(buffer, "JPG")
                blob = b_array.data()

            else:

                with open('icons/saldb_darkred.png', 'rb') as file:
                    blob = file.read()
                file.close()

            info_tuple = (blob, self.title, self.englishtitle, self.language,
                          self.start, self.fin, self.type)

            cursor.execute(
                "INSERT INTO watchlist (Art, Title, English_Title, Format, Start_Date ,Completion_Date, Series_Type) VALUES (?, ?, ?, ?, ?, ?, ?)",
                info_tuple)

            conn.commit()

            conn.close()

            rows = self.watchListTable.rowCount()
            self.watchListTable.setRowCount(rows + 1)

            col = 0

            for item in range(len(info_tuple)):
                if col == 0:
                    label = QLabel()
                    label.setScaledContents(True)
                    pixmap = QPixmap()
                    pixmap.loadFromData(info_tuple[item])
                    pixmap.scaled(120, 140, Qt.KeepAspectRatio,
                                  Qt.FastTransformation)
                    label.setPixmap(pixmap)
                    self.watchListTable.setCellWidget(
                        self.watchListTable.rowCount() - 1, col, label)
                else:
                    self.watchListTable.setItem(
                        self.watchListTable.rowCount() - 1, col,
                        QTableWidgetItem(info_tuple[item]))
                col += 1

            self.series_dialog.close()

        else:
            msg_nullTitle = QMessageBox(self.mainWindow)
            msg_nullTitle.setText("Title can not be blank")
            msg_nullTitle.setWindowTitle("Missing Entry Title")

            msg_nullTitle.show()

    def fetchInfo(self, fetchtitle):

        # format url api string with the title?
        api_base = 'https://api.jikan.moe/v3'
        url = api_base + '/search/anime?q={}&page=1'.format(fetchtitle)

        req = requests.get(url)

        resp = req.json()

        seriesImage = resp['results'][0]['image_url']

        getImage = requests.get(seriesImage).content

        # should return image in bytes
        # .content method give image in bytes so should be able to insert it directly into sqlite db

        return getImage

    def settings(self):

        if not os.path.exists("settings"):
            os.mkdir("settings")

        # main window
        mwh = self.mainWindow.height()
        mww = self.mainWindow.width()
        mwx = self.mainWindow.x()
        mwy = self.mainWindow.y()

        # splitter size

        stack_w = self.tableStack.width()
        listw = self.sidebar.width()

        # settings dict
        sal_settings = {
            'mainwindow_height': mwh,
            'mainwindow_width': mww,
            'mainwindow_x': mwx,
            'mainwindow_y': mwy,
            'stack_width': stack_w,
            'list_width': listw
        }

        with open('settings/salsettings.json', 'w') as shit:
            json.dump(sal_settings, shit, indent=4)
        shit.close()

    def newDB(self):
        conn = sqlite3.connect('saldb.sqlite')

        cursor = conn.cursor()

        createTable = "CREATE TABLE IF NOT EXISTS watchlist(Art BLOB, Title TEXT PRIMARY KEY, English_Title TEXT, Format TEXT, Start_Date TEXT ,Completion_Date TEXT, Series_Type TEXT)"

        cursor.execute(createTable)

    def dbLoad(self):

        # pandas vs just for loop over db??

        if os.path.exists('saldb.sqlite'):
            conn = sqlite3.connect('saldb.sqlite')
            cursor = conn.cursor()

        else:
            # qmessagebox to say there was not a 'saldb.sqlite' db found in the directory so a new one will be created.
            dbFileErrorMsg = QMessageBox.question(
                self.mainWindow, 'Error - Database Not Found',
                'saldb.sqlite db file was not found in the current directory press ok and a new one will be created.',
                QMessageBox.Ok, QMessageBox.Cancel)

            if dbFileErrorMsg == QMessageBox.Ok:
                self.newDB()
                conn = sqlite3.connect('saldb.sqlite')
                cursor = conn.cursor()
            else:
                sys.exit()

        sqlGetAll = 'SELECT * FROM watchlist'

        res = cursor.execute(sqlGetAll)

        for row_num, row_data in enumerate(res):
            self.watchListTable.insertRow(row_num)
            for column_number, column_data in enumerate(row_data):
                item = str(column_data)
                if column_number == 0:
                    self.tableLabel = QLabel()
                    self.tableLabel.setScaledContents(True)
                    pixmap = QPixmap()
                    pixmap.loadFromData(column_data)
                    self.tableLabel.setPixmap(pixmap)

                    self.watchListTable.setCellWidget(row_num, column_number,
                                                      self.tableLabel)
                else:
                    self.watchListTable.setItem(row_num, column_number,
                                                QTableWidgetItem(column_data))
            self.watchListTable.verticalHeader().setDefaultSectionSize(140)
            self.watchListTable.horizontalHeader().setDefaultSectionSize(120)

        conn.close()

        if os.path.isfile('settings\salsettings.json'):

            with open('settings\salsettings.json') as fyle:
                data = json.load(fyle)

            self.mainWindow.setGeometry(data['mainwindow_x'],
                                        data['mainwindow_y'],
                                        data['mainwindow_width'],
                                        data['mainwindow_height'])

            self.splitter.setSizes([data['list_width'], data['stack_width']])
Exemple #20
0
    winPlotLayout = QtGui.QGridLayout()
    winPlotWave.setLayout(winPlotLayout)
    winPlotLayout.addWidget(mefDataPlot, 0, 0, 1, 1)
    winPlotLayout.addWidget(mdfDataPlot, 0, 1, 1, 1)
    winPlotLayout.addWidget(arvDataPlot, 1, 0, 1, 1)
    winPlotLayout.addWidget(rmsDataPlot, 1, 1, 1, 1)
    winPlotLayout.addWidget(rawDataPlot, 2, 0, 1, 2)

    win.setCentralWidget(winPlotWave)

    win.resize(1000, 600)

    desktop = QApplication.desktop()
    movex = (desktop.width() - win.width()) // 2
    movey = (desktop.height() - win.height()) // 2
    win.move(0, 0)

    win.show()

    print(' √ Window is ready!')

    while True:
        rawDataCount = 0
        time1 = time.time()
        while rawDataCount < displayDataNumber:
            volData = float(rawData) * voltagePerUnit
            rawDataArray[rawDataCount] = volData
            rawData = ser.readline()
            rawDataCount = rawDataCount + 1
Exemple #21
0
class WAtQtMain(CjAt, TgWai):
    def __init__(self):
        super().__init__()

    def preStart(self):
        self.wn_init()

    def wn_init(self):
        JC_LOG.info(self.tm_wai('Initializing ...'))
        self.wu_mw = QMainWindow()
        self.wu_mw.setWindowTitle(GC_APP_NM)
        self.wu_mw.showEvent = lambda _: self.wn_shown()
        self.wu_mw.closeEvent = lambda _: self.wn_quit()
        self.wu_cw = QWidget()
        self.wu_lo = QVBoxLayout()
        self.wu_pb = QPushButton()
        self.wu_pb.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        self.wu_pb.pressed.connect(self.wn_change_font)
        self.wu_lb = QLabel()
        self.wu_lb.setAlignment(Qt.AlignCenter)
        for bu2_qo in [QWidget(), self.wu_pb, self.wu_lb]:
            self.wu_lo.addWidget(bu2_qo)
        self.wu_cw.setLayout(self.wu_lo)
        self.wu_fnt_families = QFontDatabase().families()
        self.wv_fnt_idx = len(self.wu_fnt_families) - 1
        self.wv_msg = ''
        self.wu_mw.setCentralWidget(self.wu_cw)
        self.wu_mw.resize(650, 200)
        self.wu_mw.show()
        self.wu_mw.raise_()
        self.wn_move_center()
        self.wn_change_font()
        self.getContext().system().scheduler().schedule(
            CjDuration.Zero(), CjDuration.create(100, CjTimeUnit.MILLISECONDS),
            self.getSelf(), CjSymbol('LNextFont'),
            self.getContext().system().dispatcher(), None)

    def receive(self, x_letter, x_atr_sender):
        if jf_is_instance(CjSymbol, x_letter):
            bu2_nm = x_letter.name()
            JC_LOG.debug(self.tm_wai(f'Received symbol {bu2_nm}'))
            if (bu2_nm == 'LNextFont'): self.wn_change_font()

    def wn_change_font(self):
        if self.wv_fnt_idx >= len(self.wu_fnt_families): self.wv_fnt_idx = 0
        nu_fnt_nm = self.wu_fnt_families[self.wv_fnt_idx]
        if self.wv_msg != '': JC_LOG.info(f'[Qt] {self.wv_msg}')
        nu_nt = f'({self.wv_fnt_idx+1}/{len(self.wu_fnt_families)})'
        self.wv_msg = f'0^0 {nu_nt} ({nu_fnt_nm})'
        self.wu_pb.setText(f"Say '{self.wv_msg}'")
        self.wu_pb.setFont(QFont(nu_fnt_nm, 17))
        self.wu_lb.setText(f'{nu_nt} Font name : {nu_fnt_nm}')
        self.wv_fnt_idx += 1
        self.wn_move_center()

    def wn_move_center(self):
        nu_cp = QDesktopWidget().availableGeometry().center()  # center point
        self.wu_mw.move(nu_cp.x() - self.wu_mw.width() / 2,
                        nu_cp.y() - self.wu_mw.height() / 2)

    def wn_shown(self):
        JC_LOG.info('Widget shown ...')

    def wn_quit(self):
        JC_LOG.info(self.tm_wai('About to quit ...'))
        jp_request_exit(GC_EC_SUCCESS)
Exemple #22
0
class TabDialog(QDialog):  ##########主界面
    def __init__(self, parent=None):
        super(TabDialog, self).__init__(parent)
        self.mustupdate = False
        self.setWindowOpacity(0.9)  #设置透明
        self.creatico()  #创建图标
        self.creatui()
        self.creattab()
        self.checkvision()  #运行检查升级函数QMainWindow

    def creatico(self):
        self.icon_title = QIcon()
        self.icon_title.addPixmap(QPixmap(":/img/title.ico"), QIcon.Normal,
                                  QIcon.Off)  #标题图表
        self.icon_save = QIcon()
        self.icon_save.addPixmap(QPixmap(":/img/save.ico"), QIcon.Normal,
                                 QIcon.Off)  #保存图表
        self.icon_help = QIcon()
        self.icon_help.addPixmap(QPixmap(":/img/help.ico"), QIcon.Normal,
                                 QIcon.Off)  # 帮助图表
        self.icon_aboat = QIcon()
        self.icon_aboat.addPixmap(QPixmap(":/img/about.ico"), QIcon.Normal,
                                  QIcon.Off)  #关于图表
        self.icon_github = QIcon()
        self.icon_github.addPixmap(QPixmap(":/img/github.ico"), QIcon.Normal,
                                   QIcon.Off)  #github图表

    def creatui(self):
        self.setWindowTitle('自定义报表程序')
        self.setGeometry(300, 300, 650, 270)
        #self.setFixedSize(self.width(), self.height())
        self.permissionsGroup = QGroupBox("服务器信息")
        self.permissionsLayout = QGridLayout()
        self.setWindowIcon(self.icon_title)
        ###############工具栏##########################
        self.qm = QMainWindow()
        exitAct = QAction(self.icon_save, "保存配置\nCtrl+S", self.qm)
        exitAct.setShortcut("Ctrl+S")
        exitAct.triggered.connect(self.saveconfig)
        self.toolbar = self.qm.addToolBar("save")
        exitAct1 = QAction(self.icon_help, "帮助\nCtrl+H", self.qm)
        exitAct1.setShortcut("Ctrl+H")
        exitAct1.triggered.connect(self.openhelp)
        exitAct2 = QAction(self.icon_aboat, "关于\nCtrl+I", self.qm)
        exitAct2.setShortcut("Ctrl+I")
        exitAct2.triggered.connect(self.openaboat)
        exitAct3 = QAction(self.icon_github, "查看源码\nCtrl+M", self.qm)
        exitAct3.setShortcut("Ctrl+M")
        exitAct3.triggered.connect(self.openaurl)
        self.toolbar.addAction(exitAct)
        self.toolbar.addAction(exitAct1)
        self.toolbar.addAction(exitAct2)
        self.toolbar.addAction(exitAct3)
        self.updatlabel = QLabel('', self.toolbar)
        self.updatlabel.setOpenExternalLinks(True)
        self.updatlabel.setFixedWidth(150)
        self.toolbar.addWidget(self.updatlabel)
        self.toolbar.setMovable(False)
        #self.toolbar.setFloatable(False)
        ###############服务器信息###############
        self.permissionsLayout.addWidget(QLabel('数据库', self.permissionsGroup),
                                         1, 0)
        self.le_host = QLineEdit('', self.permissionsGroup)
        self.le_host.editingFinished.connect(self.initserver)
        self.le_host.setInputMask('000.000.000.000')
        self.le_host.insert(config['server']['host'])
        self.le_host.setFixedWidth(100)
        self.le_host.setToolTip('这里要填数据库的IP')
        #print((self.le_host.height(),self.le_host.width()))
        self.permissionsLayout.addWidget(QLabel('端口', self.permissionsGroup),
                                         1, 2)
        self.le_port = QLineEdit('', self.permissionsGroup)
        self.le_port.setInputMask('99999')
        self.le_port.insert(config['server']['port'])
        self.le_port.editingFinished.connect(self.initserver)
        self.le_port.setFixedWidth(40)
        self.le_port.setToolTip('这里要填数据库的端口\n中联默认1443\n共济默认3307\n栅格默认3306')
        self.permissionsLayout.addWidget(QLabel('用户名', self.permissionsGroup),
                                         1, 4)
        self.le_usr = QLineEdit('', self.permissionsGroup)
        self.le_usr.insert(config['server']['user'])
        self.le_usr.editingFinished.connect(self.initserver)
        self.le_usr.setFixedWidth(40)
        self.le_usr.setToolTip('这里要填数据库的用户名\n中联默认sa\n共济默认gj\n栅格默认mysql')
        self.permissionsLayout.addWidget(QLabel('密码', self.permissionsGroup),
                                         1, 6)
        self.le_passwd = QLineEdit('', self.permissionsGroup)
        self.le_passwd.insert(config['server']['passwd'])
        self.le_passwd.editingFinished.connect(self.initserver)
        self.le_passwd.setFixedWidth(100)
        self.le_passwd.setToolTip(
            '这里要填数据库的密码\n中联无默认值\n共济默认xbrother\n栅格默认mysql')
        self.le_passwd.setEchoMode(QLineEdit.PasswordEchoOnEdit)
        self.permissionsLayout.addWidget(QLabel('数据库名', self.permissionsGroup),
                                         1, 8)
        self.le_db = QLineEdit('', self.permissionsGroup)
        self.le_db.insert(config['server']['db'])
        self.le_db.setFixedWidth(80)
        self.le_db.setToolTip(
            '这里要填数据库名\n中联无默认值\n共济默认historyver1\n栅格默认sgdatabase')
        self.le_db.editingFinished.connect(self.initserver)
        ##################################
        self.permissionsLayout.addWidget(self.le_host, 1, 1)
        self.permissionsLayout.addWidget(self.le_port, 1, 3)
        self.permissionsLayout.addWidget(self.le_usr, 1, 5)
        self.permissionsLayout.addWidget(self.le_passwd, 1, 7)
        self.permissionsLayout.addWidget(self.le_db, 1, 9)
        self.permissionsGroup.setLayout(self.permissionsLayout)
        self.mainLayout = QVBoxLayout()
        self.mainLayout.addWidget(self.qm)
        self.mainLayout.addWidget(self.permissionsGroup)
        self.mainLayout.addStretch(1)
        self.setLayout(self.mainLayout)

    def creattab(self):
        self.tabWidget = QTabWidget()
        self.ts1 = ri(config)
        self.ts2 = zhou()
        self.ts3 = yue(config)
        self.tabWidget.addTab(self.ts1, "日报")
        self.mainLayout.addWidget(self.tabWidget)
        self.tabWidget.addTab(self.ts2, "周报")
        self.mainLayout.addWidget(self.tabWidget)
        self.tabWidget.addTab(self.ts3, "月报")
        self.mainLayout.addWidget(self.tabWidget)

    ###################检测版本########################################
    def compare(self, a, b):  #比较版本号函数
        la = a.split('.')
        lb = b.split('.')
        f = 0
        if len(la) > len(lb):
            f = len(la)
        else:
            f = len(lb)
        for i in range(f):
            try:
                if int(la[i]) > int(lb[i]):
                    return '>'
                elif int(la[i]) == int(lb[i]):
                    continue
                else:
                    if i == 0:
                        self.mustupdate = True
                    else:
                        return '<'
            except IndexError as e:
                if len(la) > len(lb):
                    return '>'
                else:
                    return '<'
        return '='

    def checkvision(self):  # 在线获取版本号
        try:
            url = 'http://wechat.52hengshan.com/weixin/api/v1.0/appvison'
            s = requests.get(url=url, timeout=2).json()
        except:
            self.updatlabel.setText(
                "<html><head/><body><p><span style=\" text-decoration: underline; color:#00ff00;\">无法联网查找最新版本</span></a></p></body></html>"
            )
        else:
            blc_vi = self.compare(blc.vison, s['vison'])
            if blc_vi == '=':
                self.updatlabel.setText(
                    "<html><head/><body><p><span style=\" text-decoration: underline; color:#0000ff;\">已经是最新版本</span></a></p></body></html>"
                )
            elif blc_vi == '>' and not self.mustupdate:
                self.updatlabel.setText(
                    "<html><head/><body><p><span style=\" text-decoration: underline; color:#0000ff;\">你这个是内部版本吧<br>居然比发布版本要高</span></a></p></body></html>"
                )
            elif blc_vi == '<' and not self.mustupdate:
                self.updatlabel.setText(
                    "<html><head/><body><p><a href=\"{}\"><span style=\" text-decoration: underline; color:#ff0000;\">有最新版本,点此升级</span></a></p></body></html>"
                    .format(s['url']))
            elif blc_vi == '<' and self.mustupdate:
                self.tabWidget.setEnabled(False)
                self.updatlabel.setText(
                    "<html><head/><body><p><a href=\"{}\"><span style=\" text-decoration: underline; color:#ff0000;\">此版本有重大风险<br>不建议使用,必须升级</span></a></p></body></html>"
                    .format(s['url']))

    def initserver(self):  ##########从主界面获取的数据存入全局变量
        blc.host = self.le_host.text()
        blc.port = int(self.le_port.text())
        blc.usr = self.le_usr.text()
        blc.passwd = self.le_passwd.text()
        blc.db = self.le_db.text()
        self.ts1.initserverinfo(blc.host, blc.port, blc.usr, blc.passwd,
                                blc.db)

    def openaboat(self):  #######关于菜单的弹窗内容
        self.wid1 = QMainWindow()
        self.wid1.setWindowTitle('关于')
        self.wid1.setGeometry(300, 300, 300, 300)
        self.wid1.setWindowIcon(self.icon_aboat)
        reviewEdit = QTextEdit(self.wid1)
        reviewEdit.setGeometry(0, 0, 300, 300)
        self.wid1.setFixedSize(self.wid1.width(), self.wid1.height())
        reviewEdit.setPlainText(blc.text_about)
        reviewEdit.setReadOnly(True)
        self.wid1.show()

    def openaurl(self):
        QDesktopServices.openUrl(
            QtCore.QUrl('https://github.com/trz0332/bmsreport'))

    def openhelp(self):  ##帮助菜单的弹窗内容
        if path.exists(
                "help.txt"):  #判断help.txt是否存在,如果存在获取帮助文本里面的内容,填充到文本编辑控件显示
            with open('help.txt', 'r') as fb:
                blc.text_help = fb.read()
        else:
            with open('help.txt',
                      'a') as fb:  #如果帮助文本不存下,从默认的帮助变量获取文本,保存到help.txt
                fb.write(blc.text_help)
        self.wid = QMainWindow()
        self.wid.setWindowTitle('帮助')  #帮助窗口标题
        self.wid.setGeometry(300, 300, 600, 400)  #帮助窗口大小
        self.wid.setWindowIcon(self.icon_help)  #帮助窗口图标
        self.reviewEdit = QTextEdit(self.wid)  #定义一个文本编辑控件
        self.reviewEdit.setGeometry(0, 0, 600, 400)  #设置文本编辑控件大小
        self.wid.setFixedSize(self.wid.width(),
                              self.wid.height())  #设置固定大小不允许改变
        self.reviewEdit.setPlainText(blc.text_help)  #帮助文本的内容填入到文本编辑框
        self.reviewEdit.setReadOnly(True)  #制度模式
        self.wid.show()  #展示窗口

    def saveconfig(self):  #保存配置到config.ini
        config.set('server', 'host', self.le_host.text())
        config.set('server', 'port', self.le_port.text())
        config.set('server', 'user', self.le_usr.text())
        config.set('server', 'passwd', self.le_passwd.text())
        config.set('server', 'db', self.le_db.text())
        config.set('sheet_day', 'sjl', self.ts1.sjl.text())
        config.set('sheet_day', 'gzh', self.ts1.gzh.text())
        config.set('sheet_day', 'cj', str(self.ts1.jsComboBox.currentIndex()))
        config.set('sheet_day', 'mode',
                   str(self.ts1.js2ComboBox.currentIndex()))
        config.set('sheet_day', 'filename', str(self.ts1.qtfile.text()))
        with open("config.ini", "w") as fh:
            config.write(fh)
        QMessageBox.information(self, "信息", "配置文件保存成功", QMessageBox.Yes)
class WAtQtMain(CgAt):
    def __init__(self):
        super().__init__()
        self.wn_init()

    def wn_init(self):
        self.wu_wgt = QMainWindow()
        self.wu_wgt.setWindowTitle(GC_APP_NM)
        self.wu_cw = QWidget()
        self.wu_lo = QVBoxLayout()
        self.wu_lo.addLayout(self.wm_init_info())
        self.wu_lo.addWidget(self.wm_init_appdirs())
        self.wu_cw.setLayout(self.wu_lo)
        self.wu_wgt.setCentralWidget(self.wu_cw)
        self.wu_wgt.resize(650, 350)
        self.wu_wgt.show()
        self.wu_wgt.raise_()
        self.wn_move_center()

    def wm_init_info(self):
        self.wu_app_nm = 'MyApp'
        self.wu_app_vr = '1.2.3'
        self.wu_app_au = 'Harawata'
        mu_lo = QGridLayout()
        mu_lo.addWidget(QLabel('Application name'), 0, 0,
                        Qt.AlignRight | Qt.AlignCenter)
        mu_lo.addWidget(QLabel('Application version'), 1, 0,
                        Qt.AlignRight | Qt.AlignCenter)
        mu_lo.addWidget(QLabel('Application author'), 2, 0,
                        Qt.AlignRight | Qt.AlignCenter)

        def mf2_le(x_str):
            fu2_it = QLineEdit()
            fu2_it.setText(x_str)
            fu2_it.setReadOnly(True)
            return fu2_it

        mu_lo.addWidget(mf2_le(self.wu_app_nm), 0, 1,
                        Qt.AlignLeft | Qt.AlignCenter)
        mu_lo.addWidget(mf2_le(self.wu_app_vr), 1, 1,
                        Qt.AlignLeft | Qt.AlignCenter)
        mu_lo.addWidget(mf2_le(self.wu_app_au), 2, 1,
                        Qt.AlignLeft | Qt.AlignCenter)
        for bu2_row in range(3):
            mu_lo.addItem(
                QSpacerItem(1, 1, QSizePolicy.Expanding, QSizePolicy.Minimum),
                bu2_row, 2)
        return mu_lo

    def wm_init_appdirs(self):
        mu_it = QTableWidget(6, 2)
        mu_it.setHorizontalHeaderLabels(('Item', 'Directory'))
        mu_it.horizontalHeader().setStretchLastSection(True)
        mu_it.verticalHeader().setVisible(False)

        def mp2_set_item(x_row, x_item, x_path):
            mu_it.setItem(x_row, 0, QTableWidgetItem(x_item))
            mu_it.setItem(x_row, 1, QTableWidgetItem(x_path))

        mu_app_dirs = gf_jcls(
            'net.harawata.appdirs.AppDirsFactory').getInstance()
        mp2_set_item(
            0, 'User data path',
            gf_ap(
                mu_app_dirs.getUserDataDir(self.wu_app_nm, self.wu_app_vr,
                                           self.wu_app_au)))
        mp2_set_item(
            1, 'User config path',
            gf_ap(
                mu_app_dirs.getUserConfigDir(self.wu_app_nm, self.wu_app_vr,
                                             self.wu_app_au)))
        mp2_set_item(
            2, 'User cache path',
            gf_ap(
                mu_app_dirs.getUserCacheDir(self.wu_app_nm, self.wu_app_vr,
                                            self.wu_app_au)))
        mp2_set_item(
            3, 'User log path',
            gf_ap(
                mu_app_dirs.getUserLogDir(self.wu_app_nm, self.wu_app_vr,
                                          self.wu_app_au)))
        mp2_set_item(
            4, 'Site data path',
            gf_ap(
                mu_app_dirs.getSiteDataDir(self.wu_app_nm, self.wu_app_vr,
                                           self.wu_app_au)))
        mp2_set_item(
            5, 'Site config path',
            gf_ap(
                mu_app_dirs.getSiteConfigDir(self.wu_app_nm, self.wu_app_vr,
                                             self.wu_app_au)))
        mu_it.resizeColumnsToContents()
        return mu_it

    def wn_move_center(self):
        nu_cp = QDesktopWidget().availableGeometry().center()  # center point
        self.wu_wgt.move(nu_cp.x() - self.wu_wgt.width() / 2,
                         nu_cp.y() - self.wu_wgt.height() / 2)