Browse files

Added qcommmons that some shortcuts for writing pythonic code conveni…

…ence.
  • Loading branch information...
1 parent 52fef00 commit edb617deb2e8862846ab9b612f765275cc8d3e4d @shuge committed Dec 11, 2011
Showing with 357 additions and 0 deletions.
  1. +23 −0 qcommons/__init__.py
  2. +49 −0 qcommons/qthreadutils.py
  3. +48 −0 qcommons/qutils.py
  4. +237 −0 qcommons/winutils.py
View
23 qcommons/__init__.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+
+from __future__ import generators
+from __future__ import with_statement
+from __future__ import print_function
+
+
+__version__ = "201111"
+__author__ = [
+ "Shuge Lee <shuge.lee@gmail.com>",
+]
+__license__ = "MIT License"
+__contributors__ = "see http://iblah.org/changes"
+
+
+import qutils
+import qthreadutils
+import winutils
+
+
+from qutils import *
+from qthreadutils import *
+from winutils import *
View
49 qcommons/qthreadutils.py
@@ -0,0 +1,49 @@
+import time
+
+try:
+ from PySide import QtCore
+except ImportError:
+ from PyQt4 import QtCore
+
+__all__ = ['kill_qthread', 'QT', 'QTKiller']
+
+
+def kill_qthread(t):
+ if not t:
+ return
+
+ t.terminate()
+# t.wait()
+
+
+class QT(QtCore.QThread):
+ def __init__(self, func, *args, **kwargs):
+ QtCore.QThread.__init__(self)
+ self._func = func
+ self._args = args
+ self._kwargs = kwargs
+ self._return = None
+
+ def run(self):
+ self._return = self._func(*self._args, **self._kwargs)
+ self.emit(QtCore.SIGNAL('thread_finished()'))
+
+ def get_return(self):
+ return self._return
+
+
+class QTKiller(QtCore.QThread):
+ def __init__(self, target_t, timeout = 10):
+ QtCore.QThread.__init__(self)
+ self._target_t = target_t
+ self._timeout = timeout
+
+ def run(self):
+ i = 0
+ while i < self._timeout:
+ time.sleep(1)
+ self.emit(QtCore.SIGNAL('thread_running()'))
+ i += 1
+ self.emit(QtCore.SIGNAL('kill_qthread()'))
+ while not self._target_t.isFinished():
+ time.sleep(0.1)
View
48 qcommons/qutils.py
@@ -0,0 +1,48 @@
+"""
+add custom theme name and search path for fix icon file not found on Mac OS X
+
+Install Oxygen icon on Mac OS X via MacPorts:
+
+ sudo port install oxygen-icons
+
+"""
+import sys
+
+try:
+ from PySide import QtGui
+ from PySide import QtCore
+except ImportError:
+ from PyQt4 import QtGui
+ from PyQt4 import QtCore
+
+
+__all__ = [
+ "config_theme_path",
+ "icon2pix",
+]
+
+
+def config_theme_path():
+ if sys.platform != "darwin":
+ return
+
+ theme_name = str(QtGui.QIcon.themeName())
+
+ if theme_name != "Oxygen":
+ QtGui.QIcon.setThemeName("Oxygen")
+
+
+ search_paths = list(QtGui.QIcon.themeSearchPaths())
+
+ custom_path = "/opt/local/share/icons"
+ if custom_path not in search_paths:
+ search_paths.append(custom_path)
+
+ QtGui.QIcon.setThemeSearchPaths(search_paths)
+
+
+def icon2pix(icon, size = QtCore.QSize(30, 30), grayscaled = True):
+ if grayscaled:
+ return icon.pixmap(size, mode = QtGui.QIcon.Disabled)
+ else:
+ return icon.pixmap(size)
View
237 qcommons/winutils.py
@@ -0,0 +1,237 @@
+#!/usr/bin/env python
+"""
+auto save window geometry
+
+Test environment:
+ Mac OS X 10.6.8
+
+http://doc.qt.nokia.com/latest/qdesktopwidget.html
+http://www.pyside.org/docs/pyside/PySide/QtGui/QWidget.html
+"""
+import json
+import os
+
+try:
+ from PySide import QtCore
+ from PySide import QtGui
+except ImportError:
+ from PyQt4 import QtCore
+ from PyQt4 import QtGui
+
+
+__all__ = [
+ "AutoSaveGeo",
+ "CustomDlg",
+ "CustomWin",
+ ]
+
+
+class AutoSaveGeo(QtGui.QMainWindow):
+ def __init__(self, user_data_path, w = 300, h = 500, parent = None):
+ super(AutoSaveGeo, self).__init__(parent)
+
+ self.resize(w, h)
+
+ self.user_data_path = user_data_path
+ if self.user_data_path:
+ self._load_win_geo()
+
+ def closeEvent(self, evt):
+ if hasattr(self, "user_data_path") and self.user_data_path:
+ self._save_win_geo()
+
+ return super(AutoSaveGeo, self).closeEvent(evt)
+
+ def _save_win_geo(self):
+ config_path = os.path.join(self.user_data_path, "win_geometry.json")
+
+ if not os.path.exists(self.user_data_path):
+ os.makedirs(self.user_data_path)
+
+ if os.path.exists(config_path):
+ f = file(config_path)
+ buf = f.read()
+ f.close()
+ else:
+ buf = None
+
+ datas = None
+ if buf:
+ datas = json.loads(buf)
+
+ if not datas:
+ datas = {}
+
+ win_geo_data = dict(
+ x = self.x(),
+ y = self.y(),
+ w = self.width(),
+ h = self.height())
+
+ datas[self.__class__.__name__] = win_geo_data
+
+ path = config_path
+ content = json.dumps(datas)
+
+ f = file(path, "w")
+ f.write(content)
+ f.close()
+
+ def _load_win_geo(self):
+ config_path = os.path.join(self.user_data_path, "win_geometry.json")
+
+ if not os.path.exists(self.user_data_path):
+ os.makedirs(self.user_data_path)
+
+ desktop = QtGui.QApplication.desktop()
+ x = desktop.width() / 2
+ y = (desktop.height() - self.height()) / 2
+ w = self.width()
+ h = self.height()
+
+ if os.path.exists(config_path):
+ f = file(config_path)
+ buf = f.read()
+ f.close()
+ else:
+ buf = None
+
+ datas = None
+ if buf:
+ datas = json.loads(buf)
+
+ if datas:
+ cls_name = self.__class__.__name__
+ geo = datas.get(cls_name)
+
+ if geo:
+ x, y, w, h = geo['x'], geo['y'], geo['w'], geo['h']
+
+ self.setGeometry(x, y, w, h)
+
+
+class CustomDlg(QtGui.QDialog):
+ """
+ Custom dialog template.
+
+ You should override there method:
+ - __init__
+ - get_inputs
+ - popup_and_get_inputs
+ """
+ def __init__(self, parent, settings):
+ """ You should override this method """
+ super(CustomDlg, self).__init__(parent)
+
+ self.resize(400, 250)
+
+ self._settings = settings
+
+ # add custom sub-widgets here ...
+
+ def show_and_raise(self):
+ self.show()
+ self.raise_()
+
+ def keyPressEvent(self, evt):
+ close_win_cmd_w = (evt.key() == QtCore.Qt.Key_W and evt.modifiers() == QtCore.Qt.ControlModifier)
+ close_win_esc = (evt.key() == QtCore.Qt.Key_Escape)
+
+ if close_win_cmd_w or close_win_esc:
+ self.close()
+ return self._settings
+
+ def get_inputs(self):
+ """ You should override this method
+ update self._settings from custom sub-widgets ...
+ """
+ return self._settings
+
+ @staticmethod
+ def popup_and_get_inputs(parent, settings):
+ """ You should override this method """
+ dlg = CustomDlg(parent, settings)
+ dlg.show()
+ dlg.exec_()
+
+ return dlg.get_inputs()
+
+
+class CustomWin(QtGui.QWidget):
+ """
+ Custom window template.
+
+ You should override there method:
+ - __init__
+ - get_inputs
+ - popup_and_get_inputs
+ """
+ def __init__(self, parent, settings):
+ """ You should override this method """
+ super(CustomWin, self).__init__(parent)
+
+ self.resize(400, 250)
+
+ self._settings = settings
+
+ # add custom sub-widgets here ...
+
+ def show_and_raise(self):
+ self.show()
+ self.raise_()
+
+ def keyPressEvent(self, evt):
+ close_win_cmd_w = (evt.key() == QtCore.Qt.Key_W and evt.modifiers() == QtCore.Qt.ControlModifier)
+ close_win_esc = (evt.key() == QtCore.Qt.Key_Escape)
+
+ if close_win_cmd_w or close_win_esc:
+ self.close()
+ return self._settings
+
+ def get_inputs(self):
+ """ You should override this method
+ update self._settings from custom sub-widgets ...
+ """
+ return self._settings
+
+ @staticmethod
+ def popup_and_get_inputs(parent, settings):
+ """ You should override this method """
+ dlg = CustomWin(parent, settings)
+ dlg.show()
+
+ return dlg.get_inputs()
+
+
+class Demo(AutoSaveGeo):
+ def __init__(self, parent = None, user_data_path = None):
+ super(Demo, self).__init__(parent = parent, user_data_path = user_data_path)
+
+ settings = {}
+ new_settings = CustomDlg.popup_and_get_inputs(parent = self, settings = settings)
+ print "new_settings:", new_settings
+
+ def show_and_raise(self):
+ self.show()
+ self.raise_()
+
+def test1():
+ import sys
+
+ app_name = "foo"
+ #tmp_path = os.getenv("TMP") or "/tmp"
+ PWD = os.path.dirname(os.path.realpath(__file__))
+ tmp_path = PWD
+ app_data_path = os.path.join(tmp_path, app_name)
+
+
+ app = QtGui.QApplication(sys.argv)
+
+ demo = Demo(user_data_path = app_data_path)
+ demo.show_and_raise()
+
+ sys.exit(app.exec_())
+
+
+if __name__ == "__main__":
+ test1()

0 comments on commit edb617d

Please sign in to comment.