# -*- coding: utf-8 -*-
"""
This module implements utility functions and classes for NeuroChaT UI.
@author: Md Nurul Islam; islammn at tcd dot ie
"""
from PyQt5 import QtCore, QtWidgets, QtGui
try:
xlt_from_utf8 = QtCore.QString.fromUtf8
except AttributeError:
[docs] def xlt_from_utf8(s):
return s
[docs]class NLogBox(QtWidgets.QTextEdit):
"""
This class creates a formatted text-editable log-box for NeuroChaT.
Subclassed from PyQt5.QtWidgets.QTextEdit
"""
def __init__(self, parent=None):
super().__init__(parent)
[docs] def insert_log(self, msg):
"""
Format further the HTML 'msg' to categorally add color.
Also displays it in the log-box or in any log-handler.
Parameters
----------
msg
Log record that is to be displayed
"""
level = msg.split(':')[0].upper()
if level == "WARNING":
color = "darkorange"
elif level == "ERROR":
color = "red"
elif level == "INFO":
color = "black"
else:
color = "blue"
msg = '<font color=' + color + '>' + \
msg[msg.find(":") + 1:] + '</font><br>'
self.insertHtml(msg)
self.moveCursor(QtGui.QTextCursor.End)
[docs] def get_text(self):
"""
Return the text of log-box in plain text format.
Parameters
----------
None
Returns
-------
str
Plain text of log-box
"""
return self.toPlainText()
[docs]class NOut(QtCore.QObject):
"""
Implements the Qt signalling mechanism.
Subclassed from PyQt5.QtCore.QObject, it implements the Qt signalling
mechanism so that when a text is written using NOut() object, it emits a
text to the output to an output console or file or where the emitted signal
is connected to.
In NeuroChaT, the sys.stdout.write is replaced with NOut().write,
which means print('some text') will print to GUI log box in GUI and
to the standard output console when used in API.
"""
emitted = QtCore.pyqtSignal(str)
def __init__(self):
super().__init__()
[docs] def write(self, text):
"""
Emit the texts as Qt signal.
Parameters
----------
text : str
Text to be emitted
Returns
-------
None
"""
self.emitted.emit(text)
[docs]class PandasModel(QtCore.QAbstractTableModel):
"""
Class to populate a QT table view with a pandas dataframe.
Also implements methods that are to be overridden.
"""
def __init__(self, data, parent=None):
super().__init__(parent)
self._data = data
[docs] def rowCount(self, parent=None):
"""
Override the rowCount() method.
Parameters
----------
parent : QtCore.QModelIndex
Specific model for item index. Usually not required.
Returns
-------
int
Count of row in the item model
"""
return self._data.shape[0]
[docs] def columnCount(self, parent=None):
"""
Override the columnCount() method.
Parameters
----------
parent : QtCore.QModelIndex
Specific model for item index. Usually not required.
Returns
-------
int
Count of column in the item model
"""
return self._data.shape[1]
[docs] def data(self, index, role=QtCore.Qt.DisplayRole):
"""
Data model for the QtCore.QAbstractTableModel.
Parameters
----------
index
Pandas DataFrame index
role : Qt.ItemDataRole
Usually set for QtCore.Qt.DisplayRole which means the data to rendered
in the form of text
Returns
-------
str
Returns the data in the DataFrame's 'index' location in str format
"""
if index.isValid():
if role == QtCore.Qt.DisplayRole:
return str(self._data.iloc[index.row(), index.column()])
return None
[docs] def headerData(self, index, orientation, role):
"""
Data model for the QtCore.QAbstractTableModel.
Parameters
----------
index
Pandas DataFrame index
orientation : Qt.Orientation
Orientation of the data
role : Qt.ItemDataRole
Usually set for QtCore.Qt.DisplayRole which means the data to be rendered
in the form of text
Returns
-------
Data in the DataFrame().columns[index] if orientation is 'Horizontal'
or DataFrame().index[index] if orientation is 'Vertical'
"""
if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole:
return self._data.columns[index]
elif orientation == QtCore.Qt.Vertical and role == QtCore.Qt.DisplayRole:
return self._data.index[index]
return None
[docs]def add_log_box(obj_name):
"""
Return a NLogBox() object.
Parameters
----------
obj_name : str
Name of the newly created object
Returns
-------
NLogBox
Instance of NLogBox Class
"""
logTextBox = NLogBox()
return logTextBox
[docs]def add_check_box(parent=None, position=None, obj_name='', text=None):
"""
Return a QtWidgets.QCheckBox() object.
Parameters
----------
parent
Parent widget
position : tuple
Position in the parent object
obj_name : str
Name of the newly created object
text : str
Check box text
Returns
-------
QtWidgets.QCheckBox
Instance of QtWidgets.QCheckBox Class
"""
box = QtWidgets.QCheckBox(parent)
box.setObjectName(xlt_from_utf8(obj_name))
if position:
box.setGeometry(QtCore.QRect(*position))
if text:
box.setText(text)
return box
[docs]def add_combo_box(parent=None, position=None, obj_name=''):
"""
Return a QtWidgets.QComboBox() object.
Parameters
----------
parent
Parent widget
position : tuple
Position in the parent object
obj_name : str
Name of the newly created object
Returns
-------
QtWidgets.QComboBox
Instance of QtWidgets.QComboBox Class
"""
box = QtWidgets.QComboBox(parent)
box.setObjectName(xlt_from_utf8(obj_name))
if position:
box.setGeometry(QtCore.QRect(*position))
return box
[docs]def add_label(parent=None, position=None, obj_name='', text=None):
"""
Return a QtWidgets.QLabel() object.
Parameters
----------
parent
Parent widget
position : tuple
Position in the parent object
obj_name : str
Name of the newly created object
text : str
Label text
Returns
-------
QtWidgets.QLabel
Instance of QtWidgets.QLabel Class
"""
label = QtWidgets.QLabel(parent)
label.setObjectName(xlt_from_utf8(obj_name))
if position:
label.setGeometry(QtCore.QRect(*position))
if text:
label.setText(text)
return label
[docs]def add_line_edit(parent=None, position=None, obj_name='', text=None):
"""
Return a QtWidgets.QLineEdit() object.
Parameters
----------
parent
Parent widget
position : tuple
Position in the parent object
obj_name : str
Name of the newly created object
text : str
Line-edit text
Returns
-------
QtWidgets.QLineEdit
Instance of QtWidgets.QLineEdit Class
"""
line = QtWidgets.QLineEdit(parent)
line.setObjectName(xlt_from_utf8(obj_name))
if position:
line.setGeometry(QtCore.QRect(*position))
if text:
line.setText(text)
return line
[docs]def add_group_box(parent=None, position=None, obj_name='', title=None):
"""
Return a QtWidgets.QGroupBox() object.
Parameters
----------
parent
Parent widget
position : tuple
Position in the parent object
obj_name : str
Name of the newly created object
title : str
Title of the group-box
Returns
-------
QtWidgets.QGroupBox
Instance of QtWidgets.QGroupBox Class
"""
groupBox = QtWidgets.QGroupBox(parent)
groupBox.setObjectName(xlt_from_utf8(obj_name))
if position:
groupBox.setGeometry(QtCore.QRect(*position))
if title:
groupBox.setTitle(title)
return groupBox
[docs]def add_spin_box(parent=None, position=None,
obj_name='', min_val=0, max_val=128):
"""
Return a QtWidgets.QSpinBox() object.
Parameters
----------
parent
Parent widget
position : tuple
Position in the parent object
min_val : int
Minimum value of the spin-box
max_val : int
Maximum value of the spin-box
obj_name : str
Name of the newly created object
Returns
-------
QtWidgets.QSpinBox
Instance of QtWidgets.QSpinBox Class
"""
box = QtWidgets.QSpinBox(parent)
box.setObjectName(xlt_from_utf8(obj_name))
if position:
box.setGeometry(QtCore.QRect(*position))
box.setMinimum(min_val)
box.setMaximum(max_val)
return box
[docs]def add_double_spin_box(parent=None, position=None,
min_val=0, max_val=1, obj_name=""):
"""
Return a QtWidgets.QDoubleSpinBox() object.
Parameters
----------
parent
Parent widget
position : tuple
Position in the parent object
min_val : float
Minimum value of the spin-box
max_val : float
Maximum value of the spin-box
obj_name : str
Name of the newly created object
Returns
-------
QtWidgets.QDoubleSpinBox
Instance of QtWidgets.QDoubleSpinBox Class
"""
box = QtWidgets.QDoubleSpinBox(parent)
box.setObjectName(xlt_from_utf8(obj_name))
if position:
box.setGeometry(QtCore.QRect(*position))
box.setMinimum(min_val)
box.setMaximum(max_val)
return box