Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added qcommmons that some shortcuts for writing pythonic code conveni…
…ence.
- Loading branch information
Shuge Lee
committed
Dec 11, 2011
1 parent
52fef00
commit edb617d
Showing
4 changed files
with
357 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 * |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() |