Module audian.markerdata

Classes

class ColorIconEngine (color)
Expand source code
class ColorIconEngine(QIconEngine):

    def __init__(self, color):
        super().__init__()
        self.color = colors[color]


    def paint(self, painter, rect, mode=QIcon.Normal, state=QIcon.Off):
        painter.setBrush(QColor('black'))
        painter.setPen(Qt.NoPen)
        painter.drawRect(rect)
        painter.setBrush(QColor(self.color))
        painter.setPen(Qt.NoPen)
        d = rect.width()//5
        painter.drawEllipse(rect.adjusted(d, d, -d, -d))

QIconEngine() QIconEngine(other: QIconEngine)

Ancestors

  • PyQt5.QtGui.QIconEngine
  • sip.wrapper
  • sip.simplewrapper

Methods

def paint(self, painter, rect, mode=0, state=1)
Expand source code
def paint(self, painter, rect, mode=QIcon.Normal, state=QIcon.Off):
    painter.setBrush(QColor('black'))
    painter.setPen(Qt.NoPen)
    painter.drawRect(rect)
    painter.setBrush(QColor(self.color))
    painter.setPen(Qt.NoPen)
    d = rect.width()//5
    painter.drawEllipse(rect.adjusted(d, d, -d, -d))

paint(self, painter: Optional[QPainter], rect: QRect, mode: QIcon.Mode, state: QIcon.State)

class ColorDelegate (parent=None)
Expand source code
class ColorDelegate(QStyledItemDelegate):

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


    def createEditor(self, parent, option, index):
        editor = QComboBox(parent)
        for c in colors:
            editor.addItem(index.model().icons[c], c)
        editor.setEditable(False)
        return editor


    def setEditorData(self, editor, index):
        value = index.model().data(index, Qt.EditRole)
        editor.setCurrentText(value)


    def setModelData(self, editor, model, index):
        value = editor.currentText()
        model.setData(index, value, Qt.EditRole)


    def updateEditorGeometry(self, editor, option, index):
        editor.setGeometry(option.rect)

QStyledItemDelegate(parent: Optional[QObject] = None)

Ancestors

  • PyQt5.QtWidgets.QStyledItemDelegate
  • PyQt5.QtWidgets.QAbstractItemDelegate
  • PyQt5.QtCore.QObject
  • sip.wrapper
  • sip.simplewrapper

Methods

def createEditor(self, parent, option, index)
Expand source code
def createEditor(self, parent, option, index):
    editor = QComboBox(parent)
    for c in colors:
        editor.addItem(index.model().icons[c], c)
    editor.setEditable(False)
    return editor

createEditor(self, parent: Optional[QWidget], option: QStyleOptionViewItem, index: QModelIndex) -> Optional[QWidget]

def setEditorData(self, editor, index)
Expand source code
def setEditorData(self, editor, index):
    value = index.model().data(index, Qt.EditRole)
    editor.setCurrentText(value)

setEditorData(self, editor: Optional[QWidget], index: QModelIndex)

def setModelData(self, editor, model, index)
Expand source code
def setModelData(self, editor, model, index):
    value = editor.currentText()
    model.setData(index, value, Qt.EditRole)

setModelData(self, editor: Optional[QWidget], model: Optional[QAbstractItemModel], index: QModelIndex)

def updateEditorGeometry(self, editor, option, index)
Expand source code
def updateEditorGeometry(self, editor, option, index):
    editor.setGeometry(option.rect)

updateEditorGeometry(self, editor: Optional[QWidget], option: QStyleOptionViewItem, index: QModelIndex)

class MarkerLabel (label, key_shortcut, color, action=None)
Expand source code
class MarkerLabel:

    def __init__(self, label, key_shortcut, color, action=None):
        self.label = label
        self.key_shortcut = key_shortcut
        self.color = color
        self.action = action


    def copy(self):
        ml = MarkerLabel(self.label, self.key_shortcut, self.color, self.action)
        return ml

Methods

def copy(self)
Expand source code
def copy(self):
    ml = MarkerLabel(self.label, self.key_shortcut, self.color, self.action)
    return ml
class MarkerLabelsModel (labels, acts, parent=None)
Expand source code
class MarkerLabelsModel(QAbstractTableModel):
    
    def __init__(self, labels, acts, parent=None):
        QAbstractTableModel.__init__(self, parent)
        self.orig_labels = labels
        self.labels = [x.copy() for x in labels]
        self.header = ['label', 'key', 'color']
        self.dialog = None
        self.view = None
        self.key_delegate = None
        self.acts = acts
        self.icons = {}
        for c in colors:
            self.icons[c] = QIcon(ColorIconEngine(c))

        
    def rowCount(self, parent=None):
        return len(self.labels)

    
    def columnCount(self, parent=None):
        return 3


    def headerData(self, index, orientation, role=Qt.DisplayRole):
        if orientation == Qt.Horizontal and role == Qt.DisplayRole:
            return self.header[index]
        if orientation == Qt.Vertical and role == Qt.DisplayRole:
            return f'{index}'
        return QVariant()

    
    def data(self, index, role=Qt.DisplayRole):
        if not index.isValid():
            return QVariant()
        
        # data:
        if role == Qt.DisplayRole or role == Qt.EditRole:
            label = self.labels[index.row()]
            if index.column() == 0:
                return label.label
            elif index.column() == 1:
                return label.key_shortcut
            elif index.column() == 2:
                return label.color
            else:
                return QVariant()

        # icons:
        if role == Qt.DecorationRole:
            label = self.labels[index.row()]
            if index.column() == 2:
                return self.icons[label.color]
                
        # alignment:
        if role == Qt.TextAlignmentRole:
            return Qt.AlignLeft | Qt.AlignVCenter

        return QVariant()

    
    def flags(self, index):
        if not index.isValid():
            return Qt.NoItemFlag
        flags = Qt.ItemIsSelectable | Qt.ItemIsDragEnabled | Qt.ItemIsEnabled | Qt.ItemIsEditable
        return flags


    def setData(self, index, value, role=Qt.EditRole):
        if not index.isValid():
            return False
        if index.column() == 0:
            self.labels[index.row()].label = value
        elif index.column() == 1:
            self.labels[index.row()].key_shortcut = value
            act = self.find_action(value)
            if not act is None:
                act_text = act.text().replace('&', '')
                QMessageBox.information(self.parent(), "Audian key shortcut",
                                        f'Key shortcut <b>{value}</b> for label <b>{self.labels[index.row()].label}</b> disables <b>{act_text}</b>')
        elif index.column() == 2:
            self.labels[index.row()].color = value
        else:
            return False
        self.dataChanged.emit(index, index)
        return True


    def find_action(self, key_shortcut):
        ks = QKeySequence(key_shortcut)
        for a in dir(self.acts):
            act = getattr(self.acts, a)
            if isinstance(act, QAction) and act.shortcut() == ks:
                return act
        return None

                
    def store(self):
        for k in range(len(self.labels)):
            if k < len(self.orig_labels):
                self.orig_labels[k] = self.labels[k]
            else:
                self.orig_labels.append(self.labels[k])

                
    def set(self, labels):
        self.beginResetModel()
        self.orig_labels = labels
        self.labels = [x.copy() for x in labels]
        self.endResetModel()


    def insertRows(self, row, count, parent=QModelIndex()):
        if row > len(self.labels):
            return False
        self.beginInsertRows(parent, row, row+count-1)
        for k in range(count):
            color = list(colors.keys())[(row+k)%len(colors)]
            self.labels.insert(row+k, MarkerLabel(chr(ord('A')+row+k),
                                                  '', color))
        self.endInsertRows()
        return True

        
    def add_row(self):
        self.insertRows(len(self.labels), 1)


    def removeRows(self, row, count, parent=QModelIndex()):
        if row >= len(self.labels):
            return False
        self.beginRemoveRows(parent, row, row+count-1)
        for k in range(count):
            self.labels.pop(row)
        self.endRemoveRows()
        return True

        
    def remove_rows(self):
        selection = self.view.selectionModel()
        if selection.hasSelection():
            rows = [r.row() for r in selection.selectedRows()]
            for r in reversed(sorted(rows)):
                self.removeRow(r)

    
    def edit(self, parent):
        if not self.dialog is None:
            return
        xwidth = parent.fontMetrics().averageCharWidth()
        self.dialog = QDialog(parent)
        self.dialog.setWindowTitle('Audian label editor')
        vbox = QVBoxLayout()
        vbox.setContentsMargins(10, 10, 10, 10)
        self.dialog.setLayout(vbox)
        hbox = QHBoxLayout()
        hbox.setContentsMargins(0, 0, 0, 0)
        vbox.addLayout(hbox)
        self.view = QTableView()
        self.view.setModel(self)
        self.view.resizeColumnsToContents()
        self.view.setColumnWidth(0, max(8*xwidth,
                                        self.view.columnWidth(0)) +
                                 4*xwidth)
        self.view.setColumnWidth(2, max(12*xwidth,
                                        self.view.columnWidth(2)))
        self.view.horizontalHeader().setStretchLastSection(True)
        self.view.setSelectionBehavior(self.view.SelectRows)
        if has_key_editor:
            self.key_delegate = KeySequenceDelegate(self.dialog)
            self.view.setItemDelegateForColumn(1, self.key_delegate)
        color_delegate = ColorDelegate(self.dialog)
        self.view.setItemDelegateForColumn(2, color_delegate)
        hbox.addWidget(self.view)
        bbox = QVBoxLayout()
        bbox.setContentsMargins(0, 0, 0, 0)
        hbox.addLayout(bbox)
        addb = QPushButton('&Add')
        addb.clicked.connect(self.add_row)
        bbox.addWidget(addb)
        delb = QPushButton('&Remove')
        delb.clicked.connect(self.remove_rows)
        bbox.addWidget(delb)
        buttons = QDialogButtonBox(QDialogButtonBox.Cancel |
                                   QDialogButtonBox.Ok)
        buttons.rejected.connect(self.dialog.reject)
        buttons.accepted.connect(self.dialog.accept)
        vbox.addWidget(buttons)
        width = 50 + delb.sizeHint().width()
        width += self.view.verticalHeader().width()
        for c in range(self.columnCount()):
            width += self.view.columnWidth(c)
        self.dialog.setMaximumWidth(width)
        self.dialog.resize(width, 30*xwidth)
        self.dialog.finished.connect(self.finished)
        self.dialog.show()


    def finished(self, result=0):
        if result == QDialog.Accepted:
            self.store()
        self.dialog = None

QAbstractTableModel(parent: Optional[QObject] = None)

Ancestors

  • PyQt5.QtCore.QAbstractTableModel
  • PyQt5.QtCore.QAbstractItemModel
  • PyQt5.QtCore.QObject
  • sip.wrapper
  • sip.simplewrapper

Methods

def rowCount(self, parent=None)
Expand source code
def rowCount(self, parent=None):
    return len(self.labels)

rowCount(self, parent: QModelIndex = QModelIndex()) -> int

def columnCount(self, parent=None)
Expand source code
def columnCount(self, parent=None):
    return 3

columnCount(self, parent: QModelIndex = QModelIndex()) -> int

def headerData(self, index, orientation, role=0)
Expand source code
def headerData(self, index, orientation, role=Qt.DisplayRole):
    if orientation == Qt.Horizontal and role == Qt.DisplayRole:
        return self.header[index]
    if orientation == Qt.Vertical and role == Qt.DisplayRole:
        return f'{index}'
    return QVariant()

headerData(self, section: int, orientation: Qt.Orientation, role: int = Qt.ItemDataRole.DisplayRole) -> Any

def data(self, index, role=0)
Expand source code
def data(self, index, role=Qt.DisplayRole):
    if not index.isValid():
        return QVariant()
    
    # data:
    if role == Qt.DisplayRole or role == Qt.EditRole:
        label = self.labels[index.row()]
        if index.column() == 0:
            return label.label
        elif index.column() == 1:
            return label.key_shortcut
        elif index.column() == 2:
            return label.color
        else:
            return QVariant()

    # icons:
    if role == Qt.DecorationRole:
        label = self.labels[index.row()]
        if index.column() == 2:
            return self.icons[label.color]
            
    # alignment:
    if role == Qt.TextAlignmentRole:
        return Qt.AlignLeft | Qt.AlignVCenter

    return QVariant()

data(self, index: QModelIndex, role: int = Qt.ItemDataRole.DisplayRole) -> Any

def flags(self, index)
Expand source code
def flags(self, index):
    if not index.isValid():
        return Qt.NoItemFlag
    flags = Qt.ItemIsSelectable | Qt.ItemIsDragEnabled | Qt.ItemIsEnabled | Qt.ItemIsEditable
    return flags

flags(self, index: QModelIndex) -> Qt.ItemFlags

def setData(self, index, value, role=2)
Expand source code
def setData(self, index, value, role=Qt.EditRole):
    if not index.isValid():
        return False
    if index.column() == 0:
        self.labels[index.row()].label = value
    elif index.column() == 1:
        self.labels[index.row()].key_shortcut = value
        act = self.find_action(value)
        if not act is None:
            act_text = act.text().replace('&', '')
            QMessageBox.information(self.parent(), "Audian key shortcut",
                                    f'Key shortcut <b>{value}</b> for label <b>{self.labels[index.row()].label}</b> disables <b>{act_text}</b>')
    elif index.column() == 2:
        self.labels[index.row()].color = value
    else:
        return False
    self.dataChanged.emit(index, index)
    return True

setData(self, index: QModelIndex, value: Any, role: int = Qt.ItemDataRole.EditRole) -> bool

def find_action(self, key_shortcut)
Expand source code
def find_action(self, key_shortcut):
    ks = QKeySequence(key_shortcut)
    for a in dir(self.acts):
        act = getattr(self.acts, a)
        if isinstance(act, QAction) and act.shortcut() == ks:
            return act
    return None
def store(self)
Expand source code
def store(self):
    for k in range(len(self.labels)):
        if k < len(self.orig_labels):
            self.orig_labels[k] = self.labels[k]
        else:
            self.orig_labels.append(self.labels[k])
def set(self, labels)
Expand source code
def set(self, labels):
    self.beginResetModel()
    self.orig_labels = labels
    self.labels = [x.copy() for x in labels]
    self.endResetModel()
def insertRows(self, row, count, parent=<PyQt5.QtCore.QModelIndex object>)
Expand source code
def insertRows(self, row, count, parent=QModelIndex()):
    if row > len(self.labels):
        return False
    self.beginInsertRows(parent, row, row+count-1)
    for k in range(count):
        color = list(colors.keys())[(row+k)%len(colors)]
        self.labels.insert(row+k, MarkerLabel(chr(ord('A')+row+k),
                                              '', color))
    self.endInsertRows()
    return True

insertRows(self, row: int, count: int, parent: QModelIndex = QModelIndex()) -> bool

def add_row(self)
Expand source code
def add_row(self):
    self.insertRows(len(self.labels), 1)
def removeRows(self, row, count, parent=<PyQt5.QtCore.QModelIndex object>)
Expand source code
def removeRows(self, row, count, parent=QModelIndex()):
    if row >= len(self.labels):
        return False
    self.beginRemoveRows(parent, row, row+count-1)
    for k in range(count):
        self.labels.pop(row)
    self.endRemoveRows()
    return True

removeRows(self, row: int, count: int, parent: QModelIndex = QModelIndex()) -> bool

def remove_rows(self)
Expand source code
def remove_rows(self):
    selection = self.view.selectionModel()
    if selection.hasSelection():
        rows = [r.row() for r in selection.selectedRows()]
        for r in reversed(sorted(rows)):
            self.removeRow(r)
def edit(self, parent)
Expand source code
def edit(self, parent):
    if not self.dialog is None:
        return
    xwidth = parent.fontMetrics().averageCharWidth()
    self.dialog = QDialog(parent)
    self.dialog.setWindowTitle('Audian label editor')
    vbox = QVBoxLayout()
    vbox.setContentsMargins(10, 10, 10, 10)
    self.dialog.setLayout(vbox)
    hbox = QHBoxLayout()
    hbox.setContentsMargins(0, 0, 0, 0)
    vbox.addLayout(hbox)
    self.view = QTableView()
    self.view.setModel(self)
    self.view.resizeColumnsToContents()
    self.view.setColumnWidth(0, max(8*xwidth,
                                    self.view.columnWidth(0)) +
                             4*xwidth)
    self.view.setColumnWidth(2, max(12*xwidth,
                                    self.view.columnWidth(2)))
    self.view.horizontalHeader().setStretchLastSection(True)
    self.view.setSelectionBehavior(self.view.SelectRows)
    if has_key_editor:
        self.key_delegate = KeySequenceDelegate(self.dialog)
        self.view.setItemDelegateForColumn(1, self.key_delegate)
    color_delegate = ColorDelegate(self.dialog)
    self.view.setItemDelegateForColumn(2, color_delegate)
    hbox.addWidget(self.view)
    bbox = QVBoxLayout()
    bbox.setContentsMargins(0, 0, 0, 0)
    hbox.addLayout(bbox)
    addb = QPushButton('&Add')
    addb.clicked.connect(self.add_row)
    bbox.addWidget(addb)
    delb = QPushButton('&Remove')
    delb.clicked.connect(self.remove_rows)
    bbox.addWidget(delb)
    buttons = QDialogButtonBox(QDialogButtonBox.Cancel |
                               QDialogButtonBox.Ok)
    buttons.rejected.connect(self.dialog.reject)
    buttons.accepted.connect(self.dialog.accept)
    vbox.addWidget(buttons)
    width = 50 + delb.sizeHint().width()
    width += self.view.verticalHeader().width()
    for c in range(self.columnCount()):
        width += self.view.columnWidth(c)
    self.dialog.setMaximumWidth(width)
    self.dialog.resize(width, 30*xwidth)
    self.dialog.finished.connect(self.finished)
    self.dialog.show()
def finished(self, result=0)
Expand source code
def finished(self, result=0):
    if result == QDialog.Accepted:
        self.store()
    self.dialog = None
class MarkerData
Expand source code
class MarkerData:

    def __init__(self):
        self.file_path = None
        self.channels = []
        self.times = []
        self.amplitudes = []
        self.frequencies = []
        self.powers = []
        self.delta_times = []
        self.delta_amplitudes = []
        self.delta_frequencies = []
        self.delta_powers = []
        self.labels = []
        self.texts = []
        self.keys = ['channels', 'times', 'amplitudes',
                     'frequencies', 'powers',
                     'delta_times', 'delta_amplitudes',
                     'delta_frequencies', 'delta_powers', 'labels', 'texts']
        self.headers = ['channel', 'time/s', 'amplitude',
                       'frequency/Hz', 'power/dB',
                       'time-diff/s', 'ampl-diff',
                        'freq-diff/Hz', 'power-diff/dB', 'label', 'text']

        
    def clear(self):
        self.channels = []
        self.times = []
        self.amplitudes = []
        self.frequencies = []
        self.powers = []
        self.delta_times = []
        self.delta_amplitudes = []
        self.delta_frequencies = []
        self.delta_powers = []
        self.labels = []
        self.texts = []


    def add_data(self, channel, time, amplitude=None,
                 frequency=None, power=None,
                 delta_time=None, delta_amplitude=None,
                 delta_frequency=None, delta_power=None,
                 label='', text=''):
        self.channels.append(channel)
        self.times.append(time if not time is None else np.nan)
        self.amplitudes.append(amplitude if not amplitude is None else np.nan)
        self.frequencies.append(frequency if not frequency is None else np.nan)
        self.powers.append(power if not power is None else np.nan)
        self.delta_times.append(delta_time if not delta_time is None else np.nan)
        self.delta_amplitudes.append(delta_amplitude if not delta_amplitude is None else np.nan)
        self.delta_frequencies.append(delta_frequency if not delta_frequency is None else np.nan)
        self.delta_powers.append(delta_power if not delta_power is None else np.nan)
        self.labels.append(label)
        self.texts.append(text)

        
    def set_label(self, index, label):
        self.labels[index] = label

        
    def set_text(self, index, text):
        self.texts[index] = text


    def data_frame(self):
        table_dict = {}
        for key, header in zip(self.keys, self.headers):
            table_dict[header] = getattr(self, key)
        return pd.DataFrame(table_dict)


    def set_markers(self, locs, labels, rate):
        for i in range(len(locs)):
            l = ''
            t = ''
            if i < len(labels):
                l = labels[i,0]
                t = labels[i,1]
            tstart = float(locs[i,0])/rate
            tspan = float(locs[i,1])/rate
            self.add_data(0, tstart + tspan, delta_time=tspan,
                          label=l, text=t)

            
    def get_markers(self, rate):
        n = len(self.times)
        locs = np.zeros((n, 2), dtype=int)
        labels = np.zeros((n, 3), dtype=object)
        for k in range(n):
            ispan = int(np.round(self.delta_times[k]*rate))
            i1 = int(np.round(self.times[k]*rate))
            locs[k,0] = i1 - ispan
            locs[k,1] = ispan
            labels[k,0] = self.labels[k]
            labels[k,1] = self.texts[k]
        return locs, labels

Methods

def clear(self)
Expand source code
def clear(self):
    self.channels = []
    self.times = []
    self.amplitudes = []
    self.frequencies = []
    self.powers = []
    self.delta_times = []
    self.delta_amplitudes = []
    self.delta_frequencies = []
    self.delta_powers = []
    self.labels = []
    self.texts = []
def add_data(self,
channel,
time,
amplitude=None,
frequency=None,
power=None,
delta_time=None,
delta_amplitude=None,
delta_frequency=None,
delta_power=None,
label='',
text='')
Expand source code
def add_data(self, channel, time, amplitude=None,
             frequency=None, power=None,
             delta_time=None, delta_amplitude=None,
             delta_frequency=None, delta_power=None,
             label='', text=''):
    self.channels.append(channel)
    self.times.append(time if not time is None else np.nan)
    self.amplitudes.append(amplitude if not amplitude is None else np.nan)
    self.frequencies.append(frequency if not frequency is None else np.nan)
    self.powers.append(power if not power is None else np.nan)
    self.delta_times.append(delta_time if not delta_time is None else np.nan)
    self.delta_amplitudes.append(delta_amplitude if not delta_amplitude is None else np.nan)
    self.delta_frequencies.append(delta_frequency if not delta_frequency is None else np.nan)
    self.delta_powers.append(delta_power if not delta_power is None else np.nan)
    self.labels.append(label)
    self.texts.append(text)
def set_label(self, index, label)
Expand source code
def set_label(self, index, label):
    self.labels[index] = label
def set_text(self, index, text)
Expand source code
def set_text(self, index, text):
    self.texts[index] = text
def data_frame(self)
Expand source code
def data_frame(self):
    table_dict = {}
    for key, header in zip(self.keys, self.headers):
        table_dict[header] = getattr(self, key)
    return pd.DataFrame(table_dict)
def set_markers(self, locs, labels, rate)
Expand source code
def set_markers(self, locs, labels, rate):
    for i in range(len(locs)):
        l = ''
        t = ''
        if i < len(labels):
            l = labels[i,0]
            t = labels[i,1]
        tstart = float(locs[i,0])/rate
        tspan = float(locs[i,1])/rate
        self.add_data(0, tstart + tspan, delta_time=tspan,
                      label=l, text=t)
def get_markers(self, rate)
Expand source code
def get_markers(self, rate):
    n = len(self.times)
    locs = np.zeros((n, 2), dtype=int)
    labels = np.zeros((n, 3), dtype=object)
    for k in range(n):
        ispan = int(np.round(self.delta_times[k]*rate))
        i1 = int(np.round(self.times[k]*rate))
        locs[k,0] = i1 - ispan
        locs[k,1] = ispan
        labels[k,0] = self.labels[k]
        labels[k,1] = self.texts[k]
    return locs, labels
class MarkerDataModel (data, parent=None)
Expand source code
class MarkerDataModel(QAbstractTableModel):
    
    def __init__(self, data, parent=None):
        QAbstractTableModel.__init__(self, parent)
        self.data = data

        
    def rowCount(self, parent=None):
        return len(self.data.channels)

    
    def columnCount(self, parent=None):
        return len(self.data.keys)


    def headerData(self, index, orientation, role=Qt.DisplayRole):
        if orientation == Qt.Horizontal and role == Qt.DisplayRole:
            return self.data.headers[index]
        if orientation == Qt.Vertical and role == Qt.DisplayRole:
            return f'{index}'
        return QVariant()

    
    def data(self, index, role=Qt.DisplayRole):
        if not index.isValid():
            return QVariant()
        
        key = self.data.keys[index.column()]
        item = getattr(self.data, key)[index.row()]
        
        # data:
        if role == Qt.DisplayRole or role == Qt.EditRole:
            if key == 'labels' or key == 'texts':
                return item
            else:
                if item is np.nan:
                    return '-'
                else:
                    return f'{item:.5g}'
                
        # alignment:
        if role == Qt.TextAlignmentRole:
            if key == 'labels' or key == 'texts':
                return Qt.AlignLeft | Qt.AlignVCenter
            else:
                if item is np.nan:
                    return Qt.AlignHCenter | Qt.AlignVCenter
                else:
                    return Qt.AlignRight | Qt.AlignVCenter

        return QVariant()

    
    def flags(self, index):
        if not index.isValid():
            return Qt.NoItemFlag
        flags = Qt.ItemIsSelectable | Qt.ItemIsDragEnabled | Qt.ItemIsEnabled
        key = self.data.keys[index.column()]
        if key == 'labels':
            return flags | Qt.ItemIsEditable
        else:
            return flags


    def setData(self, index, value, role=Qt.EditRole):
        if not index.isValid():
            return False
        key = self.data.keys[index.column()]
        if key == 'labels':
            self.data.labels[index.row()] = value
            self.dataChanged.emit(index, index)
            return True
        else:
            return False
        

    def clear(self):
        self.beginResetModel()
        self.data.clear()
        self.endResetModel()


    def save(self, parent):
        name = os.path.splitext(os.path.basename(self.data.file_path))[0]
        file_name = f'{name}-events.csv'
        filters = 'All files (*);;Comma separated values CSV (*.csv)'
        has_excel = False
        try:
            import openpyxl
            has_excel = True
            filters += ';;Excel spreadsheet XLSX (*.xlsx)'
        except ImportError:
            pass
        file_path = os.path.join(os.path.dirname(self.data.file_path),
                                 file_name)
        file_path = QFileDialog.getSaveFileName(parent, 'Save marker data',
                                                file_path, filters)[0]
        if file_path:
            df = self.data.data_frame()
            ext = os.path.splitext(file_path)[1]
            if has_excel and ext.lower() == '.xlsx':
                df.to_excel(file_path, index=False)
            else:
                df.to_csv(file_path, index=False)
            

    def add_data(self, channel, time, amplitude, frequency, power,
                 delta_time=None, delta_amplitude=None,
                 delta_frequency=None, delta_power=None, label=''):
        self.beginInsertRows(QModelIndex(),
                             len(self.data.channels), len(self.data.channels))
        self.data.add_data(channel, time, amplitude, frequency, power,
                           delta_time, delta_amplitude,
                           delta_frequency, delta_power, label)
        self.endInsertRows()

QAbstractTableModel(parent: Optional[QObject] = None)

Ancestors

  • PyQt5.QtCore.QAbstractTableModel
  • PyQt5.QtCore.QAbstractItemModel
  • PyQt5.QtCore.QObject
  • sip.wrapper
  • sip.simplewrapper

Methods

def rowCount(self, parent=None)
Expand source code
def rowCount(self, parent=None):
    return len(self.data.channels)

rowCount(self, parent: QModelIndex = QModelIndex()) -> int

def columnCount(self, parent=None)
Expand source code
def columnCount(self, parent=None):
    return len(self.data.keys)

columnCount(self, parent: QModelIndex = QModelIndex()) -> int

def headerData(self, index, orientation, role=0)
Expand source code
def headerData(self, index, orientation, role=Qt.DisplayRole):
    if orientation == Qt.Horizontal and role == Qt.DisplayRole:
        return self.data.headers[index]
    if orientation == Qt.Vertical and role == Qt.DisplayRole:
        return f'{index}'
    return QVariant()

headerData(self, section: int, orientation: Qt.Orientation, role: int = Qt.ItemDataRole.DisplayRole) -> Any

def data(self, index, role=0)
Expand source code
def data(self, index, role=Qt.DisplayRole):
    if not index.isValid():
        return QVariant()
    
    key = self.data.keys[index.column()]
    item = getattr(self.data, key)[index.row()]
    
    # data:
    if role == Qt.DisplayRole or role == Qt.EditRole:
        if key == 'labels' or key == 'texts':
            return item
        else:
            if item is np.nan:
                return '-'
            else:
                return f'{item:.5g}'
            
    # alignment:
    if role == Qt.TextAlignmentRole:
        if key == 'labels' or key == 'texts':
            return Qt.AlignLeft | Qt.AlignVCenter
        else:
            if item is np.nan:
                return Qt.AlignHCenter | Qt.AlignVCenter
            else:
                return Qt.AlignRight | Qt.AlignVCenter

    return QVariant()

data(self, index: QModelIndex, role: int = Qt.ItemDataRole.DisplayRole) -> Any

def flags(self, index)
Expand source code
def flags(self, index):
    if not index.isValid():
        return Qt.NoItemFlag
    flags = Qt.ItemIsSelectable | Qt.ItemIsDragEnabled | Qt.ItemIsEnabled
    key = self.data.keys[index.column()]
    if key == 'labels':
        return flags | Qt.ItemIsEditable
    else:
        return flags

flags(self, index: QModelIndex) -> Qt.ItemFlags

def setData(self, index, value, role=2)
Expand source code
def setData(self, index, value, role=Qt.EditRole):
    if not index.isValid():
        return False
    key = self.data.keys[index.column()]
    if key == 'labels':
        self.data.labels[index.row()] = value
        self.dataChanged.emit(index, index)
        return True
    else:
        return False

setData(self, index: QModelIndex, value: Any, role: int = Qt.ItemDataRole.EditRole) -> bool

def clear(self)
Expand source code
def clear(self):
    self.beginResetModel()
    self.data.clear()
    self.endResetModel()
def save(self, parent)
Expand source code
def save(self, parent):
    name = os.path.splitext(os.path.basename(self.data.file_path))[0]
    file_name = f'{name}-events.csv'
    filters = 'All files (*);;Comma separated values CSV (*.csv)'
    has_excel = False
    try:
        import openpyxl
        has_excel = True
        filters += ';;Excel spreadsheet XLSX (*.xlsx)'
    except ImportError:
        pass
    file_path = os.path.join(os.path.dirname(self.data.file_path),
                             file_name)
    file_path = QFileDialog.getSaveFileName(parent, 'Save marker data',
                                            file_path, filters)[0]
    if file_path:
        df = self.data.data_frame()
        ext = os.path.splitext(file_path)[1]
        if has_excel and ext.lower() == '.xlsx':
            df.to_excel(file_path, index=False)
        else:
            df.to_csv(file_path, index=False)
def add_data(self,
channel,
time,
amplitude,
frequency,
power,
delta_time=None,
delta_amplitude=None,
delta_frequency=None,
delta_power=None,
label='')
Expand source code
def add_data(self, channel, time, amplitude, frequency, power,
             delta_time=None, delta_amplitude=None,
             delta_frequency=None, delta_power=None, label=''):
    self.beginInsertRows(QModelIndex(),
                         len(self.data.channels), len(self.data.channels))
    self.data.add_data(channel, time, amplitude, frequency, power,
                       delta_time, delta_amplitude,
                       delta_frequency, delta_power, label)
    self.endInsertRows()