예제 #1
0
    def create_actions(self):

        self.change_color_action = QtGui.QAction("Change &color", self)
        self.change_color_action.triggered.connect(self.change_color_callback)

        self.add_group_action = QtGui.QAction("&Add group", self)
        self.add_group_action.triggered.connect(self.add_group_callback)

        self.rename_channel_group_action = QtGui.QAction("Re&name group", self)
        self.rename_channel_group_action.setShortcut("F2")
        self.rename_channel_group_action.triggered.connect(
            self.rename_channel_group_callback)

        self.rename_channel_action = QtGui.QAction("Rename c&hannel", self)
        self.rename_channel_action.setShortcut("F3")
        self.rename_channel_action.triggered.connect(
            self.rename_channel_callback)

        self.remove_group_action = QtGui.QAction("&Remove group", self)
        self.remove_group_action.triggered.connect(self.remove_group_callback)

        # Add actions to the widget.
        self.addAction(self.change_color_action)
        self.addAction(self.add_group_action)
        self.addAction(self.rename_channel_group_action)
        self.addAction(self.rename_channel_action)
        self.addAction(self.remove_group_action)
    def create_layout(self):

        self.setStyleSheet(DOCKSTYLESHEET)

        # Create the title layout.
        self.setContentsMargins(0, 0, 0, 0)
        box = QtGui.QHBoxLayout()
        box.setContentsMargins(0, 2, 0, 2)
        box.setSpacing(0)

        # Add the title.
        self.title_widget = QtGui.QLabel(self.name, self)
        box.addSpacing(5)
        box.addWidget(self.title_widget)

        # Add spacing.
        box.addStretch(1000)

        # Add the dock-related buttons.
        if self.is_floatable():
            box.addWidget(self.dockable_button)
            box.addWidget(self.maximize_button)
            box.addWidget(self.dock_button)

        # Add the close button.
        if self.is_closable():
            box.addWidget(self.close_button)

        self.setLayout(box)
예제 #3
0
 def force_key_release(self):
     """HACK: force release of Ctrl, Shift and Alt when focus out."""
     self.keyReleaseEvent(QtGui.QKeyEvent(QtCore.QEvent.KeyRelease,
         QtCore.Qt.Key_Control, QtCore.Qt.NoModifier))
     self.keyReleaseEvent(QtGui.QKeyEvent(QtCore.QEvent.KeyRelease,
         QtCore.Qt.Key_Shift, QtCore.Qt.NoModifier))
     self.keyReleaseEvent(QtGui.QKeyEvent(QtCore.QEvent.KeyRelease,
         QtCore.Qt.Key_Alt, QtCore.Qt.NoModifier))
예제 #4
0
 def create_color_dialog(self):
     self.color_dialog = QtGui.QColorDialog(self)
     self.color_dialog.setOptions(QtGui.QColorDialog.DontUseNativeDialog)
     for i in xrange(48):
         if i < len(COLORMAP):
             rgb = COLORMAP[i] * 255
         else:
             rgb = (255, 255, 255)
             # rgb = (1., 1., 1.)
         k = 6 * (np.mod(i, 8)) + i // 8
         self.color_dialog.setStandardColor(k, QtGui.qRgb(*rgb))
    def __init__(self, parent=None, getfocus=None):
        super(LogView, self).__init__(parent)

        # Create the text edit widget.
        self.textedit = QtGui.QTextEdit()
        self.textedit.setReadOnly(True)

        # Add the text edit widget to the layout.
        box = QtGui.QVBoxLayout()
        box.addWidget(self.textedit)
        box.setContentsMargins(0, 0, 0, 0)
        box.setSpacing(0)
        self.setLayout(box)
예제 #6
0
    def create_layout(self):
        self.projection_view = ProjectionView(self, getfocus=False)
        self.feature_view = FeatureView(self, getfocus=False)
        self.set_data()

        # Connect the FeatureView signal to the top-level widget signals.
        self.feature_view.spikesHighlighted.connect(self.spikesHighlighted)
        self.feature_view.spikesSelected.connect(self.spikesSelected)

        # Connect the bottom-level projectionChanged signals to the top-level
        # widget signals.
        self.feature_view.projectionChanged.connect(self.projectionChanged)
        self.projection_view.projectionChanged.connect(self.projectionChanged)

        # Interconnect the projectionChanged between the two bottom-level widgets.
        self.projection_view.projectionChanged.connect(
            self.projection_changed_projection_callback)
        self.feature_view.projectionChanged.connect(
            self.projection_changed_feature_callback)

        box = QtGui.QVBoxLayout()
        # HACK: pyside does not have this function
        if hasattr(box, 'setMargin'):
            box.setMargin(0)

        box.addWidget(self.projection_view)
        box.addWidget(self.feature_view)

        self.setLayout(box)
예제 #7
0
    def __init__(self, parent=None, getfocus=None):
        super(IPythonView, self).__init__(parent)
        
        # Create an in-process kernel
        self.kernel_manager = QtInProcessKernelManager()
        self.kernel_manager.start_kernel()
        self.kernel = self.kernel_manager.kernel
        self.kernel.gui = 'qt4'
        self.shell = self.kernel.shell

        self.kernel_client = self.kernel_manager.client()
        self.kernel_client.start_channels()

        self.control = RichIPythonWidget()
        self.control.set_default_style(colors='linux')
        self.control.kernel_manager = self.kernel_manager
        self.control.kernel_client = self.kernel_client
        self.control.exit_requested.connect(self.stop)
        
        # Enable Pylab mode.
        self.shell.enable_pylab()
        self.shell.automagic = True
        
        # Add some variables in the namespace.
        self.push(galry=galry)
        
        box = QtGui.QVBoxLayout()
        box.addWidget(self.control)
        
        box.setContentsMargins(0, 0, 0, 0)
        box.setSpacing(0)

        
        self.setLayout(box)
예제 #8
0
 def shortcuts_callback(self, checked=None):
     e = QtGui.QKeyEvent(
         QtCore.QEvent.KeyPress,
         QtCore.Qt.Key_H,
         QtCore.Qt.NoModifier,
     )
     self.keyPressEvent(e)
예제 #9
0
    def set_data(self,
                 fetdim=None,
                 nchannels=None,
                 nextrafet=None,
                 channels=None):
        if fetdim is None:
            fetdim = 3
        if nchannels is None:
            nchannels = 1
        if nextrafet is None:
            nextrafet = 0
        if channels is None:
            channels = range(nchannels)

        # No need to update the widget if the data has not changed.
        if not self._has_changed(fetdim, nchannels, nextrafet):
            return

        self.fetdim = fetdim
        self.nchannels = nchannels
        self.channels = channels
        self.nextrafet = nextrafet

        # Remove the existing layout.
        if self.layout():
            QtGui.QWidget().setLayout(self.layout())

        self.box = self.create_widget()
        self.setLayout(self.box)
예제 #10
0
 def create_save_progress_dialog(self):
     self.save_progress = QtGui.QProgressDialog("Saving...", "Cancel", 0, 0,
                                                self, QtCore.Qt.Tool)
     self.save_progress.setWindowModality(QtCore.Qt.WindowModal)
     self.save_progress.setValue(0)
     self.save_progress.setWindowTitle('Saving')
     self.save_progress.setCancelButton(None)
     self.save_progress.setMinimumDuration(0)
예제 #11
0
 def create_open_progress_dialog(self):
     self.open_progress = QtGui.QProgressDialog("Converting to Kwik...",
         "Cancel", 0, 0, self, QtCore.Qt.Tool)
     self.open_progress.setWindowModality(QtCore.Qt.WindowModal)
     self.open_progress.setValue(0)
     self.open_progress.setWindowTitle('Loading')
     self.open_progress.setCancelButton(None)
     self.open_progress.setMinimumDuration(0)
예제 #12
0
def get_icon(name):
    """Get an icon from the icons folder in the current package,
    or directly from galry."""
    path = os.path.dirname(os.path.realpath(__file__))
    path = os.path.join(path, "../icons/%s.png" % name)
    if not os.path.exists(path):
        return galry.get_icon(name)
    else:
        return QtGui.QIcon(path)
예제 #13
0
파일: dock.py 프로젝트: goller/klustaviewa
 def add_button(self, name, text, callback=None, shortcut=None,
         checkable=False, icon=None):
     # Creation action.
     action = QtGui.QAction(text, self)
     if callback is None:
         callback = getattr(self, name + '_callback', None)
     if callback:
         action.triggered.connect(callback)
     if shortcut:
         action.setShortcut(shortcut)
     if icon:
         action.setIcon(get_icon(icon))
     action.setCheckable(checkable)
     # Create button
     button = QtGui.QToolButton(self)
     button.setContentsMargins(*((5,)*4))
     button.setDefaultAction(action)
     return button
예제 #14
0
    def create_context_menu(self):
        self.create_color_dialog()

        self.context_menu = QtGui.QMenu(self)
        self.context_menu.addAction(self.change_color_action)
        self.context_menu.addSeparator()
        self.context_menu.addAction(self.add_group_action)
        self.context_menu.addAction(self.rename_channel_group_action)
        self.context_menu.addAction(self.rename_channel_action)
        self.context_menu.addAction(self.remove_group_action)
예제 #15
0
    def create_feature_widget(self, coord=0):
        # coord => (channel, feature)
        self.projection = [(0, 0), (0, 1)]

        hbox = QtGui.QHBoxLayout()
        hbox.setSpacing(0)
        # HACK: pyside does not have this function
        if hasattr(hbox, 'setMargin'):
            hbox.setMargin(0)

        # channel selection
        comboBox = QtGui.QComboBox(self)
        comboBox.setEditable(True)
        comboBox.setMaximumWidth(100)
        comboBox.setInsertPolicy(QtGui.QComboBox.NoInsert)
        comboBox.addItems(["%d" % i for i in self.channels])
        comboBox.addItems(["Extra %d" % i for i in xrange(self.nextrafet)])
        comboBox.editTextChanged.connect(partial(self.select_channel, coord))
        # comboBox.setFocusPolicy(QtCore.Qt.ClickFocus)
        self.channel_box[coord] = comboBox
        hbox.addWidget(comboBox)

        # create 3 buttons for selecting the feature
        widths = [30] * self.fetdim
        labels = ['PC%d' % i for i in xrange(1, self.fetdim + 1)]

        hbox.addSpacing(10)

        # ensure exclusivity of the group of buttons
        pushButtonGroup = QtGui.QButtonGroup(self)
        for i in xrange(len(labels)):
            # selecting feature i
            pushButton = QtGui.QPushButton(labels[i], self)
            pushButton.setCheckable(True)
            if coord == i:
                pushButton.setChecked(True)
            pushButton.setMaximumSize(QtCore.QSize(widths[i], 20))
            pushButton.clicked.connect(partial(self.select_feature, coord, i))
            pushButtonGroup.addButton(pushButton, i)
            self.feature_buttons[coord][i] = pushButton
            hbox.addWidget(pushButton)

        return hbox
예제 #16
0
 def create_widget(self):
     
     box = QtGui.QHBoxLayout()
     if hasattr(box, 'setMargin'):
         box.setContentsMargins(QtCore.QMargins(10, 2, 10, 2))
     
     # box.addSpacing(10)
     
     # coord => channel combo box
     self.channel_box = [None, None]
     # coord => (butA, butB, butC)
     self.feature_buttons = [[None] * self.fetdim, [None] * self.fetdim]
     
     # add feature widget
     self.feature_widget1 = self.create_feature_widget(0)
     box.addLayout(self.feature_widget1)
     
     box.addSpacing(10)
     
     # Switch button.
     # button = QtGui.QPushButton('Flip', self)
     button = QtGui.QPushButton(self)
     button.setIcon(get_icon('flip'))
     button.setMaximumWidth(40)
     button.clicked.connect(self.flip_projections_callback)
     box.addWidget(button)
     
     box.addSpacing(10)
     
     # add feature widget
     self.feature_widget2 = self.create_feature_widget(1)
     box.addLayout(self.feature_widget2)
     
     # box.addSpacing(10)
     
     self.setTabOrder(self.channel_box[0], self.channel_box[1])
     
     # self.setMaximumWidth(300)
     # self.setMaximumHeight(80)
     
     
     return box
예제 #17
0
 def create_color_dialog(self):
     self.color_dialog = QtGui.QColorDialog(self)
     self.color_dialog.setOptions(QtGui.QColorDialog.DontUseNativeDialog)
     for i in xrange(48):
         if i < len(COLORMAP):
             rgb = COLORMAP[i] * 255
         else:
             rgb = (255, 255, 255)
             # rgb = (1., 1., 1.)
         k = 6 * (np.mod(i, 8)) + i // 8
         self.color_dialog.setStandardColor(k, QtGui.qRgb(*rgb))
예제 #18
0
    def create_context_menu(self):
        self.create_color_dialog()

        self.context_menu = QtGui.QMenu(self)
        self.context_menu.addAction(self.change_color_action)
        self.context_menu.addSeparator()
        self.context_menu.addAction(self.move_to_noise_action)
        self.context_menu.addAction(self.move_to_mua_action)
        self.context_menu.addAction(self.move_to_good_action)
        self.context_menu.addSeparator()
        self.context_menu.addAction(self.add_group_action)
        self.context_menu.addAction(self.rename_group_action)
        self.context_menu.addAction(self.remove_group_action)
예제 #19
0
 def add_action(self, name, text, callback=None, shortcut=None,
         checkable=False, checked=False, icon=None):
     action = QtGui.QAction(text, self)
     if callback is None:
         callback = getattr(self, name + '_callback', None)
     if callback:
         action.triggered.connect(callback)
     if shortcut:
         action.setShortcut(shortcut)
     if icon:
         action.setIcon(get_icon(icon))
     action.setCheckable(checkable)
     action.setChecked(checked)
     setattr(self, name + '_action', action)
예제 #20
0
    def data(self, index, role):
        item = index.internalPointer()

        col = index.column()
        # group item
        if type(item) == GroupItem:
            if col == 0:
                if role == QtCore.Qt.DisplayRole:
                    return str(item.name())
            # color
            elif col == self.columnCount() - 1:
                if role == QtCore.Qt.BackgroundRole:
                    if item.color() >= 0:
                        color = np.array(COLORMAP[item.color()]) * 255
                        return QtGui.QColor(*color)
                elif role == QtCore.Qt.DisplayRole:
                    return ""

        # channel item
        if type(item) == ChannelItem:
            # name
            if col == 0:
                if role == QtCore.Qt.DisplayRole:
                    return str(item.name())
                elif role == QtCore.Qt.BackgroundRole:
                    if item.bgcolor is None:
                        return
                    elif item.bgcolor == 'candidate':
                        color = np.array(COLORMAP[item.color()]) * 255
                        return QtGui.QColor(color[0], color[1], color[2], 90)
                    elif item.bgcolor == 'target':
                        # return QtGui.QColor(177, 177, 177, 255)
                        color = np.array(COLORMAP[item.color()]) * 255
                        return QtGui.QColor(color[0], color[1], color[2], 255)
                elif role == QtCore.Qt.ForegroundRole:
                    if item.bgcolor is None:
                        return QtGui.QColor(177, 177, 177, 255)
                    elif item.bgcolor == 'target':
                        return QtGui.QColor(0, 0, 0, 255)
            # color
            elif col == self.columnCount() - 1:
                if role == QtCore.Qt.BackgroundRole:
                    color = np.array(COLORMAP[item.color()]) * 255
                    return QtGui.QColor(*color)

        # default
        if role == QtCore.Qt.DisplayRole or role == QtCore.Qt.EditRole:
            return item.data(col)

        if role == QtCore.Qt.ForegroundRole:
            return QtGui.QColor(177, 177, 177, 255)
예제 #21
0
 def select(self, channels, groups=None, wizard=False):
     """Select multiple channels from their indices."""
     self.wizard = wizard
     if channels is None:
         channels = []
     if groups is None:
         groups = []
     if isinstance(channels, (int, long, np.integer)):
         channels = [channels]
     if isinstance(groups, (int, long, np.integer)):
         groups = [groups]
     if len(channels) == len(groups) == 0:
         return
     # Convert to lists.
     channels = list(channels)
     groups = list(groups)
     selection_model = self.selectionModel()
     selection = QtGui.QItemSelection()
     # Select groups.
     for groupidx in groups:
         group = self.model.get_group(groupidx)
         if group is not None:
             selection.select(group.index, group.index)
     # Select channels.
     for channelidx in channels:
         channel = self.model.get_channel(channelidx)
         if channel is not None:
             selection.select(channel.index, channel.index)
     # Process selection.
     selection_model.select(selection, 
             selection_model.Clear |
             selection_model.Current |
             selection_model.Select | 
             selection_model.Rows 
             )
     if len(channels) > 0:
         channel = self.model.get_channel(channels[-1])
         if channel is not None:
             # Set current index in the selection.
             selection_model.setCurrentIndex(
                 channel.index,
                 QtGui.QItemSelectionModel.NoUpdate)
             # Scroll to that channel.
             self.scrollTo(channel.index)
예제 #22
0
 def change_color_callback(self, checked=None):
     item = self.current_item
     initial_color = item.color()
     if initial_color >= 0:
         initial_color = 255 * COLORMAP[initial_color]
         initial_color = QtGui.QColor(*initial_color)
         color = QtGui.QColorDialog.getColor(initial_color)
     else:
         color = QtGui.QColorDialog.getColor()
     # return if the user canceled
     if not color.isValid():
         return
     # get the RGB values of the chosen color
     rgb = np.array(color.getRgbF()[:3]).reshape((1, -1))
     # take the closest color in the palette
     color = np.argmin(np.abs(COLORMAP[1:, :] - rgb).sum(axis=1)) + 1
     # Change the color and emit the signal.
     if isinstance(item, ChannelItem):
         self.change_channel_color(item.channelidx(), color)
     elif isinstance(item, GroupItem):
         self.change_group_color(item.groupidx(), color)
예제 #23
0
    def create_actions(self):

        self.change_color_action = QtGui.QAction("Change &color", self)
        self.change_color_action.triggered.connect(self.change_color_callback)

        self.add_group_action = QtGui.QAction("&Add group", self)
        self.add_group_action.triggered.connect(self.add_group_callback)

        self.rename_group_action = QtGui.QAction("Re&name group", self)
        self.rename_group_action.setShortcut("F2")
        self.rename_group_action.triggered.connect(self.rename_group_callback)

        self.remove_group_action = QtGui.QAction("&Remove group", self)
        self.remove_group_action.triggered.connect(self.remove_group_callback)

        self.move_to_mua_action = QtGui.QAction("Move to &MUA", self)
        self.move_to_mua_action.setShortcut("Delete")
        self.move_to_mua_action.setIcon(get_icon('multiunit'))
        self.move_to_mua_action.triggered.connect(self.move_to_mua_callback)

        self.move_to_noise_action = QtGui.QAction("Move to &noise", self)
        self.move_to_noise_action.setShortcut('Shift+Delete')
        self.move_to_noise_action.setIcon(get_icon('noise'))
        self.move_to_noise_action.triggered.connect(
            self.move_to_noise_callback)

        self.move_to_good_action = QtGui.QAction("Move to &good", self)
        # self.move_to_good_action.setIcon(get_icon('noise'))
        self.move_to_good_action.triggered.connect(self.move_to_good_callback)

        # Add actions to the widget.
        self.addAction(self.change_color_action)
        self.addAction(self.add_group_action)
        self.addAction(self.rename_group_action)
        self.addAction(self.remove_group_action)
        self.addAction(self.move_to_noise_action)
        self.addAction(self.move_to_mua_action)
        self.addAction(self.move_to_good_action)
예제 #24
0
    def __init__(self, parent=None, dolog=True, filename=None):
        super(KwikSkope, self).__init__(parent)

        # HACK: display the icon in Windows' taskbar.
        if os.name == 'nt':
            try:
                import ctypes
                myappid = 'klustateam.kwikskope'
                ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(
                    myappid)
            except:
                pass

        self.dolog = dolog
        if self.dolog:
            create_file_logger()

        log.debug("Using {0:s}.".format(QT_BINDING))

        # Main window options.
        self.move(50, 50)
        self.setWindowTitle('KwikSkope')

        # Focus options.
        self.setFocusPolicy(QtCore.Qt.WheelFocus)
        self.setMouseTracking(True)

        # Dock widgets options.
        self.setDockNestingEnabled(True)
        self.setAnimated(False)
        self.setWindowIcon(get_icon('logo'))

        # Initialize some variables.
        # self.statscache = None
        # self.loader = KlustersLoader()
        self.loader = HDF5Loader()
        self.loader.progressReported.connect(self.open_progress_reported)
        self.loader.saveProgressReported.connect(self.save_progress_reported)
        self.wizard = Wizard()

        self.controller = None
        self.spikes_highlighted = []
        self.spikes_selected = []
        self._wizard = False
        self.is_file_open = False
        self.need_save = False
        self.busy_cursor = QtGui.QCursor(QtCore.Qt.BusyCursor)
        self.normal_cursor = QtGui.QCursor(QtCore.Qt.ArrowCursor)
        self.is_busy = False
        self.override_color = False
        self.computing_correlograms = False
        self.computing_matrix = False

        # Create the main window.
        self.create_views()
        self.create_file_actions()
        self.create_edit_actions()
        self.create_view_actions()
        self.create_help_actions()
        self.create_menu()
        self.create_toolbar()
        self.create_open_progress_dialog()
        self.create_save_progress_dialog()
        self.create_threads()

        # Update action enabled/disabled property.
        self.update_action_enabled()

        # Show the main window.
        self.set_styles()
        self.restore_geometry()

        # Automatically load a file upon startup if requested.
        if filename:
            filename = os.path.realpath(filename)
            self.open_task.open(self.loader, filename)

        self.show()
예제 #25
0
    def data(self, index, role):
        item = index.internalPointer()

        col = index.column()
        # group item
        if type(item) == GroupItem:
            if col == 0:
                if role == QtCore.Qt.DisplayRole:
                    return str(item.name())
            # quality
            elif col == 1:
                if role == QtCore.Qt.TextAlignmentRole:
                    return QtCore.Qt.AlignRight
                if role == QtCore.Qt.DisplayRole:
                    return  #"%." % item.quality()
            # spkcount
            elif col == 2:
                if role == QtCore.Qt.TextAlignmentRole:
                    return QtCore.Qt.AlignRight
                if role == QtCore.Qt.DisplayRole:
                    return str(item.spkcount())
            # color
            elif col == self.columnCount() - 1:
                if role == QtCore.Qt.BackgroundRole:
                    if item.color() >= 0:
                        color = np.array(COLORMAP[item.color()]) * 255
                        return QtGui.QColor(*color)
                elif role == QtCore.Qt.DisplayRole:
                    return ""

        # cluster item
        if type(item) == ClusterItem:
            # clusteridx
            if col == 0:
                if role == QtCore.Qt.DisplayRole:
                    return str(item.clusteridx())
                elif role == QtCore.Qt.BackgroundRole:
                    if item.bgcolor is None:
                        return
                    elif item.bgcolor == 'candidate':
                        color = np.array(COLORMAP[item.color()]) * 255
                        return QtGui.QColor(color[0], color[1], color[2], 90)
                    elif item.bgcolor == 'target':
                        # return QtGui.QColor(177, 177, 177, 255)
                        color = np.array(COLORMAP[item.color()]) * 255
                        return QtGui.QColor(color[0], color[1], color[2], 255)
                elif role == QtCore.Qt.ForegroundRole:
                    if item.bgcolor is None:
                        return QtGui.QColor(177, 177, 177, 255)
                    elif item.bgcolor == 'target':
                        return QtGui.QColor(0, 0, 0, 255)
            # quality
            elif col == 1:
                if role == QtCore.Qt.TextAlignmentRole:
                    return QtCore.Qt.AlignRight
                elif role == QtCore.Qt.DisplayRole:
                    return "%.3f" % item.quality()
                elif role == QtCore.Qt.BackgroundRole:
                    if item.bgcolor is None:
                        return
                    elif item.bgcolor == 'candidate':
                        color = np.array(COLORMAP[item.color()]) * 255
                        return QtGui.QColor(color[0], color[1], color[2], 90)
                    elif item.bgcolor == 'target':
                        color = np.array(COLORMAP[item.color()]) * 255
                        return QtGui.QColor(color[0], color[1], color[2], 255)
                        # return QtGui.QColor(177, 177, 177, 255)
                elif role == QtCore.Qt.ForegroundRole:
                    if item.bgcolor is None:
                        return QtGui.QColor(177, 177, 177, 255)
                    elif item.bgcolor == 'target':
                        return QtGui.QColor(0, 0, 0, 255)
            # spkcount
            elif col == 2:
                if role == QtCore.Qt.TextAlignmentRole:
                    return QtCore.Qt.AlignRight
                if role == QtCore.Qt.DisplayRole:
                    return "%d" % item.spkcount()
                elif role == QtCore.Qt.BackgroundRole:
                    if item.bgcolor is None:
                        return
                    elif item.bgcolor == 'candidate':
                        color = np.array(COLORMAP[item.color()]) * 255
                        return QtGui.QColor(color[0], color[1], color[2], 90)
                    elif item.bgcolor == 'target':
                        # return QtGui.QColor(177, 177, 177, 255)
                        color = np.array(COLORMAP[item.color()]) * 255
                        return QtGui.QColor(color[0], color[1], color[2], 255)
                elif role == QtCore.Qt.ForegroundRole:
                    if item.bgcolor is None:
                        return QtGui.QColor(177, 177, 177, 255)
                    elif item.bgcolor == 'target':
                        return QtGui.QColor(0, 0, 0, 255)

            # color
            elif col == self.columnCount() - 1:
                if role == QtCore.Qt.BackgroundRole:
                    color = np.array(COLORMAP[item.color()]) * 255
                    return QtGui.QColor(*color)

        # default
        if role == QtCore.Qt.DisplayRole or role == QtCore.Qt.EditRole:
            return item.data(col)

        if role == QtCore.Qt.ForegroundRole:
            return QtGui.QColor(177, 177, 177, 255)