Ejemplo n.º 1
0
class NewReminderWindow(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.resize(500, 250)
        self.setWindowTitle('Add New Reminder')

        self.new_reminder_text_input = QPlainTextEdit()
        self.new_reminder_text_input.setFixedHeight(90)
        self.new_reminder_text_input.setFixedWidth(500)

        self.cancel_button = QPushButton('Cancel')
        self.cancel_button.setFixedWidth(
            self.cancel_button.minimumSizeHint().width())
        self.cancel_button.clicked.connect(self.on_cancel_clicked)
        self.save_button = QPushButton('Save')
        self.save_button.setFixedWidth(
            (self.save_button.minimumSizeHint().width()))

        self.v_box = QVBoxLayout()
        self.h_box1 = QHBoxLayout()
        self.h_box1.addWidget(self.new_reminder_text_input,
                              alignment=Qt.AlignHCenter)
        self.h_box2 = QHBoxLayout()
        self.h_box2.addWidget(self.cancel_button)
        self.h_box2.addWidget(self.save_button)
        self.v_box.addLayout(self.h_box1)
        self.v_box.addLayout(self.h_box2)
        self.setLayout(self.v_box)

    @Slot()
    def on_cancel_clicked(self):
        self.hide()
        self.new_reminder_text_input.clear()
Ejemplo n.º 2
0
class Log(QWidget):
    def __init__(self, sender, title=''):
        super(Log, self).__init__()

        self.main_layout = QVBoxLayout()
        self.header_layout = QHBoxLayout()

        title_label = QLabel(title)
        title_label.setFont(QFont('Poppins', 13))
        self.header_layout.addWidget(title_label)

        holder_label = QLabel(str(sender))
        holder_label.setWordWrap(True)
        self.log_view = QPlainTextEdit()
        self.log_view.setReadOnly(True)

        self.main_layout.addLayout(self.header_layout)
        self.main_layout.addWidget(holder_label)
        self.main_layout.addWidget(self.log_view)

        self.setLayout(self.main_layout)

        self.setStyleSheet('''
            QLabel {
                border: None;
            }
            QWidget {
                color: #e9f4fb;
            }
        ''')

    def log(self, *args):
        s = ''
        for arg in args:
            s += ' ' + str(arg)
        self.log_view.appendPlainText('>  ' + s)

    def clear(self):
        self.log_view.clear()

    def removing(self):  # old method, delete later
        self.remove()

    def remove(self):
        self.log_view.setStyleSheet('background: black; color: grey;')

        remove_button = QPushButton('x')
        remove_button.clicked.connect(self.remove_clicked)

        self.header_layout.addWidget(remove_button)

    def remove_clicked(self):
        self.setParent(None)  # removes the widget
Ejemplo n.º 3
0
class MainWindow(QMainWindow):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.setObjectName("main_window")
        self.setEnabled(True)
        self.resize(608, 248)
        size_policy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        size_policy.setHorizontalStretch(0)
        size_policy.setVerticalStretch(0)
        size_policy.setHeightForWidth(self.sizePolicy().hasHeightForWidth())
        self.setSizePolicy(size_policy)
        self.setAcceptDrops(True)
        self.setWindowTitle("FileHookPi")

        self.central_widget = QWidget(self)
        self.central_widget.setObjectName("central_widget")

        self.horizontalLayout = QHBoxLayout(self.central_widget)
        self.horizontalLayout.setObjectName("horizontalLayout")

        self.text_box = QPlainTextEdit(self.central_widget)
        self.text_box.setAcceptDrops(False)
        self.text_box.setReadOnly(True)
        self.text_box.setObjectName("text_box")

        self.horizontalLayout.addWidget(self.text_box)

        self.buttons_vertical_layout = QVBoxLayout()
        self.buttons_vertical_layout.setObjectName("buttons_vertical_layout")

        self.open_file_button = QPushButton(self.central_widget)
        self.open_file_button.setText("Open File")
        self.open_file_button.setObjectName("open_file_button")
        self.open_file_button.clicked.connect(self.select_file)

        self.buttons_vertical_layout.addWidget(self.open_file_button)

        self.line_counter = QLineEdit(self.central_widget)
        size_policy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
        size_policy.setHorizontalStretch(0)
        size_policy.setVerticalStretch(0)
        size_policy.setHeightForWidth(
            self.line_counter.sizePolicy().hasHeightForWidth())
        self.line_counter.setSizePolicy(size_policy)
        self.line_counter.setAcceptDrops(False)
        self.line_counter.setReadOnly(True)
        self.line_counter.setObjectName("line_counter")

        self.buttons_vertical_layout.addWidget(self.line_counter)

        self.next_line_button = QPushButton(self.central_widget)
        self.next_line_button.setText("Next Line")
        self.next_line_button.setObjectName("next_line_button")
        self.next_line_button.clicked.connect(self.advance_line)

        self.buttons_vertical_layout.addWidget(self.next_line_button)

        self.horizontalLayout.addLayout(self.buttons_vertical_layout)

        self.menuBar().addMenu(FileMenu(self))

        self.setCentralWidget(self.central_widget)

        self.current_file = None
        self.line_count = 0

    def select_file(self, *, advance=True):
        path, *_ = QFileDialog.getOpenFileName(self,
                                               "Open File",
                                               filter="Text Files (*.txt)")

        if not path:
            return

        self.open_file(path, advance=advance)

    def open_file(self, path, *, advance=True):
        if self.current_file is not None:
            self.cleanup()

        self.current_file = open(path, "r", encoding="utf-8")
        self.setWindowFilePath(path)

        if advance:
            self.advance_line()

    def advance_line(self):
        if self.current_file is None:
            return

        try:
            line = self.current_file.readline()
        except Exception as exc:
            message_box = QMessageBox(
                parent=self,
                text=f"Failed to read:\n{type(exc).__name__}: {exc}",
                icon=QMessageBox.Critical)
            message_box.setInformativeText("Close the file?")
            message_box.setStandardButtons(QMessageBox.No | QMessageBox.Yes)
            message_box.setDefaultButton(QMessageBox.Yes)

            if message_box.exec_() == QMessageBox.Yes:
                self.cleanup()

            return

        if not line:
            return

        self.line_count += 1
        self.line_counter.setText(str(self.line_count))
        QApplication.clipboard().setText(line.rstrip("\n"))
        self.text_box.setPlainText(line + self.text_box.toPlainText())

    def cleanup(self):
        if self.current_file is not None:
            self.current_file.close()
            self.current_file = None

        self.text_box.clear()
        self.line_count = 0
        self.line_counter.clear()
        self.setWindowFilePath("")

    def dragEnterEvent(self, event):
        urls = event.mimeData().urls()

        if urls and os.path.isfile(urls[0].path()):
            event.accept()

    def dropEvent(self, event):
        self.open_file(event.mimeData().urls()[0].path())

    def closeEvent(self, event):
        self.cleanup()
        event.accept()
Ejemplo n.º 4
0
class Widget(QWidget):

    movie_url_label_text = "粘贴有 dailymotion 版的連續劇网址 (例子: https://dramaq.de/cn191023b/): "

    def __init__(self):
        QWidget.__init__(self)

        self.q = None
        self.pool = None

        self.top = QHBoxLayout()
        self.top.setMargin(10)

        self.middle = QVBoxLayout()
        self.middle.setMargin(10)

        self.radioButtonDailyMotionDrama = QRadioButton(
            "有 Dailymotion Drama 的網站")
        self.radioButtonAny = QRadioButton("其它類型網站 (例如 YouTube)")

        self.top.addWidget(self.radioButtonDailyMotionDrama)
        self.top.addWidget(self.radioButtonAny)

        self.url_label = QLabel()
        self.url = QLineEdit()
        self.url_label.setBuddy(self.url)
        self.middle.addWidget(self.url_label)
        self.middle.addWidget(self.url)

        self.browse_folder_label = QLabel("下載到:")
        self.browseFolder = QPushButton("選擇目錄")
        self.browse_folder_label.setBuddy(self.browseFolder)
        self.middle.addWidget(self.browse_folder_label)
        self.middle.addWidget(self.browseFolder)
        self.browse_folder_value = ""

        self.bk_cinemae_spin_from = 1
        self.bk_cinemae_spin_to = 1
        self.fromEpSpinBox = QSpinBox()
        self.fromEpSpinBox.setMinimum(1)
        self.fromEpSpinBox.setMaximum(2147483647)
        self.fromEpLabel = QLabel("&從第幾集開始下載:")
        self.fromEpLabel.setBuddy(self.fromEpSpinBox)

        self.toEpSpinBox = QSpinBox()
        self.toEpSpinBox.setMinimum(1)
        self.toEpSpinBox.setMaximum(2147483647)
        self.toEpLabel = QLabel("&到第幾集停止下載:")
        self.toEpLabel.setBuddy(self.toEpSpinBox)

        self.cinema_ly = QHBoxLayout()
        #self.cinema_ly.setMargin(10)
        self.cinema_ly.addWidget(self.fromEpLabel)
        self.cinema_ly.addWidget(self.fromEpSpinBox)
        self.cinema_ly.addWidget(self.toEpLabel)
        self.cinema_ly.addWidget(self.toEpSpinBox)
        self.middle.addLayout(self.cinema_ly)

        self.add = QPushButton("開始下載")
        self.add.setEnabled(False)
        self.middle.addWidget(self.add)

        self.stop_me = QPushButton("停止下載")
        self.stop_me.setEnabled(False)
        self.middle.addWidget(self.stop_me)

        self.log_area = QPlainTextEdit()
        self.log_area.setReadOnly(True)
        self.log_area.setMaximumBlockCount(1000)
        self.middle.addWidget(self.log_area)

        #self.table_view.setSizePolicy(size)
        #self.layout.addWidget(self.table)
        self.layout = QVBoxLayout()
        self.layout.addLayout(self.top)
        self.layout.addLayout(self.middle)
        self.setLayout(self.layout)

        self.radioButtonDailyMotionDrama.toggled.connect(
            self.choose_DailyMotionDrama_widgets)
        self.radioButtonAny.toggled.connect(self.choose_Any_widgets)
        self.url.textChanged[str].connect(self.check_disable_download)
        self.browseFolder.clicked.connect(self.add_folder)
        self.add.clicked.connect(self.start_download)
        self.stop_me.clicked.connect(self.stop_download)

        self.radioButtonDailyMotionDrama.setChecked(
            True)  #set default only after .connect above

        # TESTING PURPOSE
        '''
        self.url.setText('https://journalflash.com/cn191023b/')
        self.browse_folder_value = 'C:/Users/Administrator/Documents/duboku'
        '''

        #set current process (not queue that one) log handler:
        logger = logging.getLogger(__name__)
        handler2 = LoggerWriter()
        logger.addHandler(handler2)
        logger.setLevel(logging.INFO)  #DEBUG
        handler2.emitter.sigLog.connect(self.log_area.appendPlainText)
        sys.stdout = handler2  #LoggerWriter()
        #sys.stderr = handler2 #Seems no difference
        #handler2.emitter.sigLog.emit('hihi')

    @Slot()
    def choose_DailyMotionDrama_widgets(self):

        if self.radioButtonDailyMotionDrama.isChecked():

            self.fromEpLabel.setEnabled(True)
            self.toEpLabel.setEnabled(True)

            self.fromEpSpinBox.setEnabled(True)
            self.toEpSpinBox.setEnabled(True)

            self.fromEpSpinBox.setValue(self.bk_cinemae_spin_from)
            self.toEpSpinBox.setValue(self.bk_cinemae_spin_to)
            self.fromEpLabel.setDisabled(True)
            self.toEpLabel.setDisabled(True)

    @Slot()
    def choose_Any_widgets(self):

        if self.radioButtonAny.isChecked():

            self.fromEpSpinBox.setDisabled(True)
            self.toEpSpinBox.setDisabled(True)

            self.bk_cinemae_spin_from = self.fromEpSpinBox.value()
            self.bk_cinemae_spin_to = self.toEpSpinBox.value()
            self.fromEpSpinBox.setValue(1)
            self.toEpSpinBox.setValue(1)

    @Slot()
    def add_folder(self, s):

        #fname = QFileDialog.getOpenFileName(self, 'Open file', "c:\'", "Image files (*.jpg *.gif)")
        #fname = QFileDialog.getOpenFileName(self, 'Open file', '', QFileDialog.ShowDirsOnly)
        fname = QFileDialog.getExistingDirectory(self, '選擇下載至什麼目錄', '',
                                                 QFileDialog.ShowDirsOnly)
        #print('repr: ' + repr(fname))
        if fname and fname.strip():
            fname = fname.strip()
            self.browse_folder_value = fname
            #if getOpenFileName, will return ('/home/xiaobai/Pictures/disco.jpg', 'Image files (*.jpg *.gif)')
            #, while if getExistingDirectory, will return single path string only
            self.browseFolder.setText(fname)
            self.check_disable_download(fname)
        #else:
        #    print('User cancel')

    @Slot()
    def check_disable_download(self, s):

        if self.url.text() and self.browse_folder_value:
            self.add.setEnabled(True)
        else:
            self.add.setEnabled(False)

    def task_done(self, retVal):
        self.add.setEnabled(True)
        self.stop_me.setEnabled(False)

    @Slot()
    def stop_download(self):
        if self.q:
            self.q.close()
        if self.pool:
            self.pool.terminate()
        self.add.setEnabled(True)
        self.stop_me.setEnabled(False)
        print('下載停止。')

    @Slot()
    def start_download(self):

        if self.fromEpSpinBox.value() > self.toEpSpinBox.value():
            self.log_area.setPlainText('[!] 從第幾集必須小於或等於到第幾集。')
            return

        #No need worry click twice too fast, it seems already handle by PySide2
        self.add.setEnabled(False)
        self.stop_me.setEnabled(True)
        self.log_area.clear()

        dest_full_path = self.browse_folder_value
        '''
        print('dest_full_path: ' + repr(dest_full_path))
        print('self.url.text(): ' + repr(self.url.text()))
        print('self.fromEpSpinBox.value(): ' + repr(self.fromEpSpinBox.value()))
        print('self.toEpSpinBox.value(): ' + repr(self.toEpSpinBox.value()))
        '''

        import drama_dailymotion_console

        #Windows can't set like that bcoz not update for args.url, must put explicitly
        #drama_dailymotion_console.redirect_stdout_to_custom_stdout(arg_url, ...etc, LoggerWriter())

        #failed other process
        handler = LogHandlerOtherProcess()
        handler.emitter.sigLog.connect(self.log_area.appendPlainText)
        ''' #ref current process:
        logger = logging.getLogger(__name__)
        handler2 = LoggerWriter()
        logger.addHandler(handler2)
        logger.setLevel(logging.DEBUG)
        handler2.emitter.sigLog.connect(self.log_area.appendPlainText)
        sys.stdout = handler2 #LoggerWriter()
        #handler2.emitter.sigLog.emit('hihi')
        '''

        #handler = LoggerWriter()
        #handler.emitter.sigLog.connect(self.log_area.appendPlainText)

        self.q = multiprocessing.Queue()
        self.ql = QueueListener(self.q, handler)
        self.ql.start()

        self.pool = multiprocessing.Pool(1, worker_init, [self.q])

        if self.radioButtonDailyMotionDrama.isChecked():
            self.pool.apply_async(drama_dailymotion_console.main,
                                  args=(dest_full_path,
                                        self.fromEpSpinBox.value(),
                                        self.toEpSpinBox.value(),
                                        self.url.text(),
                                        LoggerWriterOtherProcess(), False),
                                  callback=self.task_done)
        else:
            self.pool.apply_async(drama_dailymotion_console.main,
                                  args=(dest_full_path,
                                        self.fromEpSpinBox.value(),
                                        self.toEpSpinBox.value(),
                                        self.url.text(),
                                        LoggerWriterOtherProcess(), True),
                                  callback=self.task_done)
Ejemplo n.º 5
0
class MainWindow(QMainWindow):
    def __init__(self, application, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)

        self.printer_thread = WorkerThread()
        self.printer_thread.message.connect(self.standardOutputWritten)
        self.printer_thread.start()

        self.app = application
        self.app.setStyle("Fusion")

        self.__set_interface()
        self.__set_layouts()
        self.__set_stylesheet()
        self.__set_connections()
        self.__set_params()

    def closeEvent(self, event):
        self.printer_thread.stop()

    def __set_interface(self):
        self.button_width = 0.35
        self.button_height = 0.05

        self.setWindowTitle("GSI-RADS")
        self.__getScreenDimensions()

        self.setGeometry(self.left, self.top, self.width, self.height)
        self.setMaximumWidth(self.width)
        #self.setMaximumHeight(self.height)
        self.setMinimumWidth(self.width)
        self.setMinimumHeight(self.height)
        self.move(self.width / 2, self.height / 2)

        self.menu_bar = QMenuBar(self)
        self.menu_bar.setNativeMenuBar(
            False
        )  # https://stackoverflow.com/questions/25261760/menubar-not-showing-for-simple-qmainwindow-code-qt-creator-mac-os
        self.file_menu = self.menu_bar.addMenu('File')
        self.import_dicom_action = QAction(
            QIcon(
                os.path.join(os.path.dirname(os.path.realpath(__file__)),
                             'images/database-icon.png')), 'Import DICOM',
            self)
        self.import_dicom_action.setShortcut('Ctrl+D')
        self.file_menu.addAction(self.import_dicom_action)
        self.quit_action = QAction('Quit', self)
        self.quit_action.setShortcut("Ctrl+Q")
        self.file_menu.addAction(self.quit_action)

        self.settings_menu = self.menu_bar.addMenu('Settings')
        self.settings_seg_menu = self.settings_menu.addMenu("Segmentation...")
        self.settings_seg_preproc_menu = self.settings_seg_menu.addMenu(
            "Preprocessing...")
        self.settings_seg_preproc_menu_p1_action = QAction(
            "Brain-masking off (P1)", checkable=True)
        self.settings_seg_preproc_menu_p2_action = QAction(
            "Brain-masking on (P2)", checkable=True)
        self.settings_seg_preproc_menu_p2_action.setChecked(True)
        self.settings_seg_preproc_menu.addAction(
            self.settings_seg_preproc_menu_p1_action)
        self.settings_seg_preproc_menu.addAction(
            self.settings_seg_preproc_menu_p2_action)

        self.help_menu = self.menu_bar.addMenu('Help')
        self.readme_action = QAction(
            QIcon(
                os.path.join(os.path.dirname(os.path.realpath(__file__)),
                             'images/readme-icon.jpeg')), 'Tutorial', self)
        self.readme_action.setShortcut("Ctrl+R")
        self.help_menu.addAction(self.readme_action)
        self.about_action = QAction(
            QIcon(
                os.path.join(os.path.dirname(os.path.realpath(__file__)),
                             'images/about-icon.png')), 'About', self)
        self.about_action.setShortcut("Ctrl+A")
        self.help_menu.addAction(self.about_action)
        self.help_action = QAction(
            QIcon.fromTheme("help-faq"), "Help", self
        )  # Default icons can be found here: https://specifications.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html#guidelines
        self.help_action.setShortcut("Ctrl+J")
        self.help_menu.addAction(self.help_action)

        self.input_image_lineedit = QLineEdit()
        self.input_image_lineedit.setFixedWidth(self.width *
                                                (0.93 - self.button_width / 2))
        self.input_image_lineedit.setFixedHeight(self.height *
                                                 self.button_height)
        self.input_image_lineedit.setReadOnly(True)
        self.input_image_pushbutton = QPushButton('Input MRI')
        self.input_image_pushbutton.setFixedWidth(self.height *
                                                  self.button_width)
        self.input_image_pushbutton.setFixedHeight(self.height *
                                                   self.button_height)

        self.input_segmentation_lineedit = QLineEdit()
        self.input_segmentation_lineedit.setReadOnly(True)
        self.input_segmentation_lineedit.setFixedWidth(
            self.width * (0.93 - self.button_width / 2))
        self.input_segmentation_lineedit.setFixedHeight(self.height *
                                                        self.button_height)
        self.input_segmentation_pushbutton = QPushButton('Input segmentation')
        self.input_segmentation_pushbutton.setFixedWidth(self.height *
                                                         self.button_width)
        self.input_segmentation_pushbutton.setFixedHeight(self.height *
                                                          self.button_height)

        self.output_folder_lineedit = QLineEdit()
        self.output_folder_lineedit.setReadOnly(True)
        self.output_folder_lineedit.setFixedWidth(
            self.width * (0.93 - self.button_width / 2))
        self.output_folder_lineedit.setFixedHeight(self.height *
                                                   self.button_height)
        self.output_folder_pushbutton = QPushButton('Output destination')
        self.output_folder_pushbutton.setFixedWidth(self.height *
                                                    self.button_width)
        self.output_folder_pushbutton.setFixedHeight(self.height *
                                                     self.button_height)

        self.run_button = QPushButton('Run diagnosis')
        self.run_button.setFixedWidth(self.height * self.button_width)
        self.run_button.setFixedHeight(self.height * self.button_height)

        self.main_display_tabwidget = QTabWidget()

        self.tutorial_textedit = QPlainTextEdit()
        self.tutorial_textedit.setReadOnly(True)
        self.tutorial_textedit.setFixedWidth(self.width * 0.97)
        self.tutorial_textedit.setPlainText(
            "HOW TO USE THE SOFTWARE: \n"
            "  1) Click 'Input MRI...' to select from your file explorer the MRI scan to process (unique file).\n"
            "  1*) Alternatively, Click File > Import DICOM... if you wish to process an MRI scan as a DICOM sequence.\n"
            "  2) Click 'Output destination' to choose a directory where to save the results \n"
            "  3) (OPTIONAL) Click 'Input segmentation' to choose a tumor segmentation mask file, if nothing is provided the internal model with generate the segmentation automatically \n"
            "  4) Click 'Run diagnosis' to perform the analysis. The human-readable version will be displayed in the interface.\n"
            " \n"
            "NOTE: \n"
            "The output folder is populated automatically with the following: \n"
            "  * The diagnosis results in human-readable text (report.txt) and Excel-ready format (report.csv).\n"
            "  * The automatic segmentation masks of the brain and the tumor in the original patient space (input_brain_mask.nii.gz and input_tumor_mask.nii.gz).\n"
            "  * The input volume and tumor segmentation mask in MNI space in the sub-directory named \'registration\'.\n"
        )
        self.main_display_tabwidget.addTab(self.tutorial_textedit, 'Tutorial')
        self.prompt_lineedit = QPlainTextEdit()
        self.prompt_lineedit.setReadOnly(True)
        self.prompt_lineedit.setFixedWidth(self.width * 0.97)
        self.main_display_tabwidget.addTab(self.prompt_lineedit, 'Logging')
        self.results_textedit = QPlainTextEdit()
        self.results_textedit.setReadOnly(True)
        self.results_textedit.setFixedWidth(self.width * 0.97)
        self.main_display_tabwidget.addTab(self.results_textedit, 'Results')

        self.sintef_logo_label = QLabel()
        self.sintef_logo_label.setPixmap(
            QPixmap(
                os.path.join(os.path.dirname(os.path.realpath(__file__)),
                             'images/sintef-logo.png')))
        self.sintef_logo_label.setFixedWidth(0.95 * (self.width / 3))
        self.sintef_logo_label.setFixedHeight(
            1 * (self.height * self.button_height))
        self.sintef_logo_label.setScaledContents(True)
        self.stolavs_logo_label = QLabel()
        self.stolavs_logo_label.setPixmap(
            QPixmap(
                os.path.join(os.path.dirname(os.path.realpath(__file__)),
                             'images/stolavs-logo.png')))
        self.stolavs_logo_label.setFixedWidth(0.95 * (self.width / 3))
        self.stolavs_logo_label.setFixedHeight(
            1 * (self.height * self.button_height))
        self.stolavs_logo_label.setScaledContents(True)
        self.amsterdam_logo_label = QLabel()
        self.amsterdam_logo_label.setPixmap(
            QPixmap(
                os.path.join(os.path.dirname(os.path.realpath(__file__)),
                             'images/amsterdam-logo.png')))
        self.amsterdam_logo_label.setFixedWidth(0.95 * (self.width / 3))
        self.amsterdam_logo_label.setFixedHeight(
            1 * (self.height * self.button_height))
        self.amsterdam_logo_label.setScaledContents(True)

    def __set_layouts(self):
        self.input_volume_hbox = QHBoxLayout()
        self.input_volume_hbox.addStretch(1)
        self.input_volume_hbox.addWidget(self.input_image_lineedit)
        self.input_volume_hbox.addWidget(self.input_image_pushbutton)
        self.input_volume_hbox.addStretch(1)

        self.input_seg_hbox = QHBoxLayout()
        self.input_seg_hbox.addStretch(1)
        self.input_seg_hbox.addWidget(self.input_segmentation_lineedit)
        self.input_seg_hbox.addWidget(self.input_segmentation_pushbutton)
        self.input_seg_hbox.addStretch(1)

        self.output_dir_hbox = QHBoxLayout()
        self.output_dir_hbox.addStretch(1)
        self.output_dir_hbox.addWidget(self.output_folder_lineedit)
        self.output_dir_hbox.addWidget(self.output_folder_pushbutton)
        self.output_dir_hbox.addStretch(1)

        self.run_action_hbox = QHBoxLayout()
        self.run_action_hbox.addStretch(1)
        self.run_action_hbox.addWidget(self.run_button)
        self.run_action_hbox.addStretch(1)

        self.dump_area_hbox = QHBoxLayout()
        self.dump_area_hbox.addStretch(1)
        self.dump_area_hbox.addWidget(self.main_display_tabwidget)
        self.dump_area_hbox.addStretch(1)

        self.logos_hbox = QHBoxLayout()
        self.logos_hbox.addStretch(1)
        self.logos_hbox.addWidget(self.sintef_logo_label)
        self.logos_hbox.addWidget(self.stolavs_logo_label)
        self.logos_hbox.addWidget(self.amsterdam_logo_label)
        self.logos_hbox.addStretch(1)

        self.main_vbox = QVBoxLayout()
        self.main_vbox.addWidget(self.menu_bar)
        #self.main_vbox.addStretch(1)
        self.main_vbox.addLayout(self.input_volume_hbox)
        self.main_vbox.addLayout(self.output_dir_hbox)
        self.main_vbox.addLayout(self.input_seg_hbox)
        self.main_vbox.addLayout(self.run_action_hbox)
        #self.main_vbox.addStretch(1)
        self.main_vbox.addLayout(self.dump_area_hbox)
        self.main_vbox.addLayout(self.logos_hbox)
        #self.main_vbox.addStretch(1)

        self.central_label = QLabel()
        self.central_label.setLayout(self.main_vbox)
        self.setCentralWidget(self.central_label)

    def __set_stylesheet(self):
        self.central_label.setStyleSheet(
            'QLabel{background-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(207, 209, 207, 255), stop:1 rgba(230, 229, 230, 255));}'
        )
        self.menu_bar.setStyleSheet(get_stylesheet('QMenuBar'))
        self.input_image_lineedit.setStyleSheet(get_stylesheet('QLineEdit'))
        self.input_image_pushbutton.setStyleSheet(
            get_stylesheet('QPushButton'))
        self.input_segmentation_lineedit.setStyleSheet(
            get_stylesheet('QLineEdit'))
        self.input_segmentation_pushbutton.setStyleSheet(
            get_stylesheet('QPushButton'))
        self.output_folder_lineedit.setStyleSheet(get_stylesheet('QLineEdit'))
        self.output_folder_pushbutton.setStyleSheet(
            get_stylesheet('QPushButton'))

        self.results_textedit.setStyleSheet(get_stylesheet('QTextEdit'))
        self.prompt_lineedit.setStyleSheet(get_stylesheet('QTextEdit'))

        self.run_button.setStyleSheet(get_stylesheet('QPushButton'))

    def __set_connections(self):
        self.run_button.clicked.connect(self.diagnose_main_wrapper)
        self.input_image_pushbutton.clicked.connect(
            self.run_select_input_image)
        self.input_segmentation_pushbutton.clicked.connect(
            self.run_select_input_segmentation)
        self.output_folder_pushbutton.clicked.connect(
            self.run_select_output_folder)

        self.readme_action.triggered.connect(self.readme_action_triggered)
        self.about_action.triggered.connect(self.about_action_triggered)
        self.quit_action.triggered.connect(self.quit_action_triggered)
        self.import_dicom_action.triggered.connect(
            self.import_dicom_action_triggered)
        self.help_action.triggered.connect(self.help_action_triggered)
        self.settings_seg_preproc_menu_p1_action.triggered.connect(
            self.settings_seg_preproc_menu_p1_action_triggered)
        self.settings_seg_preproc_menu_p2_action.triggered.connect(
            self.settings_seg_preproc_menu_p2_action_triggered)

    def __set_params(self):
        self.input_image_filepath = ''
        self.input_annotation_filepath = ''
        self.output_folderpath = ''

    def __getScreenDimensions(self):
        screen = self.app.primaryScreen()
        size = screen.size()

        self.left = size.width() / 2
        self.top = size.height() / 2
        self.width = 0.4 * size.width()
        self.height = 0.4 * size.height()

    def readme_action_triggered(self):
        popup = QMessageBox()
        popup.setWindowTitle('Tutorial')
        popup.setText(
            "HOW TO USE THE SOFTWARE: \n"
            "  1) Click 'Input MRI...' to select from your file explorer the MRI scan to process (unique file).\n"
            "  1*) Alternatively, Click File > Import DICOM... if you wish to process an MRI scan as a DICOM sequence.\n"
            "  2) Click 'Output destination' to choose a directory where to save the results \n"
            "  3) (OPTIONAL) Click 'Input segmentation' to choose a tumor segmentation mask file, if nothing is provided the internal model with generate the segmentation automatically \n"
            "  4) Click 'Run diagnosis' to perform the analysis. The human-readable version will be displayed in the interface.\n"
            " \n"
            "NOTE: \n"
            "The output folder is populated automatically with the following: \n"
            "  * The diagnosis results in human-readable text (report.txt) and Excel-ready format (report.csv).\n"
            "  * The automatic segmentation masks of the brain and the tumor in the original patient space (input_brain_mask.nii.gz and input_tumor_mask.nii.gz).\n"
            "  * The input volume and tumor segmentation mask in MNI space in the sub-directory named \'registration\'.\n"
        )
        popup.exec_()

    def about_action_triggered(self):
        popup = QMessageBox()
        popup.setWindowTitle('About')
        popup.setText(
            'Software developed as part of a collaboration between: \n'
            '  * Departement of Health Research, SINTEF\n'
            '  * St. Olavs hospital, Trondheim University Hospital\n'
            '  * Amsterdam University Medical Center\n\n'
            'Contact: David Bouget, Andre Pedersen\n\n'
            'For questions about the software, please visit:\n'
            'https://github.com/SINTEFMedtek/GSI-RADS\n'
            'For questions about the methodological aspect, please refer to the original publication:\n'
            'https://www.mdpi.com/2072-6694/13/12/2854/review_report')
        popup.exec_()

    def quit_action_triggered(self):
        self.printer_thread.stop()
        sys.exit()

    def diagnose_main_wrapper(self):
        self.run_diagnosis_thread = threading.Thread(target=self.run_diagnosis)
        self.run_diagnosis_thread.daemon = True  # using daemon thread the thread is killed gracefully if program is abruptly closed
        self.run_diagnosis_thread.start()

    def run_diagnosis(self):
        if not os.path.exists(self.input_image_filepath) or not os.path.exists(
                self.output_folderpath):
            self.standardOutputWritten(
                'Process could not be started - The 1st and 2nd above-fields must be filled in.\n'
            )
            return

        self.run_button.setEnabled(False)
        self.prompt_lineedit.clear()
        self.main_display_tabwidget.setCurrentIndex(1)
        QApplication.processEvents(
        )  # to immidiently update GUI after button is clicked
        self.seg_preprocessing_scheme = 'P1' if self.settings_seg_preproc_menu_p1_action.isChecked(
        ) else 'P2'

        try:
            start_time = time.time()
            print('Initialize - Begin (Step 0/6)')
            from diagnosis.main import diagnose_main
            print('Initialize - End (Step 0/6)')
            print('Step runtime: {} seconds.'.format(
                np.round(time.time() - start_time, 3)) + "\n")
            diagnose_main(
                input_volume_filename=self.input_image_filepath,
                input_segmentation_filename=self.input_annotation_filepath,
                output_folder=self.output_folderpath,
                preprocessing_scheme=self.seg_preprocessing_scheme)
        except Exception as e:
            print('{}'.format(traceback.format_exc()))
            self.run_button.setEnabled(True)
            self.standardOutputWritten(
                'Process could not be completed - Issue arose.\n')
            QApplication.processEvents()
            return

        self.run_button.setEnabled(True)
        results_filepath = os.path.join(
            ResourcesConfiguration.getInstance().output_folder, 'report.txt')
        self.results_textedit.setPlainText(open(results_filepath, 'r').read())
        self.main_display_tabwidget.setCurrentIndex(2)

    def run_select_input_image(self):
        input_image_filedialog = QFileDialog()
        self.input_image_filepath = input_image_filedialog.getOpenFileName(
            self, 'Select input T1 MRI', '~',
            "Image files (*.nii *.nii.gz *.nrrd *.mha *.mhd)")[0]
        self.input_image_lineedit.setText(self.input_image_filepath)

    def run_select_input_segmentation(self):
        filedialog = QFileDialog()
        self.input_annotation_filepath = filedialog.getOpenFileName(
            self, 'Select input segmentation file', '~',
            "Image files (*.nii *.nii.gz)")[0]
        self.input_segmentation_lineedit.setText(
            self.input_annotation_filepath)

    def import_dicom_action_triggered(self):
        filedialog = QFileDialog()
        filedialog.setFileMode(QFileDialog.DirectoryOnly)
        self.input_image_filepath = filedialog.getExistingDirectory(
            self, 'Select DICOM folder', '~')
        self.input_image_lineedit.setText(self.input_image_filepath)

    def run_select_output_folder(self):
        filedialog = QFileDialog()
        filedialog.setFileMode(QFileDialog.DirectoryOnly)
        self.output_folderpath = filedialog.getExistingDirectory(
            self, 'Select output folder', '~')
        self.output_folder_lineedit.setText(self.output_folderpath)

    def standardOutputWritten(self, text):
        self.prompt_lineedit.moveCursor(QTextCursor.End)
        self.prompt_lineedit.insertPlainText(text)

        QApplication.processEvents()

    def help_action_triggered(self):
        # opens browser with specified url, directs user to Issues section of GitHub repo
        QDesktopServices.openUrl(
            QUrl("https://github.com/SINTEFMedtek/GSI-RADS/issues"))

    def settings_seg_preproc_menu_p1_action_triggered(self, status):
        if status:
            self.settings_seg_preproc_menu_p2_action.setChecked(False)
        else:
            self.settings_seg_preproc_menu_p2_action.setChecked(True)

    def settings_seg_preproc_menu_p2_action_triggered(self, status):
        if status:
            self.settings_seg_preproc_menu_p1_action.setChecked(False)
        else:
            self.settings_seg_preproc_menu_p1_action.setChecked(True)
Ejemplo n.º 6
0
Archivo: Log.py Proyecto: zsh2020/Ryven
class Log(QWidget):
    def __init__(self, sender, title=''):
        super(Log, self).__init__()

        self.main_layout = QVBoxLayout()
        self.header_layout = QHBoxLayout()

        title_label = QLabel(title)
        title_label.setFont(QFont('Poppins', 13))
        self.header_layout.addWidget(title_label)

        self.remove_button = QPushButton('x')
        self.remove_button.clicked.connect(self.remove_clicked)
        self.header_layout.addWidget(self.remove_button)
        self.remove_button.hide()

        holder_label = QLabel(shorten(str(sender), 76))
        holder_label.setWordWrap(True)
        self.log_view = QPlainTextEdit()
        self.log_view.setReadOnly(True)

        self.main_layout.addLayout(self.header_layout)
        self.main_layout.addWidget(holder_label)
        self.main_layout.addWidget(self.log_view)

        self.setLayout(self.main_layout)

        self.enabled_style_sheet = '''
            QLabel {
                border: None;
            }
            QWidget {
                color: #e9f4fb;
            }
        '''
        self.disabled_style_sheet = '''
            QLabel {
                border: None;
            }
            QWidget {
                color: #e9f4fb;
            }
            QPlainTextEdit {
                background: black; 
                color: grey;
            }
        '''
        self.setStyleSheet(self.enabled_style_sheet)

    def log(self, *args):
        s = ''
        for arg in args:
            s += ' ' + str(arg)
        self.log_view.appendPlainText('>  ' + s)

    def clear(self):
        self.log_view.clear()

    def disable(self):
        self.remove_button.show()
        self.setStyleSheet(self.disabled_style_sheet)

    def enable(self):
        self.remove_button.hide()
        self.setStyleSheet(self.enabled_style_sheet)
        self.show()

    def remove_clicked(self):
        self.hide()
Ejemplo n.º 7
0
class VentanaAdministradorDePersonas(QFrame):
    def __init__(self, parent=None):
        super(VentanaAdministradorDePersonas, self).__init__(parent)
        raiz.setWindowTitle("Administracion de personas")
        self.operacionesConPersonas = OperacionesConPersonas()
        self.instanciarVentana()

    def instanciarVentana(self):
        #Contenedor De todas las cosas de arriba a abajo
        layoutGeneral = QVBoxLayout()

        #Cosas de Derecha
        layoutDerecha = QVBoxLayout()  #Ordena cosas de arriba a abajo
        layoutDerecha.setMargin(20)

        self.btnAgregarPersona = QPushButton("Agregar persona")
        self.btnAgregarPersona.setToolTip("Toma los datos ")
        self.btnAgregarPersona.clicked.connect(self.agregarPersona)
        layoutDerecha.addWidget(self.btnAgregarPersona)

        self.btnBuscarPersona = QPushButton("Buscar persona")
        self.btnBuscarPersona.setToolTip("Busca por cedula a una persona")
        self.btnBuscarPersona.clicked.connect(self.buscarPersona)
        layoutDerecha.addWidget(self.btnBuscarPersona)

        self.btnEliminarPersona = QPushButton("Eliminar persona")
        self.btnEliminarPersona.setToolTip(
            "Elimina a la persona que esta en busqueda")
        self.btnEliminarPersona.clicked.connect(self.eliminarPersona)
        layoutDerecha.addWidget(self.btnEliminarPersona)

        self.btnActualizarPersona = QPushButton("Actualizar persona")
        self.btnActualizarPersona.setToolTip(
            "Cambia los datos de la persona seleccionada")
        self.btnActualizarPersona.clicked.connect(self.actualizarPersona)
        layoutDerecha.addWidget(self.btnActualizarPersona)

        self.btnLimpiarTexto = QPushButton("Limpiar")
        self.btnLimpiarTexto.setToolTip(
            "Limpia los campos de texto para ingresar datos")
        self.btnLimpiarTexto.clicked.connect(self.limpiarCampos)
        layoutDerecha.addWidget(self.btnLimpiarTexto)

        self.btnVolverAlMenu = QPushButton("Volver")
        self.btnVolverAlMenu.setToolTip("Vuelve al menu principal")
        self.btnVolverAlMenu.clicked.connect(self.volverAlMenu)
        layoutDerecha.addWidget(self.btnVolverAlMenu)

        #Cosas de Izquierda
        layoutIzquierda = QVBoxLayout()  #ordena cosas de arriba a abajo

        self.lblDNI = QLabel("DNI: ")
        layoutIzquierda.addWidget(self.lblDNI)
        self.DNI = QLineEdit()
        layoutIzquierda.addWidget(self.DNI)

        self.lblPrimerNombre = QLabel("Primer nombre: ")
        layoutIzquierda.addWidget(self.lblPrimerNombre)
        self.PrimerNombre = QLineEdit()
        layoutIzquierda.addWidget(self.PrimerNombre)

        self.lblSegundoNombre = QLabel("Segundo nombre: ")
        layoutIzquierda.addWidget(self.lblSegundoNombre)
        self.SegundoNombre = QLineEdit()
        layoutIzquierda.addWidget(self.SegundoNombre)

        self.lblPrimerApellido = QLabel("Primer apellido: ")
        layoutIzquierda.addWidget(self.lblPrimerApellido)
        self.PrimerApellido = QLineEdit()
        layoutIzquierda.addWidget(self.PrimerApellido)

        self.lblSegundoApellido = QLabel("Segundo apellido: ")
        layoutIzquierda.addWidget(self.lblSegundoApellido)
        self.SegundoApellido = QLineEdit()
        layoutIzquierda.addWidget(self.SegundoApellido)

        self.lblFechaDeNacimiento = QLabel("Fecha de nacimiento")
        layoutIzquierda.addWidget(self.lblFechaDeNacimiento)
        self.fechaDeNacimiento = QDateEdit()
        self.fechaDeNacimiento.setDisplayFormat("yyyy-MM-dd")
        self.fechaDeNacimiento.setCalendarPopup(True)
        self.fechaDeNacimiento.setDate(date.today())
        layoutIzquierda.addWidget(self.fechaDeNacimiento)

        #Cosas de layout de arriba
        layoutSuperior = QHBoxLayout()  #Ordena cosas de derecha a izquierda
        layoutSuperior.addLayout(layoutIzquierda)
        layoutSuperior.addLayout(layoutDerecha)

        #Cosas layout de abajo
        layoutInferior = QVBoxLayout()
        self.mostrarError = QPlainTextEdit(readOnly=True)
        layoutInferior.addWidget(self.mostrarError)

        #cosas del layout general
        layoutGeneral.addLayout(layoutSuperior)
        layoutGeneral.addLayout(layoutInferior)
        self.setLayout(layoutGeneral)

        #Redimensionar
        raiz.adjustSize()
        self.adjustSize()

    def agregarPersona(self):
        self.limpiarErrores()
        try:
            laPersona = self.llenarPersona()
            salida = self.operacionesConPersonas.insertarPersona(laPersona)
            self.mostrarError.insertPlainText(str(salida))
            self.limpiarCampos(
            )  #habilitamos la edicion y evitamos dejar datos basura
        except Exception as e:
            self.mostrarError.insertPlainText(''.join(e.args))
        pass

    def buscarPersona(self):
        self.limpiarErrores()
        try:
            laPersona = self.operacionesConPersonas.buscarPersonaPorDNI(
                int(''.join(self.DNI.text())))
            if type(laPersona) == type(""):
                self.mostrarError.insertPlainText(''.join(laPersona))
                return None
            self.llenarCampos(laPersona)
        except Exception as e:
            self.mostrarError.insertPlainText(''.join(e.args))

    def eliminarPersona(self):
        self.limpiarErrores()
        try:
            laPersona = self.llenarPersona()
            mensajeDeConfirmacion = "DNI: " + self.DNI.text()
            opcionElegida = QMessageBox.question(
                self, "Desea eliminar a la persona?", mensajeDeConfirmacion,
                QMessageBox.Yes, QMessageBox.No)
            if opcionElegida == QMessageBox.Yes:
                respuesta = self.operacionesConPersonas.eliminarPersona(
                    laPersona)
                if type(respuesta) == type(""):
                    self.mostrarError.insertPlainText(''.join(respuesta))
                    self.limpiarCampos()
                    return None
        except Exception as e:
            self.mostrarError.insertPlainText(''.join(e.args))

    def actualizarPersona(self):
        self.limpiarErrores()
        try:
            laPersona = self.llenarPersona()
            mensajeDeConfirmacion = "DNI: " + self.DNI.text()
            opcionElegida = QMessageBox.question(
                self, "Desea eliminar a la persona?", mensajeDeConfirmacion,
                QMessageBox.Yes, QMessageBox.No)
            if opcionElegida == QMessageBox.Yes:
                respuesta = self.operacionesConPersonas.actualizarPersona(
                    laPersona)
                if type(respuesta) == type(""):
                    self.mostrarError.insertPlainText(''.join(respuesta))
                    self.limpiarCampos()
                    return None
        except Exception as e:
            print(e.args)

    def llenarCampos(self, laPersona):
        self.limpiarCampos()
        self.DNI.setText(str(laPersona.getDNI()))
        self.DNI.setReadOnly(True)
        self.PrimerNombre.setText(laPersona.getPrimerNombre())
        self.SegundoNombre.setText(laPersona.getSegundoNombre())
        self.PrimerApellido.setText(laPersona.getPrimerApellido())
        self.SegundoApellido.setText(laPersona.getSegundoApellido())
        self.fechaDeNacimiento.setDate(laPersona.getFechaDeNacimiento())

    def llenarPersona(self):
        return Persona(int(''.join(self.DNI.text())),
                       ''.join(self.PrimerNombre.text()),
                       ''.join(self.SegundoNombre.text()),
                       ''.join(self.PrimerApellido.text()),
                       ''.join(self.SegundoApellido.text()),
                       ''.join(self.fechaDeNacimiento.text()))

    def limpiarCampos(self):
        self.DNI.clear()
        self.DNI.setReadOnly(False)
        self.PrimerNombre.clear()
        self.SegundoNombre.clear()
        self.PrimerApellido.clear()
        self.SegundoApellido.clear()
        self.fechaDeNacimiento.setDate(date.today())
        #limpiar campos de texto y permitir la edicion de todos ellos

    def limpiarErrores(self):
        self.mostrarError.clear()

    def volverAlMenu(self):
        raiz.setCentralWidget(None)
        raiz.setCentralWidget(VentanaPrincipal())
class TrainingConsoleWidget(QWidget):
    """The TrainingConsoleWidget provides a widget for controlling the training status
    of a model, in a simple way. (Analog of the console output in Keras, but with a few
    more options).

    It also can save and show an history of the last trained models.
    """

    training_started = Signal()
    training_stopped = Signal()

    class TrainingStatus(Enum):
        Running = 1
        Stopped = 2
        Not_Compiled = 3

    def __init__(self, parent: "QWidget" = None):
        super().__init__(parent)

        # Components
        self._pretrained_model: Optional["keras.models.Model"] = None
        self._ttv: Optional["TTVSets"] = None
        self._hyperparameters: Optional[Dict] = None
        self._callbacks: List[Callback] = []

        self._trained_model: Optional["keras.models.Model"] = None

        # Widgets
        self._start_training_button = QPushButton("Start training")
        self._stop_training_button = QPushButton("Stop training")

        self._buttons_layout = QHBoxLayout()
        self._buttons_layout.addWidget(self._start_training_button)
        self._buttons_layout.addWidget(self._stop_training_button)

        self._status_label = QLabel()

        self._batch_progress_bar = QProgressBar()
        self._epoch_progress_bar = QProgressBar()

        self.training_output_textbox = QPlainTextEdit()
        self.training_output_textbox.setReadOnly(True)

        console_output_group = QGroupBox("Console output")
        console_output_layout = QVBoxLayout()
        console_output_layout.setContentsMargins(0, 0, 0, 0)
        console_output_layout.addWidget(self.training_output_textbox)
        console_output_group.setLayout(console_output_layout)

        self._main_layout = QVBoxLayout()
        self._main_layout.addLayout(self._buttons_layout)
        self._main_layout.addWidget(self._status_label, Qt.AlignRight)
        self._main_layout.addWidget(console_output_group)
        self._main_layout.addWidget(self._batch_progress_bar)
        self._main_layout.addWidget(self._epoch_progress_bar)
        self.setLayout(self._main_layout)

        # Connections
        self._start_training_button.clicked.connect(self.start_training)
        self._stop_training_button.clicked.connect(self.stop_training)

        # Inner workings
        self.training_status = self.TrainingStatus.Not_Compiled
        self._training_thread = None

    @property
    def training_status(self):
        """Returns the current status of the training (Running, Stopped...)"""
        return self._training_status

    @training_status.setter
    def training_status(self, new_status):
        """Changes the training status.

        Doing so will update the interface accordingly.
        """
        self._training_status = new_status

        if self._training_status == self.TrainingStatus.Running:
            self._start_training_button.setEnabled(False)
            self._stop_training_button.setEnabled(True)
            self._status_label.setText("Running")
            self.start_training

        elif self._training_status == self.TrainingStatus.Stopped:
            self._start_training_button.setEnabled(True)
            self._stop_training_button.setEnabled(False)
            self._status_label.setText("Stopped")

        elif self._training_status == self.TrainingStatus.Not_Compiled:
            self._start_training_button.setEnabled(True)
            self._stop_training_button.setEnabled(False)
            self._status_label.setText("Not Compiled")

    def set_ttv(self, ttv: "TTVSets"):
        """Sets the Train/Test/Validation models used for training."""
        self._ttv = ttv

    def set_pretrained_model(self, pretrained_model: "Model"):
        """Sets a new pretrained model for training."""
        self._pretrained_model = pretrained_model

        self.training_status = self.TrainingStatus.Not_Compiled

    def set_hyperparameters(self, hyperparameters: Dict):
        """Sets new hyperparameters for training."""
        self._hyperparameters = hyperparameters

        self.training_status = self.TrainingStatus.Not_Compiled

    def set_callbacks(self, callbacks: List[Callback]):
        self._callbacks = callbacks

    def get_trained_model(self):
        """Returns the model after it has been trained."""
        return self._trained_model

    def compile_model(self):
        """Compile the model with the passed hyperparameters. The dataset is needed for
        the input shape."""
        LOGGER.info("Starting to compile the model...")

        if not self._is_input_ready():
            return False

        # Create a new model based on the pretrained one, but with a new InputLayer
        # compatible with the dataset
        if self._pretrained_model.layers[0].__class__.__name__ != "InputLayer":
            input_layer = Input(self._ttv.train.input_shape)

            output = self._pretrained_model(input_layer)
            self._trained_model = Model(input_layer, output)
        else:
            self._trained_model = self._pretrained_model

        try:
            self._trained_model.compile(
                optimizer=self._hyperparameters["optimizer"],
                loss=self._hyperparameters["loss_function"],
                metrics=["accuracy"],
            )

            self._trained_model.summary()

            LOGGER.info("Model compiled successfully!!")

            self.training_status = self.TrainingStatus.Stopped

            return True

        except Exception as err:
            LOGGER.exception("Model Compiling error: ", err)

            self.training_output_textbox.setPlainText(
                "> Error while compiling the model:\n", str(err))

        return False

    def start_training(self):
        """Starts the training on a new thread."""
        if self.training_status == self.TrainingStatus.Not_Compiled:
            successfully_compiled = self.compile_model()

            if not successfully_compiled:
                LOGGER.info("Couldn't compile model. Training not started.")
                return

        total_train_batches = len(self._ttv.train)
        total_train_epochs = self._hyperparameters["epochs"]

        self._batch_progress_bar.setMaximum(total_train_batches)
        self._epoch_progress_bar.setMaximum(total_train_epochs)
        self._epoch_progress_bar.setValue(0)
        self.training_output_textbox.clear()

        def epoch_begin_update(epoch: int, logs):
            message = f"==== Epoch {epoch + 1}/{total_train_epochs} ===="

            LOGGER.info(message)
            self.training_output_textbox.appendPlainText(message)
            self._epoch_progress_bar.setValue(epoch)

        def batch_end_update(batch: int, logs):
            # Update progress
            self._batch_progress_bar.setValue(batch)

            # Log metrics on console
            message = f"{batch}/{total_train_batches}"

            for (k, v) in list(logs.items()):
                message += f" - {k}: {v:.4f}"

            LOGGER.info(message)
            self.training_output_textbox.appendPlainText(message)

        def train_end_update(logs):
            # Put the progress bar at 100% when the training ends
            self._batch_progress_bar.setValue(
                self._batch_progress_bar.maximum())
            self._epoch_progress_bar.setValue(
                self._epoch_progress_bar.maximum())

            # Stop the training
            self.stop_training()

        # Connect callbacks
        signals_callback = SignalsCallback()
        signals_callback.epoch_begin.connect(epoch_begin_update)
        signals_callback.train_batch_end.connect(batch_end_update)
        signals_callback.train_end.connect(train_end_update)

        self.training_stopped.connect(signals_callback.stop_model)

        print(self._callbacks)
        # log_dir = "logs/fit/" + datetime.datetime.now().strftime("%Y_%m_%d-%H_%M_%S")

        # tb = program.TensorBoard()
        # tb.configure(argv=[None, "--logdir", log_dir])
        # url = tb.launch()
        # print("Launched Tensorboard instance in:", url)

        # tf_callback=tf.keras.callbacks.TensorBoard(log_dir=log_dir, histogram_freq=1)
        # tf_callback.set_model(self._trained_model)

        # Start training
        self._fit_worker = FitWorker(
            self._trained_model,
            self._ttv.train,
            self._hyperparameters,
            callbacks=[signals_callback] + self._callbacks,
        )

        self.training_status = self.TrainingStatus.Running
        self._fit_worker.start()

        self.training_started.emit()

    def stop_training(self):
        """Stops the training."""
        self.training_status = self.TrainingStatus.Stopped

        self.training_stopped.emit()

    def _is_input_ready(self) -> bool:
        """Checks if the input values used for training (model, dataset,
        hyperparameters...) are valid."""
        message = ""

        if not self._ttv.train:
            message += "> Training dataset not specified\n"

        if not self._pretrained_model:
            message += "> Model not specified.\n"

        if not self._hyperparameters:
            message += "> Hyperparameters not specified.\n"

        if message:
            self.training_output_textbox.setPlainText(message)
            LOGGER.info(message)
            return False

        return True

    def sizeHint(self) -> "QSize":
        """Returns the expected size of the widget."""
        return QSize(500, 300)

    def __reduce__(self):
        return (TrainingConsoleWidget, ())
Ejemplo n.º 9
0
class Widget(QWidget):

    cinema_url_label_text = "粘贴独播库的连续剧/综艺/动漫 URL: "
    movie_url_label_text = "粘贴独播库的电影 URL: "

    cinema_dest_label_text = "输入连续剧/综艺/动漫名 (用来命名下载的目录): "
    movie_dest_label_text = "输入电影名 (用来命名下载的文件): "

    def __init__(self):
        QWidget.__init__(self)

        self.q = None
        self.pool = None

        self.top = QHBoxLayout()
        self.top.setMargin(10)

        self.radioButtonMov = QRadioButton("电影")
        self.radioButtonCinema = QRadioButton("连续剧/综艺/动漫")

        self.top.addWidget(self.radioButtonMov)
        self.top.addWidget(self.radioButtonCinema)

        self.middle = QVBoxLayout()
        self.middle.setMargin(10)

        self.url_label = QLabel()
        self.url = QLineEdit()
        self.url_label.setBuddy(self.url)
        self.middle.addWidget(self.url_label)
        self.middle.addWidget(self.url)

        self.browse_folder_label = QLabel("下载到:")
        self.browseFolder = QPushButton("选择目录")
        self.browse_folder_label.setBuddy(self.browseFolder)
        self.middle.addWidget(self.browse_folder_label)
        self.middle.addWidget(self.browseFolder)
        self.browse_folder_value = ""

        self.dest_file_label = QLabel()
        # "输入电影/电视剧名 (用来命名下载的文件/目录): " title set by choose_movie_widgets() later
        self.folder_or_filename = QLineEdit()
        self.dest_file_label.setBuddy(self.folder_or_filename)
        self.middle.addWidget(self.dest_file_label)
        self.middle.addWidget(self.folder_or_filename)

        self.bk_cinemae_spin_from = 1
        self.bk_cinemae_spin_to = 1
        self.fromEpSpinBox = QSpinBox()
        self.fromEpSpinBox.setMinimum(1)
        self.fromEpSpinBox.setMaximum(2147483647)
        self.fromEpLabel = QLabel("&从第几集开始下载:")
        self.fromEpLabel.setBuddy(self.fromEpSpinBox)

        self.toEpSpinBox = QSpinBox()
        self.toEpSpinBox.setMinimum(1)
        self.toEpSpinBox.setMaximum(2147483647)
        self.toEpLabel = QLabel("&到第几集停止下载:")
        self.toEpLabel.setBuddy(self.toEpSpinBox)

        self.cinema_ly = QHBoxLayout()
        #self.cinema_ly.setMargin(10)
        self.cinema_ly.addWidget(self.fromEpLabel)
        self.cinema_ly.addWidget(self.fromEpSpinBox)
        self.cinema_ly.addWidget(self.toEpLabel)
        self.cinema_ly.addWidget(self.toEpSpinBox)
        self.middle.addLayout(self.cinema_ly)

        self.proxy_label = QLabel("(如有)代理:")
        self.proxy = QLineEdit()
        self.proxy_label.setBuddy(self.proxy)
        self.middle.addWidget(self.proxy_label)
        self.middle.addWidget(self.proxy)

        self.add = QPushButton("开始下载")
        self.add.setEnabled(False)
        self.middle.addWidget(self.add)

        self.stop_me = QPushButton("停止下载")
        self.stop_me.setEnabled(False)
        self.middle.addWidget(self.stop_me)

        self.log_area = QPlainTextEdit()
        self.log_area.setReadOnly(True)
        self.log_area.setMaximumBlockCount(1000)
        self.middle.addWidget(self.log_area)

        #self.table_view.setSizePolicy(size)
        #self.layout.addWidget(self.table)
        self.layout = QVBoxLayout()
        self.layout.addLayout(self.top)
        self.layout.addLayout(self.middle)
        self.setLayout(self.layout)

        self.radioButtonMov.toggled.connect(self.choose_movie_widgets)
        self.radioButtonCinema.toggled.connect(self.choose_cinema_widgets)
        self.url.textChanged[str].connect(self.check_disable_download)
        self.browseFolder.clicked.connect(self.add_folder)
        self.folder_or_filename.textChanged[str].connect(
            self.check_disable_download)
        self.add.clicked.connect(self.start_download)
        self.stop_me.clicked.connect(self.stop_download)

        self.radioButtonMov.setChecked(
            True)  #set default only after .connect above

        # TESTING PURPOSE
        '''
        self.radioButtonMov.setChecked(False)
        self.url.setText('https://www.duboku.net/voddetail-969.html')
        self.browse_folder_value = 'C:/Users/Administrator/Documents/duboku'
        self.folder_or_filename.setText('初恋')
        '''

        #set current process (not queue that one) log handler:
        logger = logging.getLogger(__name__)
        handler2 = LoggerWriter()
        logger.addHandler(handler2)
        logger.setLevel(logging.INFO)  #DEBUG
        handler2.emitter.sigLog.connect(self.log_area.appendPlainText)
        sys.stdout = handler2  #LoggerWriter()
        #sys.stderr = handler2 #Seems no difference
        #handler2.emitter.sigLog.emit('hihi')

    @Slot()
    def choose_movie_widgets(self):

        if self.radioButtonMov.isChecked():

            self.url_label.setText(self.movie_url_label_text)
            self.dest_file_label.setText(self.movie_dest_label_text)

            self.fromEpLabel.setDisabled(True)
            self.toEpLabel.setDisabled(True)

            self.fromEpSpinBox.setDisabled(True)
            self.toEpSpinBox.setDisabled(True)

            self.bk_cinemae_spin_from = self.fromEpSpinBox.value()
            self.bk_cinemae_spin_to = self.toEpSpinBox.value()
            self.fromEpSpinBox.setValue(1)
            self.toEpSpinBox.setValue(1)

    @Slot()
    def choose_cinema_widgets(self):

        if self.radioButtonCinema.isChecked():

            self.url_label.setText(self.cinema_url_label_text)
            self.dest_file_label.setText(self.cinema_dest_label_text)

            self.fromEpLabel.setEnabled(True)
            self.toEpLabel.setEnabled(True)

            self.fromEpSpinBox.setEnabled(True)
            self.toEpSpinBox.setEnabled(True)

            self.fromEpSpinBox.setValue(self.bk_cinemae_spin_from)
            self.toEpSpinBox.setValue(self.bk_cinemae_spin_to)

    @Slot()
    def add_folder(self, s):

        #fname = QFileDialog.getOpenFileName(self, 'Open file', "c:\'", "Image files (*.jpg *.gif)")
        #fname = QFileDialog.getOpenFileName(self, 'Open file', '', QFileDialog.ShowDirsOnly)
        fname = QFileDialog.getExistingDirectory(self, '选择下载至什么目录', '',
                                                 QFileDialog.ShowDirsOnly)
        #print('repr: ' + repr(fname))
        if fname and fname.strip():
            fname = fname.strip()
            self.browse_folder_value = fname
            #if getOpenFileName, will return ('/home/xiaobai/Pictures/disco.jpg', 'Image files (*.jpg *.gif)')
            #, while if getExistingDirectory, will return single path string only
            self.browseFolder.setText(fname)
            self.check_disable_download(fname)
        #else:
        #    print('User cancel')

    @Slot()
    def check_disable_download(self, s):

        if self.url.text().strip(
        ) and self.browse_folder_value and self.folder_or_filename.text():
            self.add.setEnabled(True)
        else:
            self.add.setEnabled(False)

    def task_done(self, retVal):
        self.add.setEnabled(True)
        self.stop_me.setEnabled(False)

    @Slot()
    def stop_download(self):
        if self.q:
            self.q.close()
        if self.pool:
            self.pool.terminate()
        self.add.setEnabled(True)
        self.stop_me.setEnabled(False)
        print('下载停止。')

    @Slot()
    def start_download(self):

        if self.fromEpSpinBox.value() > self.toEpSpinBox.value():
            self.log_area.setPlainText('[!] 从第几集必须小于或等于到第几集。')
            return

        #No need worry click twice too fast, it seems already handle by PySide2
        self.add.setEnabled(False)
        self.stop_me.setEnabled(True)
        self.log_area.clear()

        dest_full_path = os.path.join(self.browse_folder_value,
                                      self.folder_or_filename.text())
        '''
        print('dest_full_path: ' + repr(dest_full_path))
        print('self.url.text(): ' + repr(self.url.text()))
        print('self.fromEpSpinBox.value(): ' + repr(self.fromEpSpinBox.value()))
        print('self.toEpSpinBox.value(): ' + repr(self.toEpSpinBox.value()))
        '''

        import duboku_console

        #Windows can't set like that bcoz not update for args.url, must put explicitly
        #duboku_console.redirect_stdout_to_custom_stdout(arg_url, ...etc, LoggerWriter())

        #failed other process
        handler = LogHandlerOtherProcess()
        handler.emitter.sigLog.connect(self.log_area.appendPlainText)
        ''' #ref current process:
        logger = logging.getLogger(__name__)
        handler2 = LoggerWriter()
        logger.addHandler(handler2)
        logger.setLevel(logging.DEBUG)
        handler2.emitter.sigLog.connect(self.log_area.appendPlainText)
        sys.stdout = handler2 #LoggerWriter()
        #handler2.emitter.sigLog.emit('hihi')
        '''

        #handler = LoggerWriter()
        #handler.emitter.sigLog.connect(self.log_area.appendPlainText)

        self.q = multiprocessing.Queue()
        self.ql = QueueListener(self.q, handler)
        self.ql.start()

        self.pool = multiprocessing.Pool(1, worker_init, [self.q])

        if self.radioButtonMov.isChecked():
            self.pool.apply_async(duboku_console.main,
                                  args=(None, dest_full_path,
                                        self.fromEpSpinBox.value(),
                                        self.toEpSpinBox.value(),
                                        self.url.text().strip(),
                                        LoggerWriterOtherProcess(), False,
                                        self.proxy.text()),
                                  callback=self.task_done)
        else:
            self.pool.apply_async(duboku_console.main,
                                  args=(dest_full_path, None,
                                        self.fromEpSpinBox.value(),
                                        self.toEpSpinBox.value(),
                                        self.url.text().strip(),
                                        LoggerWriterOtherProcess(), False,
                                        self.proxy.text()),
                                  callback=self.task_done)
Ejemplo n.º 10
0
class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.textEdit = QPlainTextEdit()
        self.curFile = ""

        self.centralWidget = qtw.QWidget()
        self.mainWindow = self.createMainWindow()
        self.centralWidget.setLayout(self.mainWindow)

        self.setCentralWidget(self.centralWidget)
        #self.setFixedSize(1000, 550)
        
        self.createActions()
        self.createMenus()
        #self.createToolBars()
        self.createStatusBar()

        self.readSettings()

        self.textEdit.document().contentsChanged.connect(self.documentWasModified)

        #self.setCurrentFile("")
        self.setUnifiedTitleAndToolBarOnMac(True)

        #self.menuBar = qtw.QLayout.menuBar()
        #self.statusBar = qtw.QMainWindow.statusBar()
        self.Qsettings = QSettings()

        #self.connectlist()

    def createMainWindow(self):

        self.graphics = GraphicsWindow()
        self.spreadsheet = self.graphics.scene_class.spreadsheet
        self.control = self.spreadsheet.control

        self.controlobj = self.control.controlBox

        self.control.nextButton.clicked.connect(self.spreadsheet.update_table)
        self.control.nextButton.clicked.connect(self.graphics.update_view)
        
        self.control.prevButton.clicked.connect(self.spreadsheet.prev_table)
        self.control.prevButton.clicked.connect(self.graphics.prev_view)

        self.righttop = QVBoxLayout()
        self.righttop.addLayout(self.controlobj)
        self.righttop.addWidget(self.spreadsheet.table)

        self.mainWin = QHBoxLayout()
        self.mainWin.addWidget(self.graphics)
        self.mainWin.addLayout(self.righttop)

        return self.mainWin
    
    def closeEvent(self, event):
        if self.maybeSave:
            self.writeSettings
            event.accept()
        else:
            event.ignore()

    def newFile(self):
        if self.maybeSave:
            self.textEdit.clear()
            self.setCurrentFile("")

    def open(self):
        if self.maybeSave:
            fileName = QFileDialog.getOpenFileName(self)
            if not fileName.isEmpty():
                self.loadFile(fileName)

    def save(self):
        if self.curFile == "":
            return self.saveAs

        else:
            return self.saveFile(self.curFile)

    def saveAs(self):
        fileName = QFileDialog.getSaveFileName(self)
        if fileName.isEmpty():
            return False
        
        return self.saveFile(fileName)

    def about(self):
        QMessageBox.about(self, "About Application\n", 
                                                "The <b>Application</b> example demonstrates how to\n"
                                                "write modern GUI applications using Qt, With a menu bar\n"
                                                "toolbars, and a status bar.")

    def documentWasModified(self):
        self.setWindowModified(self.textEdit.document().isModified())

    
    
    def createActions(self):
        self.Act = QAction(QIcon(":/images/new.png"), "&New", self)
        self.Act.setShortcuts(QKeySequence.New)
        self.Act.setStatusTip("Create a new file")
        self.Act.triggered.connect(self.newFile)

        self.openAct = QAction(QIcon(":/images/new.png"), "&Open", self)
        self.openAct.setShortcuts(QKeySequence.Open)
        self.openAct.setStatusTip("Open an exsting file")
        self.openAct.triggered.connect(self.open)

        self.saveAct = QAction("&Save", self)
        self.saveAct.setShortcuts(QKeySequence.Save)
        self.saveAct.setStatusTip("Save a file")
        self.saveAct.triggered.connect(self.save)

        self.saveasAct = QAction("&Save as", self)
        self.saveasAct.setShortcuts(QKeySequence.SaveAs)
        self.saveasAct.setStatusTip("Save as a file")
        self.saveasAct.triggered.connect(self.saveAs)

        self.aboutQtAct = QAction("About &Qt", self)
        self.aboutQtAct.setStatusTip("Show the Qt library's About box")
        self.aboutQtAct.triggered.connect(qApp.aboutQt)

        self.exitAct = QAction("&Exit", self)
        self.exitAct.setStatusTip("Exit")
        self.exitAct.triggered.connect(self.exit)

        #self.cutAct.setEnabled(False)
        #self.copyAct.setEnabled(False)
        #self.textEdit.copyAvailable[bool].connect(self.cutAct.setEnabled)
        #self.textEdit.copyAvailable[bool].connect(self.copyAct.setEnabled)

        self.findAct = QAction("&Find", self)
        self.findAct.triggered.connect(self.find)
        self.gotocellAct = QAction("&GoToCell", self)
        self.gotocellAct.triggered.connect(self.gotocell)
        self.sortAct = QAction("&Sort", self)
        self.sortAct.triggered.connect(self.sort)

        self.undoAct = QAction("&Undo", self)
        self.redoAct = QAction("&Redo", self)
        self.cutAct = QAction("&Cut", self)
        self.copyAct = QAction("&Copy", self)
        self.pasteAct = QAction("&Paste", self)
        self.aboutAct = QAction("&About", self)
        self.boldAct = QAction("&Bold", self)
        self.italicAct = QAction("&Italic", self)
        self.leftAlignAct = QAction("&LeftAlign", self)
        self.rightAlignAct = QAction("&Alignment", self)
        self.justifyAct = QAction("&Justify", self)
        self.centerAct = QAction("&Center", self)
        self.setLineSpacingAct = QAction("&setLine", self)
        self.setParagrahSpacingAct = QAction("&setPAragrah", self)


    def createStatusBar(self):
        self.statusBar().showMessage("Ready")

    def createMenus(self):
        self.fileMenu = self.menuBar().addMenu("&File")
        self.fileMenu.addAction(self.Act)
        self.fileMenu.addAction(self.openAct)
        self.fileMenu.addAction(self.saveAct)
        self.fileMenu.addSeparator()
        self.fileMenu.addAction(self.exitAct)

        self.editMenu = self.menuBar().addMenu("&Edit")
        self.editMenu.addAction(self.undoAct)
        self.editMenu.addAction(self.redoAct)
        self.editMenu.addSeparator()
        self.editMenu.addAction(self.cutAct)
        self.editMenu.addAction(self.copyAct)
        self.editMenu.addAction(self.pasteAct)
        self.editMenu.addSeparator()

        self.dataMenu = self.menuBar().addMenu("&Data")
        self.dataMenu.addAction(self.findAct)
        self.dataMenu.addAction(self.gotocellAct)
        self.dataMenu.addAction(self.sortAct)

        self.helpMenu = self.menuBar().addMenu("&Help")
        self.helpMenu.addAction(self.aboutAct)
        self.helpMenu.addAction(self.aboutQtAct)

        self.formatMenu = self.editMenu.addMenu("&Fornat")
        self.formatMenu.addAction(self.boldAct)
        self.formatMenu.addAction(self.italicAct)
        self.formatMenu.addSeparator().setText("Alignment")
        self.formatMenu.addAction(self.leftAlignAct)
        self.formatMenu.addAction(self.rightAlignAct)
        self.formatMenu.addAction(self.justifyAct)
        self.formatMenu.addAction(self.centerAct)
        self.formatMenu.addSeparator()
        self.formatMenu.addAction(self.setLineSpacingAct)
        self.formatMenu.addAction(self.setParagrahSpacingAct)

    def readSettings(self):
        self.settings = QSettings("Trolltrch", "Application Example")
        self.pos = self.settings.value("pos", QPoint(200, 200))#.toPoint()
        self.size = self.settings.value("size", QSize(400, 400))#.toSize()
        self.resize(self.size)
        self.move(self.pos)

    def writeSettings(self):
        self.settings = QSettings("Trolltech", "Application Example")
        self.settings.setValue("pos", self.pos)
        self.setting.setValue("size", self.size)

    def maybeSave(self):
        if self.textEdit.document().isModified():
            ret = QMessageBox.warning(self, "Application",
                                                                  "The document has been modified.\n"
                                                                  "Do you want to save your changes?",
                                                                  QMessageBox.Save | QMessageBox.Discard | QMessageBox.cancel)
            
            if ret == QMessageBox.Save:
                return self.save
            elif ret == QMessageBox.Cancel:
                return False
        
        return True

    def loadFile(self, fileName):
        file = QFile(fileName)
        if not file.open(QFile.ReadOnly | QFile.Text):
            QMessageBox.warning(self, "Application", "Cannot read file"
                                                                                        "{}:\n{}".format(fileName, file.errorString()))
            return False

        in_ = QTextStream(file)
        QApplication.setOverrideCursor(Qt.WaitCursor)
        self.textEdit.setPlainText(in_.readAll())
        QApplication.restoreOverrideCursor()

        self.setCurrentFile(fileName)
        self.statusBar().showMessage("File loaded", 2000)

    def saveFile(self, fileName):
        file = QFile(fileName)
        if not file.open(QFile.WriteOnly | QFile.Text):
            QMessageBox.warning(self, "Application",
                                                         "Cannot write file %1:\n%2.".arg(fileName)
                                                                                                           .arg(file.errorString()))
            return False

        self.out = QTextStream(file)
        QApplication.setOverrideCursor(Qt.WaitCursor)
        self.out = self.textEdit.toPlainText()
        QApplication.restoreOverrideCursor()

        self.setCurrentFile(fileName)
        self.statusBar().showMessage("File saved", 2000)
        return True

    def setCurrentFile(self, fileName):
        self.curFile = fileName
        self.textEdit.document().setModified(False)
        self.setWindowModified(False)

        if self.curFile.isEmpty():
            shownName = "untitled.txt"
        else:
            shownName = strippedName(curFile)

        setWindowTitle(tr("%1[*] - %2").arg(shownName).arg("Application"))

    def strippedName(self, fullFileName):
        return QFileInfo(fullFileName).fileName()

    def exit(self):
        pass

    '''
    def connectlist(self):

        self.copyAct.triggered.connect(self.spreadsheet.copy())
        self.pasteAct.triggered.connect(self.spreadsheet.paste())
        # self.
    '''

    def find(self):
        print("findをクリックしました")
        self.fw = FindDialog()
        self.fw.show()
        self.fw.activateWindow()

    def gotocell(self):
        self.gw = GoToCell()
        self.gw.show()
        self.gw.activateWindow()

    def sort(self):
        self.sw = Sort()
        self.sw.show()
        self.sw.activateWindow()
Ejemplo n.º 11
0
class MyWidget(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.thread = SerialMonitorThread()
        self.thread.dataReady.connect(self.get_data, Qt.QueuedConnection)
        self.thread.setTerminationEnabled(True)

        #Menu
        self.setPalette(get_verifone_color())

        collapsible = CollapsibleWidget()
        self.init_logging(collapsible)

        self.init_download(collapsible)

        self.init_analyser(collapsible)

        collapsible.add_sections()
        # Scroll Area
        self.createLoggingDisplayLabel()
        self.scrollArea = QScrollArea()
        self.scrollArea.setBackgroundRole(QPalette.Dark)
        self.scrollArea.setWidget(self.text)
        self.scrollArea.setWidgetResizable(True)

        hLayout = QHBoxLayout()
        #hLayout.addLayout(vLayout)
        hLayout.addWidget(collapsible)
        hLayout.addWidget(self.scrollArea)

        self.setLayout(hLayout)

    def init_logging(self, collapsible):

        self.logger = QPushButton("Start Logging", self)
        self.logger.setFont(QFont("Times", 14, QFont.Bold))
        self.logger.clicked.connect(lambda: self.display_log_data())
        self.logger.setStyleSheet("background-color: white")

        #self.filterLayout = QtWidgets.QHBoxLayout()
        self.logFilterLabel = QLabel('Filter', self)
        self.logFilterLabel.setFont(QFont("Times", 14, QFont.Bold))
        self.logFilterLabel.setPalette(get_white_color_text())
        self.logFilterLabel.setFixedWidth(60)
        self.logFilter = QLineEdit(self)
        self.logFilter.setPalette(get_white_color())
        self.logFilter.setStyleSheet("background-color: white")
        self.logFilter.setFixedWidth(200)
        #self.filterLayout.addWidget(self.logFilterLabel, QtCore.Qt.AlignLeft)
        #self.filterLayout.addWidget(self.logFilter, QtCore.Qt.AlignLeft)

        self.serialList = QComboBox()
        ports = get_available_serial_ports()
        if (len(ports) == 1):
            self.serialList.addItem(ports[0])
            self.thread.set_comport(self.serialList.currentText())
        else:
            self.serialList.addItem("Select")
            for port in ports:
                self.serialList.addItem(port)

        self.serialList.currentIndexChanged.connect(
            lambda: self.set_serial_port())
        self.serialList.setStyleSheet("background-color: white")
        self.clear = QPushButton("Clear Log File", self)
        self.clear.setStyleSheet("background-color: white")
        self.clear.setFont(QFont("Times", 14, QFont.Bold))
        self.clear.clicked.connect(lambda: self.clear_data())

        widget = QFrame(collapsible.get_tree())
        widget.setPalette(get_verifone_color())
        title = "Logging"
        self.loggerGrid = QGridLayout(widget)
        self.loggerGrid.addWidget(self.logger, 0, 0, 1, 2)
        self.loggerGrid.addWidget(self.logFilterLabel, 1, 0, 1, 1)
        self.loggerGrid.addWidget(self.logFilter, 1, 1, 1, 1)
        self.loggerGrid.addWidget(self.serialList, 2, 0, 1, 2)
        self.loggerGrid.addWidget(self.clear, 3, 0, 1, 2)

        collapsible.include_section(title, widget)

    def init_download(self, collapsible):
        self.download = QPushButton("Download Package", self)
        self.download.setFont(QFont("Times", 14, QFont.Bold))
        self.download.clicked.connect(lambda: self.send_file())
        self.download.setStyleSheet("background-color: white")

        self.loadDownloadFile = QPushButton("Load File", self)
        self.loadDownloadFile.setFont(QFont("Times", 14, QFont.Bold))
        self.loadDownloadFile.clicked.connect(self.loadFromFile)
        self.loadDownloadFile.setStyleSheet("background-color: white")

        self.downloadFileName = QLineEdit("File name", self)
        self.downloadFileName.setStyleSheet("background-color: white")
        self.downloadFileName.setFixedWidth(300)

        self.downloadAddress = QLineEdit("IP Address", self)
        self.downloadAddress.setStyleSheet("background-color: white")
        self.downloadAddress.setFixedWidth(300)

        self.downloadStatus = QLabel("Download Status", self)
        self.downloadStatus.setStyleSheet(
            "background-color: rgba(3, 169, 229, 0); color : white")
        self.downloadStatus.setFixedWidth(300)
        widget = QFrame(collapsible.get_tree())
        title = "Download"

        self.downloadGrid = QGridLayout(widget)
        self.downloadGrid.addWidget(self.download, 0, 0, 1, 2)
        self.downloadGrid.addWidget(self.loadDownloadFile, 1, 0, 1, 2)
        self.downloadGrid.addWidget(self.downloadFileName, 2, 0, 1, 2)
        self.downloadGrid.addWidget(self.downloadAddress, 3, 0, 1, 2)
        self.downloadGrid.addWidget(self.downloadStatus, 4, 0, 1, 2)
        collapsible.include_section(title, widget)

    def init_analyser(self, collapsible):
        self.performanceData = QPushButton("View Performance Data", self)
        self.performanceData.setFont(QFont("Times", 14, QFont.Bold))
        self.performanceData.clicked.connect(
            lambda: self.display_performance_data())
        self.performanceData.setStyleSheet("background-color: white")

        self.performanceChart = QPushButton("View Performance Chart", self)
        self.performanceChart.setFont(QFont("Times", 14, QFont.Bold))
        self.performanceChart.clicked.connect(
            lambda: self.display_performance_chart())
        self.performanceChart.setStyleSheet("background-color: white")

        widget = QFrame(collapsible.get_tree())
        title = "Analyser"
        self.analyserGrid = QGridLayout(widget)
        self.analyserGrid.addWidget(self.performanceData, 0, 0, 1, 2)
        self.analyserGrid.addWidget(self.performanceChart, 1, 0, 1, 2)
        collapsible.include_section(title, widget)

    def loadFromFile(self):
        fileName, _ = QFileDialog.getOpenFileName(
            self, "Load Package", '', "Download Files (*.tgz);;All Files (*)")

        if not fileName:
            return

        try:
            in_file = open(str(fileName), 'rb')
        except IOError:
            QMessageBox.information(
                self, "Unable to open file",
                "There was an error opening \"%s\"" % fileName)
            return
        in_file.close()
        self.downloadFileName.setText(fileName)

    def createLoggingDisplayLabel(self):
        # Display Area
        self.text = QPlainTextEdit(self)
        self.text.setReadOnly(True)
        self.text.setFont(QFont("Times", 12, QFont.Bold))
        self.text.setTextInteractionFlags(Qt.TextSelectableByMouse
                                          | Qt.TextSelectableByKeyboard)

    def clear_data(self):
        self.text.clear()
        os.remove(logfile_path, dir_fd=None)

    def display_log_data(self):
        #send_file()

        if ('COM' in self.serialList.currentText()):
            self.createLoggingDisplayLabel()
            self.scrollArea.setWidget(self.text)
            self.thread.stop()
            self.thread.start()

            data = get_data_from_file(logfile_path)
            if (len(data) > 0 and data != None):
                self.text.appendPlainText(data)
            self.logger.setDisabled(True)

    def get_data(self, data):
        if (len(data) > 0):
            logFile = open(logfile_path, "a")
            logFile.write(data)
            logFile.close()
            filterText = self.logFilter.text()
            if filterText in data.rstrip():
                self.text.appendPlainText(data.rstrip())
                vbar = self.scrollArea.verticalScrollBar()
                vbar.setValue(vbar.maximum())

    def display_performance_data(self):
        self.thread.stop()
        data = get_data_from_file(logfile_path)
        jsonData = translate_data_to_json(data)
        self.performanceData = DisplayPerformanceData()
        self.performanceData.loadCsv(
            os.path.join(base_log_path, "performance_data.csv"))
        self.scrollArea.setWidget(self.performanceData)
        self.logger.setDisabled(False)

    def display_performance_chart(self):
        self.thread.stop()
        self.scrollArea.setWidget(get_performace_chart())
        self.logger.setDisabled(False)

    def set_serial_port(self):
        self.thread.set_comport(self.serialList.currentText())

    def send_file(self):
        base_path = os.path.join("c:/", "VFI", 'wks',
                                 'global-payment-application', 'GPA', 'output',
                                 'vos2', 'gpa', 'dl.gpa-1.0.0.0-000.tgz')
        fileName = self.downloadFileName.text()
        try:
            in_file = open(str(fileName), 'rb')
        except IOError:
            QMessageBox.information(
                self, "Unable to open file",
                "There was an error opening \"%s\"" % fileName)
            return
        in_file.close()

        load_vos_package_ip('192.168.0.104', fileName, self.downloadStatus)
Ejemplo n.º 12
0
class application(QTabWidget):
    bot = 0

    def __init__(self, parent=None):
        super(application, self).__init__(parent)
        self.bot = None
        self.db = sqlite3.connect('database')
        # tabs
        self.tab1 = QWidget()
        self.tab2 = QWidget()
        self.tab3 = QWidget()
        self.tab4 = QWidget()
        self.tab5 = QWidget()
        self.resize(640, 400)

        self.addTab(self.tab1, "Tab 1")
        self.addTab(self.tab2, "Tab 2")
        self.addTab(self.tab3, "Tab 3")
        self.addTab(self.tab4, "Tab 4")
        self.addTab(self.tab5, "Tab 5")

        # tab set keys
        self.h_box_key = QHBoxLayout()
        self.change_key_b = QPushButton("Edit keys")
        self.edit_1 = QLineEdit()
        self.edit_2 = QLineEdit()
        self.edit_3 = QLineEdit()
        self.edit_4 = QLineEdit()
        self.result = QLabel()
        self.set_button = QPushButton("Set keys")
        self.handle_info = QLabel()
        self.follower_info = QLabel()
        self.ready_lab = QLabel()

        # tab follow
        self.box_label = QLabel("Link to tweet")
        self.combo_label = QLabel("Mode")
        self.spin_label = QLabel("Limit before sleep")
        self.prog_bar = QProgressBar()
        self.combo_box = QComboBox()
        self.h_box = QHBoxLayout()
        self.spin_box = QSpinBox()
        self.link_box = QLineEdit()
        self.link_result = QLabel()
        self.follow_button = QPushButton("Follow Retweeters")
        self.cancel_button = QPushButton("Cancel")
        self.logger = QPlainTextEdit()
        self.h_box2 = QHBoxLayout()
        self.max_box = QSpinBox()
        self.max_label = QLabel("Max follows before stop")

        # tab unfollow
        self.unfollow_button = QPushButton("Unfollow Auto followers")
        self.unf_logger = QPlainTextEdit()
        self.unfollow_res = QLabel()
        self.prog_bar_unf = QProgressBar()
        self.unfollow_cancel = QPushButton("Cancel")
        self.unf_confirm = QMessageBox()

        # tab help
        self.help_box = QPlainTextEdit()
        self.help_label = QLabel(
            "<a href='http://Optumsense.com/'>http://Optumsense.com/</a>")

        #tab schedule
        self.tweet_box = QPlainTextEdit()
        self.date_time = QDateTimeEdit(QDateTime.currentDateTime())
        self.schedule_but = QPushButton("Schedule Tweet")
        self.schedule_info = QLabel()
        self.schedule_table = QTableView()

        # threads
        self.follow_thread = None
        self.unfollow_thread = None
        self.schedule_thread = None

        # tabs
        self.tab1UI()
        self.tab2UI()
        self.tab3UI()
        self.tab4UI()
        self.tab5UI()

        self.setWindowTitle("Optumize")
        self.setWindowIcon(QtGui.QIcon('assets/oo.png'))

        # db
        cursor = self.db.cursor()
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS keys(one TEXT, two TEXT, three TEXT, four TEXT)'''
                       )
        self.db.commit()

    def tab1UI(self):
        layout = QFormLayout()
        layout.addRow(self.h_box)
        self.h_box.addWidget(self.combo_label)
        self.combo_label.setAlignment(Qt.AlignRight)
        self.h_box.addWidget(self.combo_box)
        self.combo_box.addItem("Follow Retweeters")
        self.combo_box.addItem("Follow Followers")
        self.combo_box.currentIndexChanged.connect(self.selection_change)

        self.h_box.addWidget(self.spin_label)
        self.spin_label.setAlignment(Qt.AlignRight)
        self.h_box.addWidget(self.spin_box)
        self.spin_box.setMinimum(1)
        self.spin_box.setValue(30)

        layout.addRow(self.box_label, self.link_box)
        self.link_result.setAlignment(Qt.AlignCenter)
        layout.addRow(self.link_result)
        layout.addRow(self.follow_button)
        self.follow_button.clicked.connect(self.follow_ret)

        layout.addRow(self.cancel_button)
        self.cancel_button.clicked.connect(self.cancel_onclick)
        layout.addRow(self.h_box2)
        self.h_box2.addWidget(self.max_label)
        self.h_box2.addWidget(self.max_box)
        self.max_box.setFixedWidth(100)
        self.max_label.setAlignment(Qt.AlignRight)
        self.max_box.setMaximum(1000000)
        self.max_box.setValue(100)
        self.max_label.hide()
        self.max_box.hide()
        layout.addRow(self.logger)

        self.logger.setReadOnly(True)
        layout.addRow(self.prog_bar)
        self.prog_bar.setAlignment(Qt.AlignCenter)
        self.setTabText(0, "Follow")
        self.setTabIcon(0, QtGui.QIcon('assets/check_mark.png'))
        self.tab1.setLayout(layout)

    def selection_change(self, i):
        if i == 0:
            self.box_label.setText("Link to tweet")
            self.follow_button.setText("Follow Retweeters")
            self.link_result.setText("")
            self.max_label.hide()
            self.max_box.hide()
            self.follow_button.clicked.connect(self.follow_ret)
        else:
            self.box_label.setText("Handle of user")
            self.follow_button.setText("Follow Followers")
            self.link_result.setText("")
            self.max_label.show()
            self.max_box.show()
            self.max_label.setText("Max follows before stop")
            self.follow_button.clicked.connect(self.follow_fol)

    def cancel_onclick(self):
        if self.follow_thread is None:
            pass
        elif self.follow_thread.isRunning():
            self.prog_bar.setValue(0)
            self.logger.appendPlainText("Cancelled script")
            self.follow_thread.terminate()
            self.follow_thread = None

    def follow_ret(self):
        self.prog_bar.setValue(0)
        self.follow_button.setEnabled(False)
        self.link_result.setText("")
        self.logger.clear()
        limit = self.spin_box.value()
        if self.bot is None:
            self.link_result.setText(
                "<font color='red'>Configure access keys in set keys tab</font>"
            )
            return
        if self.follow_thread is not None:
            return
        link = self.link_box.text()
        id_tweet = link.split("/")[-1]
        try:
            tweet = self.bot.api.get_status(id_tweet)

            self.logger.appendPlainText(
                f"following retweeters from link: {link}...")
            self.follow_thread = FollowThread(self.bot, id_tweet, limit, 1, 0)
            self.follow_thread.start()
            self.connect(self.follow_thread, SIGNAL("finished()"), self.done)
            self.connect(self.follow_thread, SIGNAL("setup_prog(QString)"),
                         self.setup_prog)
            self.connect(self.follow_thread, SIGNAL("post_follow(QString)"),
                         self.post_follow)
        except tweepy.error.TweepError:
            self.follow_button.setEnabled(True)
            self.link_result.setText(
                "<font color='red'>Could not find tweet</font>")

    def setup_prog(self, msg):
        self.prog_bar.setMaximum(int(msg))

    def follow_fol(self):
        self.prog_bar.setValue(0)
        self.follow_button.setEnabled(False)
        self.link_result.setText("")
        self.logger.clear()
        limit = self.spin_box.value()
        if self.bot is None:
            self.link_result.setText(
                "<font color='red'>Configure access keys in set keys tab</font>"
            )
            return
        if self.follow_thread is not None:
            return
        handle = self.link_box.text()
        if handle == '':
            self.link_result.setText(
                "<font color='red'>Enter a handle above</font>")
            return
        elif handle[0] == '@':
            id_user = handle[1:]
        else:
            id_user = handle
        try:
            man = self.bot.api.get_user(id_user)
            self.logger.appendPlainText(
                f"following followers of {man.screen_name}...")
            self.logger.appendPlainText(f"Collecting")
            self.follow_thread = FollowThread(self.bot, id_user, limit, 2,
                                              self.max_box.value())
            self.follow_thread.start()
            self.connect(self.follow_thread, SIGNAL("finished()"), self.done)
            self.connect(self.follow_thread, SIGNAL("setup_prog(QString)"),
                         self.setup_prog)
            self.connect(self.follow_thread, SIGNAL("post_follow(QString)"),
                         self.post_follow)
        except tweepy.error.TweepError:
            self.follow_button.setEnabled(True)
            self.link_result.setText(
                "<font color='red'>Could not find user</font>")

    def post_follow(self, message):
        if message == "bad":
            self.logger.appendPlainText(
                "Rate limit exceeded... sleeping for cooldown")
        else:
            self.logger.appendPlainText(message)
            self.prog_bar.setValue(self.prog_bar.value() + 1)

    def done(self):
        self.follow_thread = None
        self.follow_button.setEnabled(True)

    def tab2UI(self):
        layout = QFormLayout()
        layout.addRow(self.unfollow_button)
        layout.addRow(self.unfollow_cancel)
        layout.addRow(self.unfollow_res)
        self.unfollow_res.setAlignment(Qt.AlignCenter)
        self.unfollow_button.clicked.connect(self.unfollow_fol)
        self.unfollow_cancel.clicked.connect(self.unfollow_can)
        layout.addWidget(self.unf_logger)
        self.unf_logger.setReadOnly(True)
        layout.addRow(self.prog_bar_unf)
        self.prog_bar_unf.setAlignment(Qt.AlignCenter)
        self.setTabText(1, "Unfollow")
        self.setTabIcon(1, QtGui.QIcon('assets/cross.png'))
        self.tab2.setLayout(layout)

    def unfollow_fol(self):
        self.unfollow_button.setEnabled(False)
        self.unfollow_thread = UnfollowThread(self.bot)
        self.unfollow_thread.start()
        self.connect(self.unfollow_thread, SIGNAL("post_unfol(QString)"),
                     self.post_unfol)
        self.connect(self.unfollow_thread, SIGNAL("finished()"), self.done_unf)

    def done_unf(self):
        self.unfollow_thread = None
        self.unf_logger.appendPlainText("Done")
        self.unfollow_button.setEnabled(True)

    def post_unfol(self, msg):
        if msg == "bad":
            self.unf_logger.appendPlainText(
                "rate limit exceeded, resting for 15 minutes")
        else:
            self.unf_logger.appendPlainText(f"Unfollowing {msg}")

    def unfollow_can(self):
        if self.unfollow_thread is None:
            pass
        elif self.unfollow_thread.isRunning():
            self.unf_logger.appendPlainText("Cancelled script")
            self.unfollow_thread.terminate()
            self.unfollow_thread = None

    def tab3UI(self):
        layout = QFormLayout()
        layout.addWidget(self.tweet_box)
        self.tweet_box.setMaximumHeight(150)
        self.tweet_box.setPlaceholderText("Tweet contents")
        layout.addRow(self.date_time)
        self.date_time.setCalendarPopup(True)
        layout.addRow(self.schedule_info)
        layout.addRow(self.schedule_but)
        self.schedule_but.clicked.connect(self.schedule_tweet)
        layout.addWidget(self.schedule_table)
        self.setTabText(2, "Schedule Tweet")
        self.setTabIcon(2, QtGui.QIcon('assets/calendar.png'))
        self.tab3.setLayout(layout)

    def schedule_tweet(self):
        tweet_contents = self.tweet_box.toPlainText()
        if (len(tweet_contents) == 0):
            print("length of tweet is 0")
            self.schedule_info.setText("length of tweet is 0")
            return
        elif (len(tweet_contents) >= 280):
            self.schedule_info.setText("Tweet char limit exceeded")
            return
        if self.bot is None:
            self.schedule_info.setText(
                "<font color='red'>Configure access keys in set keys tab</font>"
            )
            return
        datetime = self.date_time.text()
        try:
            print("done")
            self.schedule_thread.start()
            self.schedule_thread.add_tweet(tweet_contents, datetime)
        except:
            self.follow_button.setEnabled(True)
            self.link_result.setText(
                "<font color='red'>Could not find user</font>")

    def done_schedule(self):
        print("done scheduler")

    def tab4UI(self):
        layout = QFormLayout()
        layout.addRow("API key", self.edit_1)
        layout.addRow("API key secret", self.edit_2)
        layout.addRow("Auth token", self.edit_3)
        layout.addRow("Auth token secret", self.edit_4)
        self.set_button.clicked.connect(self.set_keys)
        l = self.read_file()
        if l is not None:
            if len(l) == 4:
                self.edit_1.setText(l[0])
                self.edit_2.setText(l[1])
                self.edit_3.setText(l[2])
                self.edit_4.setText(l[3])
                self.set_keys()
        layout.addRow(self.result)
        self.result.setAlignment(Qt.AlignCenter)
        layout.addRow(self.h_box_key)
        self.h_box_key.addWidget(self.change_key_b)
        self.h_box_key.addWidget(self.set_button)
        self.change_key_b.clicked.connect(self.change_keys)
        layout.addRow(self.handle_info)
        self.handle_info.setAlignment(Qt.AlignCenter)
        layout.addRow(self.follower_info)
        self.follower_info.setAlignment(Qt.AlignCenter)
        layout.addRow(self.ready_lab)
        self.ready_lab.setAlignment(Qt.AlignCenter)
        self.setTabText(3, "Settings")
        self.setTabIcon(3, QtGui.QIcon('assets/settings.png'))
        self.tab4.setLayout(layout)

    def change_keys(self):
        self.set_button.setEnabled(True)

    def set_keys(self):
        self.set_button.setEnabled(False)
        self.result.setText("")
        one = self.edit_1.text()
        two = self.edit_2.text()
        three = self.edit_3.text()
        four = self.edit_4.text()
        try:
            self.bot = apiconnector.ApiConnector(one, two, three, four)
            me = self.bot.add_keys(one, two, three, four)
            self.handle_info.setText("Handle: @" + me.screen_name)
            self.follower_info.setText("Followers: " + str(me.followers_count))
            self.ready_lab.setText("<font color='green'>Ready!</font>")
            cursor = self.db.cursor()
            cursor.execute('DELETE FROM keys;', )
            cursor.execute(
                '''INSERT INTO keys(one, two, three, four)
                  VALUES(?,?,?,?)''', (one, two, three, four))
            self.db.commit()
            self.schedule_thread = ScheduleThread(self.bot)
        except:
            print("Could not authenticate you")
            self.result.setText(
                "<font color='red'>Could not authenticate you</font>")

    def read_file(self):
        result = []
        try:
            cursor = self.db.cursor()
            cursor.execute('''SELECT one, two, three, four FROM keys''')
            all_rows = cursor.fetchall()
            for row in all_rows:
                result.append(row[0])
                result.append(row[1])
                result.append(row[2])
                result.append(row[3])
            return result

        except:
            return None

    def tab5UI(self):
        layout = QFormLayout()
        layout.addRow("Website", self.help_label)
        self.help_label.setOpenExternalLinks(True)
        self.setTabText(4, "Help")
        self.setTabIcon(4, QtGui.QIcon('assets/help.png'))
        self.tab5.setLayout(layout)
Ejemplo n.º 13
0
class MyTextEditor(QMainWindow):

    def __init__(self):
        QMainWindow.__init__(self)
        self.textEdit =  QPlainTextEdit()
        self.setCentralWidget(self.textEdit)
    
        self.createActions()

        self.readSettings()
    
        self.setCurrentFile("")

    def createActions(self):
        
        self.toolBar = self.addToolBar("main tool bar")
        self.menuBar = self.menuBar()
        self.fileMenu = self.menuBar.addMenu('File')
        self.helpMenu = self.menuBar.addMenu('Help')

        
        Act = QAction(QIcon(":/icons/new.png"), self.tr("&New"), self)
        Act.setShortcuts(QKeySequence.New)
        Act.setStatusTip(self.tr("Create a new file"))
        Act.triggered.connect(self.newFile)
     
        self.fileMenu.addAction(Act)
        self.toolBar.addAction(Act)
        
        openAct =  QAction(QIcon(":/icons/openconf.png"), self.tr("&Open..."), self)
        openAct.setShortcuts(QKeySequence.Open)
        openAct.setStatusTip(self.tr("Open an existing file"))
        self.fileMenu.addAction(openAct)
        self.toolBar.addAction(openAct)
        openAct.triggered.connect(self.open)

        saveAct =  QAction(QIcon(":/icons/save.png"), self.tr("&Save..."), self)
        saveAct.setShortcuts(QKeySequence.Save)
        saveAct.setStatusTip(self.tr("Save a file"))
        self.fileMenu.addAction(saveAct)
        self.toolBar.addAction(saveAct)
        saveAct.triggered.connect(self.save)


        self.fileMenu.addSeparator()

        quitAct =  QAction(QIcon(":/icons/exit.png"), self.tr("&Exit..."), self)
        quitAct.setShortcuts(QKeySequence.Close)
        quitAct.setStatusTip(self.tr("Exit"))
        self.fileMenu.addAction(quitAct)
        self.toolBar.addAction(quitAct)
        quitAct.triggered.connect(self.exit)


        aboutQtAct =  QAction(self.tr("About &Qt"), self)
        aboutQtAct.setStatusTip(self.tr("Show the Qt library's About box"))
        aboutQtAct.triggered.connect(self.about)
        self.helpMenu.addAction(aboutQtAct)
        
    def loadFile(self, fileName):
        file = QFile(fileName)
        if not file.open(QFile.ReadOnly | QFile.Text):
            QMessageBox.warning(self, self.tr("Application"), self.tr("Cannot read file "
                "{}:\n{}.".format(fileName, file.errorString())))
            return
    
        inStream = QTextStream(file)
        QApplication.setOverrideCursor(QtGui.Qt.WaitCursor)
        self.textEdit.setPlainText(inStream.readAll())
        print(inStream.readAll())
        QApplication.restoreOverrideCursor()
    
        self.setCurrentFile(fileName)
        self.statusBar().showMessage(self.tr("File loaded"), 2000)
        
    def newFile(self):
        if self.maybeSave():
            self.fileName = QFileDialog.getOpenFileName(self)
            if not self.fileName == "":
                self.loadFile(self.fileName[0])
    
    def open(self):
        if self.maybeSave():
            fileName = QFileDialog.getOpenFileName(self)
            if not fileName == "" :
                self.loadFile(fileName[0])
    
    def save(self):
        if self.curFile == "":
            return self.saveAs()
        else:
            return self.saveFile(self.curFile)

    def saveAs(self):
        fileName = QFileDialog.getSaveFileName(self)
        if fileName == "" :
            return False
        return self.saveFile(fileName[0])      

    def saveFile(self, fileName):
        file = QFile(fileName)
        if not file.open(QFile.WriteOnly | QFile.Text):
            QMessageBox.warning(self, self.tr("Application"),
                                 self.tr("Cannot write file %1:\n%2.")
                                 .arg(fileName)
                                 .arg(file.errorString()))
            return False
    
        out = QTextStream(file)
        QApplication.setOverrideCursor(QtGui.Qt.WaitCursor)
        print (self.textEdit.toPlainText())
        out << self.textEdit.toPlainText()
        QApplication.restoreOverrideCursor()
    
        self.setCurrentFile(fileName)
        self.statusBar().showMessage(self.tr("File saved"), 2000)
        return True

    def documentWasModified(self):
        self.setWindowModified(self.textEdit.document().isModified())
        
    def about(self):
       QMessageBox.about(self, self.tr("About Application"),
                self.tr("The <b>Application</b> example demonstrates how to "
                   "write modern GUI applications using Qt, with a menu bar, "
                   "toolbars, and a status bar."))                          
    def File(self):
        if self.maybeSave():
            self.textEdit.clear()
            self.setCurrentFile("")

    def setCurrentFile(self,fileName):
        self.curFile = fileName
        self.textEdit.document().setModified(False)
        self.setWindowModified(False)
    
        if self.curFile == "":
            shownName = "untitled.txt"
        else:
            shownName = self.strippedName(self.curFile)
    
        self.setWindowTitle(self.tr("{}[*] - {}").format(shownName,self.tr("Application")))    

    def strippedName(self, fullFileName):
        return QFileInfo(fullFileName).fileName()


    def readSettings(self):
        settings = QSettings("Trolltech", "Application Example")
        pos = settings.value("pos", QPoint(200, 200))
        size = settings.value("size", QSize(400, 400))
        self.resize(size)
        self.move(pos)

    def writeSettings(self):
        settings = QSettings("Trolltech", "Application Example")
        settings.setValue("pos", self.pos())
        settings.setValue("size", self.size())
                    
    def closeEvent(self, event):
        if self.maybeSave():
            self.writeSettings()
            event.accept()
        else:
            event.ignore()   

    def exit(self):
        self.close() #with call to closeEvent
        #self.deleteLater() #Do not call closeEvent
        
    def maybeSave(self):
        if self.textEdit.document().isModified():
            ret = QMessageBox.warning(self, self.tr("Application"),
                                      self.tr("The document has been modified.\n"
                                         "Do you want to save your changes?"),
                                     QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel)
            if ret == QMessageBox.Save:
                return self.save()
            elif ret == QMessageBox.Cancel:
                return False
        return True                
Ejemplo n.º 14
0
class BibTeXWidget(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self._source = None
        self._table = None
        self._id = -1
        self._inspire_id = None
        self._doi = None
        self._bibtex_string = ""

        self._fetcher = Fetcher()
        self._fetcher.BatchReady.connect(self._HandleBatchReady)
        self._fetcher.FetchingFinished.connect(self._HandleFetchingCompleted)

        self._text_edit = QPlainTextEdit()
        font = QFont("Monospace")
        self._text_edit.setFont(font)
        self._text_edit.setTextInteractionFlags(
            Qt.TextInteractionFlag.TextSelectableByKeyboard
            | Qt.TextInteractionFlag.TextSelectableByMouse)
        self._text_edit.setEnabled(False)

        self._dowload_inspire = QToolButton()
        self._dowload_inspire.setIcon(QIcon(icons.INSPIRE))
        self._dowload_inspire.clicked.connect(self._FetchINSPIRE)
        self._dowload_inspire.setEnabled(False)

        self._dowload_doi = QToolButton()
        self._dowload_doi.setIcon(QIcon(icons.DOI))
        self._dowload_doi.clicked.connect(self._FetchDOI)
        self._dowload_doi.setEnabled(False)

        self._SetupUI()

    def _SetupUI(self):
        tool_widget = QWidget()
        tool_layout = QHBoxLayout()
        tool_layout.setContentsMargins(0, 0, 0, 0)
        tool_layout.addWidget(self._dowload_inspire)
        tool_layout.addWidget(self._dowload_doi)
        tool_layout.addStretch(1)
        tool_widget.setLayout(tool_layout)

        layout = QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self._text_edit)
        layout.addWidget(tool_widget)
        self.setLayout(layout)

    def SetTable(self, database_table):
        if self._table == database_table:
            return

        if self._table is not None:
            self._table.Cleared.disconnect(self.Clear)

        self._table = database_table
        self._table.Cleared.connect(self.Clear)

    def Clear(self):
        self._text_edit.clear()
        self._text_edit.setEnabled(False)
        self._dowload_inspire.setEnabled(False)
        self._dowload_doi.setEnabled(False)

    def DisplayItem(self, id_):
        # NOTE: What if the item gets updated?

        if self._id == id_:
            return

        self._id = id_
        self._fetcher.Stop()
        self.Clear()

        if self._id == -1:
            return

        record = self._table.GetRow(self._id, ("inspire_id", "dois"))
        self._inspire_id = record["inspire_id"]
        self._doi = None if record["dois"] == [] else record["dois"][0]
        has_inspire_id = self._inspire_id is not None
        has_doi = self._doi is not None

        self._text_edit.setEnabled(has_inspire_id | has_doi)
        self._dowload_inspire.setEnabled(has_inspire_id)
        self._dowload_doi.setEnabled(has_doi)

    def _FetchINSPIRE(self):
        self._fetcher.Fetch(InspireBibTeXPlugin,
                            "recid:" + str(self._inspire_id),
                            batch_size=2)

    def _FetchDOI(self):
        self._fetcher.Fetch(DOIBibTeXPlugin, self._doi)

    def _HandleBatchReady(self, batch):
        self._bibtex_string = batch[0]

    def _HandleFetchingCompleted(self, records_number):
        self._text_edit.setPlainText(self._bibtex_string)