Skip to content

Commit

Permalink
Added qcommmons that some shortcuts for writing pythonic code conveni…
Browse files Browse the repository at this point in the history
…ence.
  • Loading branch information
Shuge Lee committed Dec 11, 2011
1 parent 52fef00 commit edb617d
Show file tree
Hide file tree
Showing 4 changed files with 357 additions and 0 deletions.
23 changes: 23 additions & 0 deletions 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 *
49 changes: 49 additions & 0 deletions 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)
48 changes: 48 additions & 0 deletions 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)
237 changes: 237 additions & 0 deletions 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.