Source code for wbia.guitool.guitool_misc

# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, print_function
from wbia.guitool.__PYQT__ import QtCore, QtGui
from wbia.guitool.__PYQT__ import QtWidgets  # NOQA
import six
import utool
import sys
import logging
from six.moves import range
from wbia.guitool.guitool_decorators import slot_
from wbia.guitool import guitool_main
import utool as ut

ut.noinject(__name__)


# For some reason QtCore.Qt.ALT doesn't work right
ALT_KEY = 16777251


[docs]def make_option_dict(options, shortcuts=True): """ helper for popup menu callbacks """ keys = ut.take_column(options, 0) values = ut.take_column(options, 1) if shortcuts: shortcut_keys = [key[key.find('&') + 1] if '&' in key else None for key in keys] try: ut.assert_unique(shortcut_keys, name='shortcut_keys', ignore=[None]) except AssertionError: print('shortcut_keys = %r' % (shortcut_keys,)) print('options = %r' % (ut.repr2(options),)) raise shortcut_dict = { sc_key: val # sc_key: (make_option_dict(val, shortcuts=True) # if isinstance(val, list) else val) for (sc_key, val) in zip(shortcut_keys, values) if sc_key is not None and not isinstance(val, list) } return shortcut_dict else: ut.assert_unique(keys, name='option_keys') fulltext_dict = { key: ( make_option_dict(val, shortcuts=False) if isinstance(val, list) else val ) for (key, val) in zip(keys, values) if key is not None } return fulltext_dict
[docs]def find_used_chars(name_list): """ Move to guitool """ used_chars = [] for name in name_list: index = name.find('&') if index == -1 or index + 1 >= len(name): continue char = name[index + 1] used_chars.append(char) return used_chars
[docs]class BlockContext(object): def __init__(self, widget): self.widget = widget self.was_blocked = None def __enter__(self): self.was_blocked = self.widget.blockSignals(True) def __exit__(self, type_, value, trace): if trace is not None: print('[BlockContext] Error in context manager!: ' + str(value)) return False # return a falsey value on error self.widget.blockSignals(self.was_blocked)
# Qt object that will send messages (as signals) to the frontend gui_write slot
[docs]class GUILoggingSender(QtCore.QObject): write_ = QtCore.pyqtSignal(str) def __init__(self, write_slot): QtCore.QObject.__init__(self) self.write_.connect(write_slot)
[docs] def write_gui(self, msg): self.write_.emit(str(msg))
[docs]class GUILoggingHandler(logging.StreamHandler): """ A handler class which sends messages to to a connected QSlot """ def __init__(self, write_slot): super(GUILoggingHandler, self).__init__() self.sender = GUILoggingSender(write_slot)
[docs] def emit(self, record): try: msg = self.format(record) + '\n' self.sender.write_.emit(msg) except (KeyboardInterrupt, SystemExit): raise except Exception: self.handleError(record)
[docs]class QLoggedOutput(QtWidgets.QTextEdit): def __init__(self, parent=None, visible=True): super(QLoggedOutput, self).__init__(parent) # QtWidgets.QTextEdit.__init__(self, parent) self.setAcceptRichText(False) self.setReadOnly(True) self.setVisible(visible) self.logging_handler = None if visible: self._initialize_handler()
[docs] def setVisible(self, flag): if flag and self.logging_handler is None: # Make sure handler is initialized on first go self._initialize_handler() super(QLoggedOutput, self).setVisible(flag)
def _initialize_handler(self): self.logging_handler = GUILoggingHandler(self.gui_write) utool.add_logging_handler(self.logging_handler)
[docs] @slot_(str) def gui_write(outputEdit, msg_): # Slot for teed log output app = guitool_main.get_qtapp() # Write msg to text area outputEdit.moveCursor(QtGui.QTextCursor.End) # TODO: Find out how to do backspaces in textEdit msg = str(msg_) if msg.find('\b') != -1: msg = msg.replace('\b', '') + '\n' outputEdit.insertPlainText(msg) if app is not None: app.processEvents()
[docs] @slot_() def gui_flush(outputEdit): app = guitool_main.get_qtapp() if app is not None: app.processEvents()
[docs]def get_cplat_tab_height(): if sys.platform.startswith('darwin'): tab_height = 21 else: tab_height = 30 return tab_height
[docs]def get_view_selection_as_str(view): """ References: http://stackoverflow.com/questions/3135737/copying-part-of-qtableview """ model = view.model() selection_model = view.selectionModel() qindex_list = selection_model.selectedIndexes() qindex_list = sorted(qindex_list) # print('[guitool] %d cells selected' % len(qindex_list)) if len(qindex_list) == 0: return copy_table = [] previous = qindex_list[0] def astext(data): """ Helper which casts model data to a string """ if not isinstance(data, six.string_types): text = repr(data) else: text = str(data) return text.replace('\n', '<NEWLINE>').replace(',', '<COMMA>') # for ix in range(1, len(qindex_list)): text = astext(model.data(previous)) copy_table.append(text) qindex = qindex_list[ix] if qindex.row() != previous.row(): copy_table.append('\n') else: copy_table.append(', ') previous = qindex # Do last element in list text = astext(model.data(qindex_list[-1])) copy_table.append(text) # copy_table.append('\n') copy_str = str(''.join(copy_table)) return copy_str
[docs]def set_qt_object_names(dict_): """ Hack to set qt object names from locals, vars, or general dict context """ for key, val in dict_.items(): if hasattr(val, 'setObjectName'): val.setObjectName(key)