예제 #1
0
class ANoise:
    """Control the sound indicator"""
    def __init__(self):
        # These 3 are needed
        GObject.threads_init()
        DBusGMainLoop(set_as_default=True)
        Gst.init(None)
        GLib.set_application_name(_('Ambient Noise'))
        self.sound_menu = SoundMenuControls('Ambient Noise', 'anoise')
        self.noise = Noise()
        self.win_preferences = Preferences(self)

        try:
            self.keybinder = Keybinder
            self.keybinder.init()
            if self.keybinder.bind('AudioPlay', self._sound_menu_play_toggle,
                                   None):
                self.keybinder.bind('AudioStop', self._sound_menu_stop, None)
                self.keybinder.bind('AudioPause', self._sound_menu_pause, None)
                self.keybinder.bind('AudioNext', self._sound_menu_next, None)
                self.keybinder.bind('AudioPrev', self._sound_menu_previous,
                                    None)
            else:
                self.keybinder = None

        except (ValueError, ImportError):
            self.keybinder = None

        # Need in a few DE
        try:
            self.window = GUI(self)
        except:
            pass

        self.player = Gst.ElementFactory.make(PLAYBIN, "player")
        self.player.connect("about-to-finish", self._loop)

        dummy_i18n = (_("Coffee Shop"), _("Fire"), _("Forest"), _("Night"),
                      _("Rain"), _("River"), _("Sea"), _("Storm"), _("Wind")
                      )  # Need i18n

        # Overwrite libraty methods
        self.sound_menu._sound_menu_is_playing = self._sound_menu_is_playing
        self.sound_menu._sound_menu_play = self._sound_menu_play
        self.sound_menu._sound_menu_pause = self._sound_menu_pause
        self.sound_menu._sound_menu_next = self._sound_menu_next
        self.sound_menu._sound_menu_previous = self._sound_menu_previous
        self.sound_menu._sound_menu_raise = self._sound_menu_raise
        self.sound_menu._sound_menu_play_toggle = self._sound_menu_play_toggle

        # Autostart when click on sound indicator icon
        threading.Timer(1, self._sound_menu_play).start()

    def _loop(self, message):
        """Start again the same sound in the EOS"""
        self.player.set_property('uri', self.noise.get_current_filename_uri())

    def _sound_menu_is_playing(self):
        """Called in the first click"""
        return self.is_playing

    def _sound_menu_play_toggle(self, keypress=None, data=None):
        """Play toggle, media keys have an expectation that play is a toggle"""
        if self.is_playing:
            self._sound_menu_pause('AudioPause')
        else:
            self._sound_menu_play('AudioPlay')

    def _sound_menu_play(self, keypress=None, data=None):
        """Play"""
        self.is_playing = True  # Need to overwrite this for an issue with autstart
        self.sound_menu.song_changed(
            self.noise.get_current_index(), '', '', self.noise.get_name(),
            urllib.parse.quote(self.noise.get_icon_uri(), ':/'),
            urllib.parse.quote(self.noise.get_current_filename_uri(), ':/'))
        self.player.set_property('uri', self.noise.get_current_filename_uri())
        self.player.set_state(Gst.State.PLAYING)
        self.sound_menu.signal_playing()

    def _sound_menu_stop(self, keypress=None, data=None):
        """Stop, different from pause in that it sets the pointer of the track to the start again"""
        self.is_playing = False
        self.player.set_state(
            Gst.State.READY)  # assuming this is akin to stop?
        self.sound_menu.signal_stopped()

    def _sound_menu_pause(self, keypress=None, data=None):
        """Pause"""
        self.is_playing = False  # Need to overwrite this for an issue with autstart
        self.player.set_state(Gst.State.PAUSED)
        self.sound_menu.signal_paused()

    def _set_new_play(self, what):
        """Next or Previous"""
        # Get Next/Previous
        if what == 'next':
            self.noise.set_next()
        if what == 'previous':
            self.noise.set_previous()
        # From pause?
        self.player.set_state(Gst.State.READY)
        # Play
        if self.is_playing:
            self._sound_menu_play()
        else:
            self.sound_menu.song_changed(
                self.noise.get_current_index(), '', '', self.noise.get_name(),
                urllib.parse.quote(self.noise.get_icon_uri(), ':/'),
                urllib.parse.quote(self.noise.get_current_filename_uri(),
                                   ':/'))

    def _sound_menu_previous(self, keypress=None, data=None):
        """Previous"""
        self._set_new_play('previous')

    def _sound_menu_next(self, keypress=None, data=None):
        """Next"""
        self._set_new_play('next')

    def _sound_menu_raise(self):
        """Click on player"""
        self.win_preferences.show()

    def set_timer(self, enable, seconds):
        if enable:
            self.timer = threading.Timer(seconds, self._set_future_pause)
            self.timer.start()
        else:
            self.timer.cancel()

    def _set_future_pause(self):
        self.win_preferences.set_show_timer()
        self._sound_menu_pause()
예제 #2
0
 def open_preferences(self, widget):
     ConfigManager.disable_losefocus_temporary = True
     prefs = Preferences()
     prefs.show()
예제 #3
0
파일: anoise.py 프로젝트: Claymor3/anoise
class ANoise:
    """Control the sound indicator"""
    def __init__(self):
        # These 3 are need
        GObject.threads_init()
        DBusGMainLoop(set_as_default=True)
        Gst.init(None)
        
        self.sound_menu = SoundMenuControls('anoise')
        self.noise = Noise()
        self.win_preferences = Preferences(self)
        
        # Need in a few DE
        try:
            self.window = GUI(self)
        except:
            pass
        
        self.player = Gst.ElementFactory.make(PLAYBIN, "player")
        self.player.connect("about-to-finish", self._loop)
        
        self.player.set_property('uri', self.noise.get_current_filename())
        self.is_playing = True
        
        dummy_i18n = (_("Coffee Shop"), _("Fire"), _("Forest"), _("Night"), _("Rain"), _("River"), _("Sea"), _("Storm"), _("Wind")) # Need i18n
        
        # Overwrite libraty methods
        self.sound_menu._sound_menu_is_playing = self._sound_menu_is_playing
        self.sound_menu._sound_menu_play       = self._sound_menu_play
        self.sound_menu._sound_menu_pause      = self._sound_menu_pause
        self.sound_menu._sound_menu_next       = self._sound_menu_next
        self.sound_menu._sound_menu_previous   = self._sound_menu_previous
        self.sound_menu._sound_menu_raise      = self._sound_menu_raise
        
        # Autostart when click on sound indicator icon
        threading.Timer(2, self._sound_menu_play).start()
    
    def _loop(self, message):
        """Start again the same sound in the EOS"""
        self.player.set_property('uri', self.noise.get_current_filename())
    
    def _sound_menu_is_playing(self):
        """Called in the first click"""
        return self.is_playing
    
    def _sound_menu_play(self):
        """Play"""
        self.is_playing = True # Need to overwrite this for an issue with autstart
        self.sound_menu.song_changed('', '', self.noise.get_name(), self.noise.get_icon())
        self.player.set_state(Gst.State.PLAYING)
        self.sound_menu.signal_playing()
    
    def _sound_menu_pause(self):
        """Pause"""
        self.is_playing = False # Need to overwrite this for an issue with autstart
        self.player.set_state(Gst.State.PAUSED)
        self.sound_menu.signal_paused()
    
    def _set_new_play(self, what):
        """Next or Previous"""
        self.noise.refresh_all_ogg()
        # Get Next/Previous
        if what == 'next':
            self.noise.set_next()
        if what == 'previous':
            self.noise.set_previous()
        # From pause?
        self.player.set_state(Gst.State.READY)
        if not self.is_playing:
            self.is_playing = True
        # Set new sound
        self.player.set_property('uri', self.noise.get_current_filename())
        # Play
        self._sound_menu_play()
    
    def _sound_menu_previous(self):
        """Previous"""
        self._set_new_play('previous')
    
    def _sound_menu_next(self):
        """Next"""
        self._set_new_play('next')
    
    def _sound_menu_raise(self):
        """Click on player"""
        self.win_preferences.show()
    
    def set_timer(self, enable, seconds):
        if enable:
            self.timer = threading.Timer(seconds, self._set_future_pause)
            self.timer.start()
        else:
            self.timer.cancel()
    
    def _set_future_pause(self):
        self.win_preferences.set_show_timer()
        self._sound_menu_pause()
예제 #4
0
class GUI:
    """This will be for DE as MATE 14.10+ which hasn't sound indicator with Gtk3"""
    def __init__(self, player):
        self.player = player
        self.win_preferences = Preferences(self)

        builder = Gtk.Builder()
        builder.add_from_file('/usr/share/anoise/anoise.ui')
        self.win_icon = builder.get_object('icon_noise')
        self.btn_play = builder.get_object('btn_play')
        self.lbl_title = builder.get_object('lbl_title')
        builder.connect_signals(self)
        self.window = builder.get_object('main_win')
        self.window.show_all()
        self._set_window_icon()

    def _set_window_icon(self):
        try:
            self.window.set_icon_from_file(
                self.player.noise.get_icon().replace('file://', ''))
            self.win_icon.set_from_file(self.player.noise.get_icon().replace(
                'file://', ''))
        except:
            self.window.set_icon_from_file(
                '/usr/share/icons/hicolor/48x48/apps/anoise.png')
            self.win_icon.set_from_file(
                '/usr/share/icons/hicolor/48x48/apps/anoise.png')
        self.lbl_title.set_text(self.player.noise.get_name())

    def on_btn_previous_clicked(self, widget, data=None):
        self.player._set_new_play('previous')
        image = Gtk.Image(stock=Gtk.STOCK_MEDIA_PAUSE)
        self.btn_play.set_image(image)
        self._set_window_icon()

    def on_btn_next_clicked(self, widget, data=None):
        self.player._set_new_play('next')
        image = Gtk.Image(stock=Gtk.STOCK_MEDIA_PAUSE)
        self.btn_play.set_image(image)
        self._set_window_icon()

    def _play(self):
        self.player.is_playing = True
        self.player._sound_menu_play()
        image = Gtk.Image(stock=Gtk.STOCK_MEDIA_PAUSE)
        self.btn_play.set_image(image)

    def _pause(self):
        if self.player.is_playing:
            self.player.is_playing = False
        self.player._sound_menu_pause()
        image = Gtk.Image(stock=Gtk.STOCK_MEDIA_PLAY)
        self.btn_play.set_image(image)

    def on_btn_play_pause_clicked(self, widget, data=None):
        if self.player.is_playing:
            self._pause()
        else:
            self._play()

    def on_menu_preferences_activate(self, widget, data=None):
        self.win_preferences.show()

    def set_timer(self, enable, seconds):
        if enable:
            self.timer = threading.Timer(seconds, self._set_future_pause)
            self.timer.start()
        else:
            self.timer.cancel()

    def _set_future_pause(self):
        self.win_preferences.set_show_timer()
        self._pause()

    def on_menu_about_activate(self, widget, data=None):
        webbrowser.open_new('http://anoise.tuxfamily.org')

    def on_main_win_delete_event(self, widget, data=None):
        try:
            self.timer.cancel()
        except:
            pass
        Gtk.main_quit()
예제 #5
0
 def open_preferences(self, widget):
     ConfigManager.disable_losefocus_temporary = True
     prefs = Preferences()
     prefs.show()
예제 #6
0
class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setupUi(self)

        self.tableWidget_dropzone.setColumnCount(3)
        self.tableWidget_dropzone.setRowCount(9)
        self.tableWidget_dropzone.setAcceptDrops(True)
        self.tableWidget_dropzone.setColumnWidth(0, 192)
        self.tableWidget_dropzone.setColumnWidth(1, 192)
        self.tableWidget_dropzone.setColumnWidth(2, 192)
        self.tableWidget_dropzone.setHorizontalHeaderLabels(['A1', 'A2', 'A3'])
        self.tableWidget_dropzone.setVerticalHeaderLabels(
            ['', 'R1', 'R2', 'R3', 'R4', 'R5', 'R6', 'R7', 'R8'])

        arrayUpload_settings = QSettings('vll', 'arrayUpload')
        path1 = arrayUpload_settings.value('path1', type=str)

        self.label_d1_data.setText(path1)

        dpath = 'C:/'

        comboBox1 = DataCombo(dpath)
        comboBox2 = QComboBox()
        comboBox3 = QComboBox()

        self.tableWidget_dropzone.setCellWidget(0, 0, comboBox1)
        self.tableWidget_dropzone.setCellWidget(0, 1, comboBox2)
        self.tableWidget_dropzone.setCellWidget(0, 2, comboBox3)

        self.loadExcel()
        self.load_samples()

        self.actionPreferences.triggered.connect(self.show_preferences)

    def loadExcel(self):

        book = xlrd.open_workbook("C:/Users/parla/Documents/test.xls", 'r')
        sheet = book.sheet_by_index(0)

        self.tableWidget_XLS.setColumnCount(sheet.ncols + 10)
        self.tableWidget_XLS.setRowCount(sheet.nrows + 10)

        self.check_change = False

        for row_index in range(0, sheet.nrows):

            for col_index in range(0, sheet.ncols):

                content = sheet.cell(row_index, col_index).value
                item = QTableWidgetItem(content)
                self.tableWidget_XLS.setItem(row_index, col_index, item)
                self.tableWidget_XLS.setDragEnabled(True)

        self.check_change = True

    def load_samples(self):

        files = os.listdir("C:/Users/parla/Documents/")
        sfiles = natsorted(files)
        sfiles.insert(0, " -- none selected -- ")

        for f in sfiles:
            # print(f)
            if f.endswith('.xls') or f.endswith(' -- none selected -- '):
                self.load_samples_comboBox.addItem(f)

    def show_preferences(self):
        self.p = Preferences(self)
        self.p.show()
예제 #7
0
class NoduleCADx(QMainWindow):
    def __init__(self):
        super().__init__()
        loadUi('mainwindow.ui', self)
        self.setWindowFlags(Qt.WindowMaximizeButtonHint
                            | Qt.WindowMinimizeButtonHint
                            | Qt.WindowCloseButtonHint)

        self.display_dialog = None
        # ColumnWidth of Patient List
        self.treeWidget.setColumnWidth(0, 70)
        self.treeWidget.setColumnWidth(1, 100)
        self.treeWidget.setColumnWidth(2, 100)
        self.treeWidget.setColumnWidth(3, 50)
        self.treeWidget.setColumnWidth(4, 50)
        # ColumnWidth of Scan and Nodule List
        self.noduletreeWidget.setColumnWidth(0, 70)
        self.noduletreeWidget.setColumnWidth(1, 100)
        self.noduletreeWidget.setColumnWidth(2, 100)
        self.noduletreeWidget.setColumnWidth(3, 50)
        self.noduletreeWidget.setColumnWidth(4, 100)
        self.noduletreeWidget.setColumnWidth(5, 100)
        self.noduletreeWidget.setColumnWidth(6, 100)
        self.noduletreeWidget.setColumnWidth(7, 100)
        self.noduletreeWidget.setColumnWidth(8, 100)
        self.preferences_dialog = None

        # pkg_name is the JSON file saved all the detected information (including scan path)
        # create a pkg_name.json if it doesn't exist.
        if not os.path.exists(pkg_name):
            with open(pkg_name, 'w') as json_file:
                initial_json = {
                    'app': 'Nodule CADx',
                    'version': '1.0.0',
                    "preferences": {
                        "threshold": "0.8",
                        "project_directory": os.getcwd(),
                        "automatic_classification": True,
                        "windowlevel": "?"
                    },
                    'members': []
                }
                json.dump(initial_json, json_file, indent=2)

        # load pkg_name.json
        with open(pkg_name, 'r') as f:
            self.data = json.load(f)
        # load nodulenet and classification model and refresh patient list.
        self.nodulenet_model = None
        self.classification_model = None
        self.load_model()
        self.refresh_patient_list()

    def load_model(self):
        """
        Load (1)NoduleNet and (2)Classification model.
        Since I didn't install NoduleNet on my macOS, so only load it on Windows10.
        """
        # NoduleNet model
        if use_win10:
            args = parser.parse_args()
            initial_checkpoint = args.weight
            net = args.net
            net = getattr(this_module, net)(config)
            if initial_checkpoint:
                print('[Loading model from %s]' % initial_checkpoint)
                checkpoint = torch.load(initial_checkpoint, map_location='cpu')
                net.load_state_dict(checkpoint['state_dict'], )
            else:
                print('No model weight file specified')
            net.set_mode('eval')
            net.use_mask = True
            net.use_rcnn = True
            self.nodulenet_model = net
        else:
            self.nodulenet_model = None

        # Classification model
        self.classification_model = joblib.load(
            'model/classification_model.pkl')

    @pyqtSlot()
    def on_reportButton_clicked(self):
        """
        Export system report in CSV format.
        """
        report = [[
            'Name', 'Date of Birth', 'Sex', 'Final-Score', 'Management',
            'Scan Path', 'Nodule', 'Diameter', 'Type', 'Calcification',
            'Spiculation', 'Perifissural', 'Endobronchial', 'Score'
        ]]
        for m in self.data['members']:
            report.append([
                m['patient_name'], m['date_of_birth'], m['sex'], m['score'],
                m['management']
            ])
            for s in m['scans']:
                report.append([''] * 5 + [s['scan_path']])
                for i, n in enumerate(s['nodules'], start=1):
                    type_name = self.get_type_name(n['type'])
                    report.append([''] * 6 + [
                        f'Nodule{i}', n['diameter'], type_name,
                        n['calcification'], n['spiculation'],
                        n['perifissural'], n['endobronchial'], n['score']
                    ])
        with open('report.csv', 'w') as csvfile:
            writer = csv.writer(csvfile)
            writer.writerows(report)

    @staticmethod
    def get_type_name(nodule_type):
        """
        Get type name for display.
        """
        if nodule_type == '1':
            return 'non-solid'
        elif nodule_type == '2':
            return 'non/part'
        elif nodule_type == '3':
            return 'part-solid'
        elif nodule_type == '4':
            return 'part/solid'
        elif nodule_type == '5':
            return 'solid'

    def refresh_patient_list(self):
        """
        refresh patient list (upper block of main window).
        """
        self.treeWidget.clear()
        for m in self.data['members']:
            scan_item = QTreeWidgetItem(self.treeWidget, [
                '\u2713' if m['updated'] else '\u2717', m['patient_name'],
                m['date_of_birth'], m['sex'], m['score'], m['management']
            ])
            for i in range(scan_item.columnCount()):
                scan_item.setTextAlignment(i, Qt.AlignHCenter)

    def refresh_scan_list(self, member):
        """
        refresh scan and nodule list (lower block of main window).
        """
        self.noduletreeWidget.clear()
        for scan in member['scans']:
            p = QTreeWidgetItem(self.noduletreeWidget, [
                '\u2713' if scan['updated'] else '\u2717', scan['scan_date'],
                scan['scan_path']
            ])
            if scan['updated']:
                for count, nodule in enumerate(scan['nodules'], start=1):
                    type_name = self.get_type_name(nodule['type'])
                    n_item = QTreeWidgetItem(p, [
                        '', '', f'Nodule{count}',
                        str(nodule['prob']),
                        str(nodule['diameter']), type_name,
                        str(nodule['calcification']),
                        str(nodule['spiculation']),
                        str(nodule['perifissural']),
                        str(nodule['endobronchial']), nodule['score']
                    ])
                    for i in range(n_item.columnCount()):
                        n_item.setTextAlignment(i, Qt.AlignHCenter)
            for i in range(p.columnCount()):
                p.setTextAlignment(i, Qt.AlignHCenter)
        self.noduletreeWidget.expandAll()

    @pyqtSlot()
    def on_actionPreferences_triggered(self):
        if not self.preferences_dialog:
            self.preferences_dialog = Preferences(self.data['preferences'])
            self.preferences_dialog.rejected.connect(self.update_preferences)
        self.preferences_dialog.show()

    def update_preferences(self):
        """
        update preferences when OK in preferences dialog is clicked.
        """
        self.data['preferences'] = self.preferences_dialog.preferences

    def on_treeWidget_itemClicked(self):
        index_member = self.treeWidget.currentIndex().row()
        self.refresh_scan_list(member=self.data['members'][index_member])

    @pyqtSlot()
    def on_loadscanButton_clicked(self):
        fname, _filter = QFileDialog.getOpenFileName(self, 'open file',
                                                     '~/Desktop',
                                                     'Scan (*.mhd *.nrrd)')

        # make up some patient information for .mhd file from LUNA16
        faker = Faker()
        patient_name = faker.name()
        birth_date = faker.date()
        patient_sex = faker.profile()['sex']
        scan_date = faker.date()

        # For general DICOM series
        '''
        reader = sitk.ImageSeriesReader()
        reader = sitk.ImageSeriesReader()
        dir = '/Users/apple/Desktop/神農/一些參考/Patient CT EDU (Anonym-TR123)'
        seriesIDs = reader.GetGDCMSeriesIDs(dir)
        dcm_series = reader.GetGDCMSeriesFileNames(dir, seriesIDs[0])
        reader.SetFileNames(dcm_series)
        reader.MetaDataDictionaryArrayUpdateOn()
        # Execute() is needed to GetMetaData
        img = reader.Execute()
        patient_name = reader.GetMetaData(0,'0010|0010').strip()
        birth_date = reader.GetMetaData(0,'0010|0030').strip()
        patient_sex = reader.GetMetaData(0,'0010|0040').strip()
        '''

        exist = False
        for i, m in enumerate(self.data['members']):
            if patient_name == m['patient_name']:
                self.data['members'][i]['scans'].append({
                    'updated': False,
                    'scan_path': fname,
                    'scan_date': scan_date,
                    'nodules': []
                })
                self.data['members'][i]['updated'] = False
                exist = True
        if not exist:
            self.data['members'].append({
                'updated':
                False,
                'patient_name':
                patient_name,
                'date_of_birth':
                birth_date,
                'sex':
                patient_sex,
                'score':
                '?',
                'management':
                '?',
                'scans': [{
                    'updated': False,
                    'scan_path': fname,
                    'scan_date': scan_date,
                    'nodules': []
                }]
            })
        self.refresh_patient_list()

    @pyqtSlot()
    def on_displayButton_clicked(self):
        index_member = self.treeWidget.currentIndex().row()
        nodule_select = None
        if self.noduletreeWidget.selectedItems()[0].parent():
            directory = self.noduletreeWidget.selectedItems()[0].parent().text(
                2)
            nodule_select = self.noduletreeWidget.currentIndex().row()
            index_scan = self.noduletreeWidget.indexFromItem(
                self.noduletreeWidget.selectedItems()[0].parent()).row()
        else:
            directory = self.noduletreeWidget.selectedItems()[0].text(2)
            index_scan = self.noduletreeWidget.indexFromItem(
                self.noduletreeWidget.selectedItems()[0]).row()

        self.display_dialog = CthreeD()
        self.display_dialog.updata_data_signal.connect(
            partial(self.update_data, index_member, index_scan))
        self.display_dialog.show()
        self.display_dialog.w = self.display_dialog.imgLabel_1.width()
        self.display_dialog.h = self.display_dialog.imgLabel_1.height()
        self.display_dialog.load_dicomfile(
            directory=directory,
            nodule_select=nodule_select,
            scan=self.data['members'][index_member]['scans'][index_scan])

    def update_data(self, index_member, index_scan, data_csv):
        self.data['members'][index_member]['scans'][index_scan]['nodules'] = []
        for row in data_csv:
            self.data['members'][index_member]['scans'][index_scan][
                'nodules'].append(row)
        self.refresh_scan_list(member=self.data['members'][index_member])

        self.management(index_member)

    def mousePressEvent(self, event):
        if app.focusWidget():
            self.setFocus()

    # TODO Not complete enough
    def management(self, index_member=None):
        """
        Get highest Lung-RADS score and match the date to show management
        """
        # diameter for solid component is needed for class 4 if nodule type is part-solid
        scores = []
        scans_date = []
        max_solid_component_diameter = 0
        for s in self.data['members'][index_member]['scans']:
            y, m, d = s['scan_date'].split(sep='-')
            scans_date.append(datetime(int(y), int(m), int(d)))
            for n in s['nodules']:
                scores.append(n['score'])
                if n['type'] == '3':
                    if eval(n['diameter']
                            ) * 0.5 > max_solid_component_diameter:
                        max_solid_component_diameter = eval(
                            n['diameter']) * 0.5
        newest = datetime(1000, 1, 1)
        for scan_date in scans_date:
            if scan_date > newest:
                newest = scan_date
        management = ''
        if '?' in scores:
            max_score = '?'
            management = '?'
        else:
            breaker = False
            max_score = '0'
            for s in ['4X', '4B', '4A', '3', '2', '1', '0']:
                if scores.__len__() == 0:
                    print('no nodule')
                    max_score = '1'
                    break

                for score in scores:
                    if score == s:
                        max_score = s
                        breaker = True
                        break
                if breaker:
                    break

            if max_score == '0':
                management = 'Additional lung cancer screening CT images and/or comparison to ' \
                             'prior chest CT examinations is needed'
            elif max_score == '1' or max_score == '2':
                management = f'LDCT @ {newest.date()+relativedelta(years=1)}'
            elif max_score == '3':
                management = f'LDCT @ {newest.date()+relativedelta(months=6)}'
            elif max_score == '4A':
                management = f'LDCT @ {newest.date()+relativedelta(months=3)}'
                if max_solid_component_diameter >= 8:
                    management += ' (PET/CT may be used)'
            elif max_score == '4B' or max_score == '4X':
                management = f'Chest CT w/ or w/o contrast, PET/CT and/or tissue sampling may be used'
                # TODO 這邊是如果有新生大結節才要的
                # management += '1 month LDCT may be recommended to
                # address potentially infectious or inflammatory conditions'

        self.data['members'][index_member]['score'] = max_score
        self.data['members'][index_member]['management'] = management
        self.refresh_patient_list()

    @pyqtSlot()
    def on_detectButton_clicked(self):
        # show status on statusbar
        self.statusBar().showMessage(
            'Model predicting, please wait for a while ...')
        self.statusBar().repaint()
        QApplication.instance().processEvents()

        # TODO Check if selected scan is already detected
        index_member = self.treeWidget.currentIndex().row()
        index_scan = self.noduletreeWidget.currentIndex().row()

        if use_win10:
            csv_data = detect(
                self.data['members'][index_member]['scans'][index_scan]
                ['scan_path'], self.nodulenet_model, self.classification_model,
                self.data['preferences'])
        else:
            csv_data = None

        self.update_data(index_member, index_scan, csv_data)
        self.data['members'][index_member]['scans'][index_scan][
            'updated'] = True
        self.refresh_scan_list(self.data['members'][index_member])
        status = [
            scan['updated']
            for scan in self.data['members'][index_member]['scans']
        ]
        if False not in status:
            self.data['members'][index_member]['updated'] = True
            self.refresh_patient_list()
        self.statusBar().showMessage('Done.', msecs=5000)
        self.management(index_member)

    @pyqtSlot()
    def on_savechangesButton_clicked(self):
        messagebox = QMessageBox.warning(
            self, 'Are you sure you want to save changes?',
            'You cannot undo this action, re-detect scans if necessary.',
            QMessageBox.Ok | QMessageBox.Cancel, QMessageBox.Ok)
        if messagebox == QMessageBox.Ok:
            with open(pkg_name, 'w') as json_file:
                json.dump(self.data, json_file, indent=2)
예제 #8
0
class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setupUi(self)

        self.tableWidget_dropzone.setColumnCount(6)
        self.tableWidget_dropzone.setRowCount(9)
        self.tableWidget_dropzone.setAcceptDrops(True)
        self.tableWidget_dropzone.setColumnWidth(0, 128)
        self.tableWidget_dropzone.setColumnWidth(1, 64)
        self.tableWidget_dropzone.setColumnWidth(2, 128)
        self.tableWidget_dropzone.setColumnWidth(3, 64)
        self.tableWidget_dropzone.setColumnWidth(4, 128)
        self.tableWidget_dropzone.setColumnWidth(5, 64)
        self.tableWidget_dropzone.setHorizontalHeaderLabels([
            'A1 Sample IDs', 'Gender', 'A2 Sample IDs', 'Gender',
            'A3 Sample IDs', 'Gender'
        ])
        self.tableWidget_dropzone.setVerticalHeaderLabels(
            ['', 'R1', 'R2', 'R3', 'R4', 'R5', 'R6', 'R7', 'R8'])
        self.tableWidget_dropzone.setSpan(0, 0, 1, 2)
        self.tableWidget_dropzone.setSpan(0, 2, 1, 2)
        self.tableWidget_dropzone.setSpan(0, 4, 1, 2)

        # populate stuff
        # arrayUpload_settings = QSettings('vll', 'arrayUpload')
        # path_array_data_folder = arrayUpload_settings.value('path_array_data_folder', type=str)
        # dataComboBox1 = DataCombo(path_array_data_folder)
        # dataComboBox2 = DataCombo(path_array_data_folder)
        # dataComboBox3 = DataCombo(path_array_data_folder)
        #
        # self.tableWidget_dropzone.setCellWidget(0, 0, dataComboBox1)
        # self.tableWidget_dropzone.setCellWidget(0, 2, dataComboBox2)
        # self.tableWidget_dropzone.setCellWidget(0, 4, dataComboBox3)

        self.populateExcelComboBox()
        self.populateDataComboBoxes()
        self.populateInvestigators()

        # other settings

        self.dateEdit.setDateTime(QDateTime.currentDateTime())

        # actions

        self.actionPreferences.triggered.connect(self.show_preferences)
        self.load_samples_comboBox.activated.connect(self.loadExcel)

    def repopulate(self):
        self.populateExcelComboBox()
        self.populateDataComboBoxes()
        self.populateInvestigators()

    def populateInvestigators(self):
        arrayUpload_settings = QSettings('vll', 'arrayUpload')
        investigators_list = arrayUpload_settings.value('investigators',
                                                        type=list)

        investigators_list.insert(0, " -- none selected -- ")

        self.comboBox_investigator.clear()
        for i in investigators_list:
            self.comboBox_investigator.addItem(i)

    def populateDataComboBoxes(self):
        arrayUpload_settings = QSettings('vll', 'arrayUpload')
        path_array_data_folder = arrayUpload_settings.value(
            'path_array_data_folder', type=str)
        dataComboBox1 = DataCombo(path_array_data_folder)
        dataComboBox2 = DataCombo(path_array_data_folder)
        dataComboBox3 = DataCombo(path_array_data_folder)

        self.tableWidget_dropzone.setCellWidget(0, 0, dataComboBox1)
        self.tableWidget_dropzone.setCellWidget(0, 2, dataComboBox2)
        self.tableWidget_dropzone.setCellWidget(0, 4, dataComboBox3)

    def populateExcelComboBox(self):
        self.load_samples_comboBox.clear()
        arrayUpload_settings = QSettings('vll', 'arrayUpload')
        path_sample_excel_files_folder = arrayUpload_settings.value(
            'path_sample_excel_files_folder', type=str)
        files = os.listdir(path=path_sample_excel_files_folder)
        files_xls = []
        for f in files:
            if f.endswith(".xls"):
                files_xls.append(f)

        sfiles_xls = natsorted(files_xls)

        sfiles_xls.insert(0, " -- none selected -- ")

        for f in sfiles_xls:
            if f[0] != '$':
                self.load_samples_comboBox.addItem(f)

    def loadExcel(self):
        arrayUpload_settings = QSettings('vll', 'arrayUpload')
        path_sample_excel_files_folder = arrayUpload_settings.value(
            'path_sample_excel_files_folder', type=str)

        self.tableWidget_XLS.clear()

        cexcel = self.load_samples_comboBox.currentText()
        cexcel_path = path_sample_excel_files_folder + "/" + cexcel

        if cexcel != " -- none selected -- ":

            book = xlrd.open_workbook(cexcel_path, 'r')
            sheet = book.sheet_by_index(0)

            self.tableWidget_XLS.setColumnCount(sheet.ncols + 10)
            self.tableWidget_XLS.setRowCount(sheet.nrows + 10)
            self.check_change = False

            for row_index in range(0, sheet.nrows):
                for col_index in range(0, sheet.ncols):
                    content = sheet.cell(row_index, col_index).value
                    item = QTableWidgetItem(content)
                    self.tableWidget_XLS.setItem(row_index, col_index, item)
                    self.tableWidget_XLS.setDragEnabled(True)

            self.check_change = True

    def load_samples(self):

        files = os.listdir("C:/Users/parla/Documents/")
        sfiles = natsorted(files)
        sfiles.insert(0, " -- none selected -- ")

        for f in sfiles:
            # print(f)
            if f.endswith('.xls') or f.endswith(' -- none selected -- '):
                self.load_samples_comboBox.addItem(f)

    def show_preferences(self):
        self.p = Preferences(self)
        self.p.show()
예제 #9
0
class Indicator:

    # ----------------------------------------------------------------------- #
    def __init__(self, player):

        # apparently appindicator will not quit on Ctrl-C by default. fix
        # bellow allows it to do so in Ctrl-C run the default action kernel
        # action which allows indicator to exit
        signal.signal(signal.SIGINT, signal.SIG_DFL)

        # expose the passing player to tht class
        self._player = player

        # remove registration to dbus, disabling MPRIS integration, mainly this
        # is done because current anoise MPRIS integration does not notify the
        # GUI element of play/pause/next/forward changes internally an attempt
        # at dbus manager that listens for anoise mpris notification fails due
        # to double signaling and handling of multiple MPRIS subscribed clients
        # and inability to distinguish which come from anoise
        self._player.sound_menu.remove_from_connection()

        #: DEBUG SETTING, used during development
        #: hide window ui, if it's the GUI class (rather then Indicator class)
        # if self._player.window.__class__.__name__ == 'GUI':
        #     self._player.window.window.hide()

        # build the preferences window
        self._preferences_window = Preferences(self)

        # expose the default gtk settings
        self._gtk_settings = Gtk.Settings.get_default()

        # expose the default icon theme
        self._default_icon_theme = Gtk.IconTheme.get_default()

        # expose "hicolor" theme as fallback theme
        self._fallback_icon_theme = Gtk.IconTheme()
        self._fallback_icon_theme.set_custom_theme('hicolor')

        # expose found appindicator and appindicator-pause icons
        self._appindicator_icon, self._appindicator_icon_pause = \
            self._get_indicator_icons()

        # build the appindicator
        self._appindicator, builder = self._make_appindicator()

        # expose the play/pause menu item to the class
        self._menuitem_play = builder.get_object('play_pause_toggle')
        # expose now playing menu item
        self._menuitem_now_playing = builder.get_object('now_playing')

        # expose now playing image
        self._image_now_playing = builder.get_object('image_now_playing')
        # expose play image
        self._image_play = builder.get_object('image_play')
        # expose pause image
        self._image_pause = builder.get_object('image_pause')

        # disable startup autoplay (ugh, terrible approach)
        # runs before indicator is made visible to show the "paused" icon
        self._disable_startup_autoplay()

        # set the indicator status to active
        self._appindicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)

        # update the noise icon in the ui and the appindicator
        self._update_now_playing()

    # ----------------------------------------------------------------------- #
    def set_timer(self, enable, seconds):
        # method is run by preferences window code, which is why it's public

        # it's strange that this code is run in the UI code.
        # if window ui and appindicator will both install you will end up with
        # two timers, so seems like runing both "ui"s is not a good idea
        # exclusive, unless preferences can be a singleton

        if enable:
            self.timer = threading.Timer(seconds, self._set_future_pause)
            self.timer.start()
        else:
            self.timer.cancel()

    # ----------------------------------------------------------------------- #
    def _disable_startup_autoplay(self):
        """
        Disable auto play on aplication startup. This is done by patching
        the self._player._sound_menu_play with function that pauses the player
        insteady of playing it, and the restores the original function after it
        was ran once. Unfortunately this is the only way to do this at this
        point.
        """

        # set all the gui statuses to "pause"
        self._pause()
        # preserve the original function
        original_func = self._player._sound_menu_play

        # create a patched function which pauses the play when run the FIRST
        # time and then restores the original _sound_menu_play to the player
        # object (sad, should not need to patch)
        def _sound_menu_play(*args, **kwargs):
            # pause
            self._player._sound_menu_pause()
            self._player._sound_menu_play = original_func

        # now patch the play function with our patched function
        self._player._sound_menu_play = _sound_menu_play

    # ----------------------------------------------------------------------- #
    def _make_appindicator(self):
        """
        Return constructed AppIndicator and it's menu.
        Also return the menu builder so we can update few of it's items
        """

        # get full glade file. assumption here is that the ui file in the same
        # folder as this script
        ui_file_path = os.path.join(
            os.path.realpath(os.path.dirname(__file__)), 'appindicator.ui')

        # force showing of images despite whatever the global setting is
        self._gtk_settings.props.gtk_button_images = True

        # build the apindicator menu from the glade file
        builder = Gtk.Builder()
        builder.add_from_file(ui_file_path)

        # create the appindicator
        appindicator = AppIndicator3.Indicator.new(
            APPINDICATOR_ID, self._appindicator_icon,
            AppIndicator3.IndicatorCategory.APPLICATION_STATUS)

        # get the appindicator menu
        menu = builder.get_object('appindicator_menu')

        # setup the signals for the appindicator menu items
        builder.connect_signals(self)

        # get the play/pause menu iterm
        menuitem_play = builder.get_object('play_pause_toggle')

        # setup to trigger play/pause menu action on appindicator middle click
        appindicator.set_secondary_activate_target(menuitem_play)

        # set all menu items visible
        menu.show_all()

        # attach to the menu to the appindicator
        appindicator.set_menu(menu)

        return appindicator, builder

    # ----------------------------------------------------------------------- #
    def _get_indicator_icons(self):

        icons = []

        # for over both default and fallback theme to get icons
        for theme in [self._default_icon_theme, self._fallback_icon_theme]:
            # try to find both regular and pause icons
            for icon_name in [APPINDICATOR_ICON, APPINDICATOR_ICON_PAUSE]:
                # break out of the loop if we failed to find any of the icons
                # and set the icon collection to an empty list
                if theme.has_icon(icon_name) is True:
                    icon_info = theme.lookup_icon(icon_name, Gtk.IconSize.MENU,
                                                  0)
                    # get icon file path
                    icons.append(icon_info.get_filename())
                else:
                    icons = []
                    break

            # if we found both icons break out
            if len(icons) == 2 or all(icons) is True:
                break

        # if we could not find 2 icons fallback to very generic icons
        if len(icons) != 2 or all(icons) is False:
            icons = APPINDICATOR_ICONS_FALLBACK

        return icons

    # ----------------------------------------------------------------------- #
    def _on_toggle_play_pause_activate(self, widget):
        if self._player.is_playing:
            self._player._sound_menu_pause()
            self._pause()
        else:
            self._player._sound_menu_play()
            self._play()

    # ----------------------------------------------------------------------- #
    def _on_next_activate(self, widget):
        # tell the player to play next track
        self._player._set_new_play('next')
        # update noise status
        self._update_now_playing()

    # ----------------------------------------------------------------------- #
    def _on_previous_activate(self, widget):
        # tell the player to play track
        self._player._set_new_play('previous')
        # update noise status
        self._update_now_playing()

    # ----------------------------------------------------------------------- #
    def _on_preferences_window_show_activate(self, widget):
        self._preferences_window.show()

    # ----------------------------------------------------------------------- #
    def _on_about_activate(self, widget):
        # open default web browser to the homepage
        webbrowser.open_new('http://anoise.tuxfamily.org')

    # ----------------------------------------------------------------------- #
    def _on_quit_activate(self, widget):
        # try to cancel the timer catching all (really?) exceptions
        try:
            self.timer.cancel()
        except Exception:
            pass

        # tell gtk main loop to quit
        Gtk.main_quit()

    # ----------------------------------------------------------------------- #
    def _update_now_playing(self):
        # try to get the noise icon file, otherwise fallback to the default
        # note: it does not throw a specific error we can test for so
        #       we are testing for Exception
        try:
            # get the icon file name for the existing noise
            icon_file = self._player.noise.get_icon().replace('file://', '')
            fallback_icon_name = None
        except Exception:
            # retrieve the default application icon from the icon as a pixbuf
            icon_file = APPINDICATOR_ICON
            fallback_icon_name = PLAYING_NOW_FALLBACK_ICON

        # get the now playing noise
        now_playing = self._player.noise.get_name()
        # form "Not Playing: <noise>" string for the indicator
        new_label = "Now Playing: %s" % now_playing
        # update the indicator now playing label to the noise name
        self._menuitem_now_playing.set_label(new_label)

        # update the now playing menu icon
        #
        # if fallback icon name is not set then we set the found noise icon
        # otherwise we set the set the image to the fallback icons
        if fallback_icon_name is None:
            self._image_now_playing.set_from_file(icon_file)
        else:
            self._image_now_playing.set_from_icon_name(fallback_icon_name,
                                                       Gtk.IconSize.MENU)

        # update the now playing menu item with the now playing image
        self._menuitem_now_playing.set_image(self._image_now_playing)

    # ----------------------------------------------------------------------- #
    def _play(self):
        # tell player to play
        self._menuitem_play.set_label("P_ause")
        self._menuitem_play.set_image(self._image_pause)
        self._appindicator.set_icon(self._appindicator_icon)
        self._update_now_playing()

    # ----------------------------------------------------------------------- #
    def _pause(self):
        # pause the player
        self._menuitem_play.set_label("_Play")
        self._menuitem_play.set_image(self._image_play)
        self._appindicator.set_icon(self._appindicator_icon_pause)
        self._update_now_playing()

    # ----------------------------------------------------------------------- #
    def _set_future_pause(self):
        self._preferences_window.set_show_timer()
        self._player._sound_menu_pause()
        self._pause()
예제 #10
0
class Window(QWidget):
    """The main front end for the application."""
    def __init__(self, config):
        # Initialize the object as a QWidget and
        # set its title and minimum width

        QWidget.__init__(self)

        self.config = config
        self.peerList = config.peerList
        self.setWindowTitle('BlastShare')
        self.setMinimumSize(320, 480)
        self.setMaximumWidth(320)
        self.prefw = None
        
        # connects the signals!
        self.connect(self.peerList,
                     SIGNAL("initTransfer"), self.sendFileToPeer)

        ''' Will add feature in future version '''
        '''
        shareFilesAction = QAction(QIcon('exit.png'), '&Share File(s)', self)
        shareFilesAction.setShortcut('Ctrl+O')
        shareFilesAction.setStatusTip('Share File(s)')
        shareFilesAction.triggered.connect(quitApp)
        '''
        
        preferencesAction = QAction(QIcon('exit.png'), '&Preferences', self)
        preferencesAction.setShortcut('Ctrl+P')
        preferencesAction.setStatusTip('Preferences')
        preferencesAction.triggered.connect(self.editPreferences)

        exitAction = QAction(QIcon('exit.png'), '&Exit', self)
        exitAction.setShortcut('Ctrl+Q')
        exitAction.setStatusTip('Exit application')
        exitAction.triggered.connect(quitApp)

        menubar = QMenuBar()
        fileMenu = menubar.addMenu('&File')
        
        ''' Will enable in future versions '''
        # fileMenu.addAction(shareFilesAction)
        
        fileMenu.addAction(preferencesAction)
        fileMenu.addAction(exitAction)

        layout = QVBoxLayout()
        layout.setContentsMargins(QMargins(0, 0, 0, 0))
        self.setLayout(layout)
        
        statusBar = QStatusBar()
        statusBar.showMessage('Ready')
        
        layout.addWidget(menubar)
        layout.addWidget(self.peerList)
        layout.addWidget(statusBar)
        
    def sendFileToPeer(self, fileName, peerID, peerAddress, peerPort):
        log.msg("File dropped {0}".format(fileName))
        session = Session(str(fileName), self.config, peerAddress, peerPort)
        self.config.sessions[str(session.id)] = session
        session.startTransfer()
            
    def questionMessage(self, fileName, peerName):    
        reply = QMessageBox.question(self, "Accept file download?",
                "Do you want to accept the {0} from {1}?".format(fileName,
                                                                 peerName),
                QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel)
        if reply == QMessageBox.Yes:
            return "yes"
        elif reply == QMessageBox.No:
            return "no"
        else:
            return "cancel"
        
    def editPreferences(self):
        """ Launches the edit preferences dialog for this window. """
        self.prefw = Preferences(self)
        self.prefw.show()
           
    def run(self):
        self.show()
        QT_APP.exec_()