Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # -*- coding: utf-8 -*-
- #! /usr/bin/env python
- '''
- Python Manager
- ==============
- GUI tool for managing modules and packages based on reimport: Full featured reload for Python.
- '''
- import os
- import reimport
- import sys
- import time
- import shiboken
- from itertools import groupby
- from PySide import QtGui, QtCore
- PARENT_APPLICATION = None
- if 'Maya' in sys.executable:
- from maya.OpenMayaUI.MQtUtil import mainWindow
- maya_window = shiboken.wrapInstance(long(mainWindow()), QtGui.QWidget)
- PARENT_APPLICATION = maya_window
- elif 'Nuke' in sys.executable:
- PARENT_APPLICATION = 'Nuke' # Replace with proper nuke qwidget
- STYLE = '''
- QLabel#Header{
- background: rgb(235, 235, 235);
- padding: 15px;
- font: 12pt;
- }
- QListWidget{
- background: rgb(215, 215, 215);
- outline: none;
- }
- QListWidget::item{
- background: rgb(215, 215, 215);
- border-top: 1px solid rgb(230, 230, 230);
- border-bottom: 1px solid rgb(200, 200, 200);
- outline: none;
- }
- QListWidget::item:selected{
- color: rgb(235, 235, 235);
- background: rgb(100, 100, 215);
- border-top: 1px solid rgb(115, 115, 230);
- border-bottom: 1px solid rgb(85, 85, 200)
- }
- QPushButton{
- border: 0;
- color: rgb(235, 235, 235);
- background: rgb(200, 20, 20);
- font-weight: 400;
- border-radius: 8px;
- }
- QPushButton:pressed{
- border: 0;
- padding: 0;
- margin: 0;
- }
- QScrollBar:vertical{
- border: 1px solid rgb(115, 115, 115);
- background: rgb(255, 255, 255, 0);
- width: 8px;
- margin: 0;
- }
- QScrollBar::handle:vertical{
- background: rgb(165, 165, 165);
- min-height: 20px;
- height: 40px;
- width: 8px;
- }
- QScrollBar::handle:vertical:hover{
- background: rgb(185, 185, 185);
- min-height: 20px;
- height: 40px;
- width: 8px;
- }
- QScrollBar::add-line:vertical{
- background: rgb(0,0,0,0);
- subcontrol-origin: paddding;
- subcontrol-position: top;
- }
- QScrollBar::sub-line:vertical{
- background: rgb(0,0,0,0);
- subcontrol-origin: padding;
- subcontrol-position: bottom;
- }
- QScrollBar::top-arrow:vertical, QScrollBar::bottom-arrow:vertical{
- background: rgb(255,255,255,0);
- }
- QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical{
- background: rgb(255,255,255,0);
- }
- '''
- class ModuleWidget(QtGui.QWidget):
- '''QListWidgetItem Widget that wraps up a module or package, displaying
- modified time and module path. Tooltips display module filepaths.
- '''
- def __init__(self, module, subpackages=None, parent=None):
- super(ModuleWidget, self).__init__(parent)
- self.module = module
- self.subpackages = subpackages
- self.grid = QtGui.QGridLayout()
- self.grid.setContentsMargins(20, 10, 20, 10)
- self.grid.setColumnStretch(2, 1)
- modname = self.module.__name__
- modpath = self.module.__file__
- modmodf = time.localtime(os.path.getmtime(modpath))
- font = QtGui.QFont('SansSerif', 12)
- subfont = QtGui.QFont('SansSerif', 10)
- self.modf = QtGui.QLabel(time.strftime('%H:%M', modmodf))
- self.modf.setFont(font)
- self.name = QtGui.QLabel(modname)
- self.name.setFont(font)
- self.name.setToolTip(modpath)
- self.grid.addWidget(self.modf, 0, 0)
- self.grid.addWidget(self.name, 0, 1, 1, 2)
- if self.subpackages:
- for i, subpackage in enumerate(self.subpackages):
- subname = subpackage.__name__
- subpath = subpackage.__file__
- submodf = time.localtime(os.path.getmtime(modpath))
- modf = QtGui.QLabel(time.strftime('%H:%M', modmodf))
- modf.setFont(subfont)
- name = QtGui.QLabel(subname)
- name.setFont(subfont)
- name.setToolTip(subpath)
- self.grid.addWidget(modf, i + 1, 1)
- self.grid.addWidget(name, i + 1, 2)
- self.setLayout(self.grid)
- self.setAttribute(QtCore.Qt.WA_StyledBackground)
- self.setObjectName('ModuleWidget')
- self.deactivate()
- def activate(self):
- self.setStyleSheet('QLabel{color:rgb(235,235,235)}')
- def deactivate(self):
- self.setStyleSheet('QLabel{color:rgb(15,15,15)}')
- class ModuleList(QtGui.QListWidget):
- '''QListWidget extended to act more like a python list and handle module
- objects.'''
- def __init__(self, *args, **kwargs):
- super(ModuleList, self).__init__(*args, **kwargs)
- self.itemSelectionChanged.connect(self.selection_changed)
- self.setSelectionMode(QtGui.QListWidget.ExtendedSelection)
- self.setFocusPolicy(QtCore.Qt.NoFocus)
- def selection_changed(self, *args):
- '''Change text color of ModuleWidgets based on selection.'''
- for i in range(self.count()):
- item = self.item(i)
- w = self.itemWidget(item)
- if w:
- if item.isSelected():
- w.activate()
- else:
- w.deactivate()
- def refresh(self):
- '''Get a new list of modified modules to display.'''
- self.clear()
- self.extend(reimport.modified())
- def extend(self, modules):
- '''Takes an iterable of module paths and groups them by package, then
- adds them to the QListWidget. Delegates QListWidgetItem to
- ModuleWidget.'''
- modified = sorted(modules)
- def top_level(item):
- '''Sort by top level module.'''
- return item.split('.')[0]
- grouped = {}
- for k, v in groupby(modified, key=top_level):
- grouped[k] = [item for item in v if not item == k]
- for module, subpackages in grouped.iteritems():
- m = sys.modules.get(module)
- sp = [sys.modules.get(p) for p in subpackages]
- self.append(m, sp)
- def append(self, module, subpackages=None):
- '''Append module or a package to the list.'''
- item = QtGui.QListWidgetItem(self)
- w = ModuleWidget(module, subpackages)
- item.setSizeHint(w.sizeHint())
- self.setItemWidget(item, w)
- super(ModuleList, self).addItem(item)
- def selected(self):
- '''Iterate over selected items.'''
- for item in self.selectedItems():
- yield(item)
- def pop(self, item):
- '''Pop a list item and return a ModuleWidget'''
- w = self.itemWidget(item)
- self.takeItem(self.row(item))
- return w
- class Button(QtGui.QPushButton):
- '''Sexy button with a drop shadow.'''
- shadow_state = {
- 'default': (12, (0, 4)),
- 'press': (12, (0, 2)),
- 'enter': (13, (0, 5)),
- }
- def __init__(self, *args, **kwargs):
- super(Button, self).__init__(*args, **kwargs)
- self.drop_shadow = QtGui.QGraphicsDropShadowEffect(self)
- self.drop_shadow.setBlurRadius(self.shadow_state['default'][0])
- self.drop_shadow.setOffset(*self.shadow_state['default'][1])
- self.drop_shadow.setColor(QtGui.QColor(0, 0, 0, 75))
- self.setFocusPolicy(QtCore.Qt.NoFocus)
- self.setGraphicsEffect(self.drop_shadow)
- def mousePressEvent(self, event):
- self.drop_shadow.setBlurRadius(self.shadow_state['press'][0])
- self.drop_shadow.setOffset(*self.shadow_state['press'][1])
- super(Button, self).mousePressEvent(event)
- def enterEvent(self, event):
- self.drop_shadow.setBlurRadius(self.shadow_state['enter'][0])
- self.drop_shadow.setOffset(*self.shadow_state['enter'][1])
- super(Button, self).enterEvent(event)
- def leaveEvent(self, event):
- self.drop_shadow.setBlurRadius(self.shadow_state['default'][0])
- self.drop_shadow.setOffset(*self.shadow_state['default'][1])
- super(Button, self).leaveEvent(event)
- def mouseReleaseEvent(self, event):
- self.drop_shadow.setBlurRadius(self.shadow_state['default'][0])
- self.drop_shadow.setOffset(*self.shadow_state['default'][1])
- super(Button, self).mouseReleaseEvent(event)
- class PythonManager(QtGui.QDialog):
- '''GUI Managing modified Python modules and packages.'''
- def __init__(self, parent=PARENT_APPLICATION):
- super(PythonManager, self).__init__(parent)
- drop_shadow = QtGui.QGraphicsDropShadowEffect(self)
- drop_shadow.setBlurRadius(10)
- drop_shadow.setOffset(0, 3)
- drop_shadow.setColor(QtGui.QColor(0, 0, 0, 50))
- self.module_list = ModuleList()
- self.layout = QtGui.QGridLayout(self)
- self.layout.setContentsMargins(0, 0, 0, 0)
- self.layout.setSpacing(0)
- self.layout.setRowMinimumHeight(0, 39)
- self.layout.addWidget(self.module_list, 1, 0)
- self.setLayout(self.layout)
- self.refresh_button = Button('Refresh', self)
- self.refresh_button.clicked.connect(self.module_list.refresh)
- self.reimport_button = Button('Reimport', self)
- self.reimport_button.clicked.connect(self.reimport_button_clicked)
- self.header = QtGui.QLabel('Modified Modules and Packages', self)
- self.header.setObjectName('Header')
- self.header.setGraphicsEffect(drop_shadow)
- self.header.setFixedHeight(40)
- self.setWindowTitle('Python Manager')
- self.setStyleSheet(STYLE)
- def resizeEvent(self, event):
- '''Resize PythonManager UI, reposition buttons and header.'''
- super(PythonManager, self).resizeEvent(event)
- w = self.width()
- h = self.height()
- riw = self.reimport_button.width()
- rih = self.reimport_button.height()
- rfw = self.refresh_button.width()
- self.setMinimumWidth(riw + rfw + 50)
- self.header.setFixedWidth(w)
- self.header.move(0, 0)
- self.reimport_button.move(w - riw - 20, h -rih - 20)
- self.refresh_button.move(w - riw - rfw - 30, h - rih - 20)
- def reimport_button_clicked(self):
- '''Reimport selected items from the ModuleList.'''
- for item in self.module_list.selected():
- w = self.module_list.pop(item)
- reimport.reimport(w.module)
- def main():
- app = QtGui.QApplication(sys.argv)
- pyman = PythonManager()
- pyman.show()
- sys.exit(app.exec_())
- if __name__ == '__main__':
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement