1
# -*- coding: utf-8 -*-
3
# Copyright © 2009-2010 Pierre Raybaut
4
# Licensed under the terms of the MIT License
5
# (see spyderlib/__init__.py for details)
8
Object Editor Dialog based on Qt
11
from spyderlib.qt.QtCore import QObject, SIGNAL
14
class DialogKeeper(QObject):
16
QObject.__init__(self)
20
def set_namespace(self, namespace):
21
self.namespace = namespace
23
def create_dialog(self, dialog, refname, func):
24
self.dialogs[id(dialog)] = dialog, refname, func
25
self.connect(dialog, SIGNAL('accepted()'),
26
lambda eid=id(dialog): self.editor_accepted(eid))
27
self.connect(dialog, SIGNAL('rejected()'),
28
lambda eid=id(dialog): self.editor_rejected(eid))
30
dialog.activateWindow()
33
def editor_accepted(self, dialog_id):
34
dialog, refname, func = self.dialogs[dialog_id]
35
self.namespace[refname] = func(dialog)
36
self.dialogs.pop(dialog_id)
38
def editor_rejected(self, dialog_id):
39
self.dialogs.pop(dialog_id)
41
keeper = DialogKeeper()
44
def create_dialog(obj, obj_name):
45
"""Creates the editor dialog and returns a tuple (dialog, func) where func
46
is the function to be called with the dialog instance as argument, after
47
quitting the dialog box
49
The role of this intermediate function is to allow easy monkey-patching.
50
(uschmitt suggested this indirection here so that he can monkey patch
51
oedit to show eMZed related data)
54
from spyderlib.widgets.texteditor import TextEditor
55
from spyderlib.widgets.dicteditorutils import (ndarray, FakeObject,
57
from spyderlib.widgets.dicteditor import DictEditor
58
from spyderlib.widgets.arrayeditor import ArrayEditor
60
conv_func = lambda data: data
61
readonly = not is_known_type(obj)
62
if isinstance(obj, ndarray) and ndarray is not FakeObject:
63
dialog = ArrayEditor()
64
if not dialog.setup_and_check(obj, title=obj_name,
67
elif isinstance(obj, Image) and Image is not FakeObject \
68
and ndarray is not FakeObject:
69
dialog = ArrayEditor()
72
if not dialog.setup_and_check(data, title=obj_name,
75
from spyderlib.pil_patch import Image
76
conv_func = lambda data: Image.fromarray(data, mode=obj.mode)
77
elif isinstance(obj, (str, unicode)):
78
dialog = TextEditor(obj, title=obj_name, readonly=readonly)
81
dialog.setup(obj, title=obj_name, readonly=readonly)
84
return conv_func(dialog.get_value())
86
return dialog, end_func
89
def oedit(obj, modal=True, namespace=None):
90
"""Edit the object 'obj' in a GUI-based editor and return the edited copy
91
(if Cancel is pressed, return None)
93
The object 'obj' is a container
95
Supported container types:
96
dict, list, tuple, str/unicode or numpy.array
98
(instantiate a new QApplication if necessary,
99
so it can be called directly from the interpreter)
102
from spyderlib.utils.qthelpers import qapplication
108
assert isinstance(obj, basestring)
110
if namespace is None:
111
namespace = globals()
112
keeper.set_namespace(namespace)
113
obj = namespace[obj_name]
114
# keep QApplication reference alive in the Python interpreter:
115
namespace['__qapp__'] = app
117
result = create_dialog(obj, obj_name)
120
dialog, end_func = result
124
return end_func(dialog)
126
keeper.create_dialog(dialog, obj_name, end_func)
128
qt_inputhook = os.environ.get("INSTALL_QT_INPUTHOOK",
129
"").lower() == "true"
130
if os.name == 'nt' and not qt_inputhook:
135
"""Run object editor test"""
136
import datetime, numpy as np
137
from spyderlib.pil_patch import Image
138
image = Image.fromarray(np.random.random_integers(255, size=(100, 100)))
139
example = {'str': 'kjkj kj k j j kj k jkj',
140
'list': [1, 3, 4, 'kjkj', None],
141
'dict': {'d': 1, 'a': np.random.rand(10, 10), 'b': [1, 2]},
143
'array': np.random.rand(10, 10),
145
'date': datetime.date(1945, 5, 8),
146
'datetime': datetime.datetime(1945, 5, 8),
149
class Foobar(object):
155
print oedit(np.random.rand(10, 10))
156
print oedit(oedit.__doc__)
159
if __name__ == "__main__":
1
# -*- coding: utf-8 -*-
3
# Copyright © 2009-2010 Pierre Raybaut
4
# Licensed under the terms of the MIT License
5
# (see spyderlib/__init__.py for details)
8
Object Editor Dialog based on Qt
11
from spyderlib.qt.QtCore import QObject, SIGNAL
14
class DialogKeeper(QObject):
16
QObject.__init__(self)
20
def set_namespace(self, namespace):
21
self.namespace = namespace
23
def create_dialog(self, dialog, refname, func):
24
self.dialogs[id(dialog)] = dialog, refname, func
25
self.connect(dialog, SIGNAL('accepted()'),
26
lambda eid=id(dialog): self.editor_accepted(eid))
27
self.connect(dialog, SIGNAL('rejected()'),
28
lambda eid=id(dialog): self.editor_rejected(eid))
30
dialog.activateWindow()
33
def editor_accepted(self, dialog_id):
34
dialog, refname, func = self.dialogs[dialog_id]
35
self.namespace[refname] = func(dialog)
36
self.dialogs.pop(dialog_id)
38
def editor_rejected(self, dialog_id):
39
self.dialogs.pop(dialog_id)
41
keeper = DialogKeeper()
44
def create_dialog(obj, obj_name):
45
"""Creates the editor dialog and returns a tuple (dialog, func) where func
46
is the function to be called with the dialog instance as argument, after
47
quitting the dialog box
49
The role of this intermediate function is to allow easy monkey-patching.
50
(uschmitt suggested this indirection here so that he can monkey patch
51
oedit to show eMZed related data)
54
from spyderlib.widgets.texteditor import TextEditor
55
from spyderlib.widgets.dicteditorutils import (ndarray, FakeObject,
57
from spyderlib.widgets.dicteditor import DictEditor
58
from spyderlib.widgets.arrayeditor import ArrayEditor
60
conv_func = lambda data: data
61
readonly = not is_known_type(obj)
62
if isinstance(obj, ndarray) and ndarray is not FakeObject:
63
dialog = ArrayEditor()
64
if not dialog.setup_and_check(obj, title=obj_name,
67
elif isinstance(obj, Image) and Image is not FakeObject \
68
and ndarray is not FakeObject:
69
dialog = ArrayEditor()
72
if not dialog.setup_and_check(data, title=obj_name,
75
from spyderlib.pil_patch import Image
76
conv_func = lambda data: Image.fromarray(data, mode=obj.mode)
77
elif isinstance(obj, (str, unicode)):
78
dialog = TextEditor(obj, title=obj_name, readonly=readonly)
81
dialog.setup(obj, title=obj_name, readonly=readonly)
84
return conv_func(dialog.get_value())
86
return dialog, end_func
89
def oedit(obj, modal=True, namespace=None):
90
"""Edit the object 'obj' in a GUI-based editor and return the edited copy
91
(if Cancel is pressed, return None)
93
The object 'obj' is a container
95
Supported container types:
96
dict, list, tuple, str/unicode or numpy.array
98
(instantiate a new QApplication if necessary,
99
so it can be called directly from the interpreter)
102
from spyderlib.utils.qthelpers import qapplication
108
assert isinstance(obj, basestring)
110
if namespace is None:
111
namespace = globals()
112
keeper.set_namespace(namespace)
113
obj = namespace[obj_name]
114
# keep QApplication reference alive in the Python interpreter:
115
namespace['__qapp__'] = app
117
result = create_dialog(obj, obj_name)
120
dialog, end_func = result
124
return end_func(dialog)
126
keeper.create_dialog(dialog, obj_name, end_func)
128
qt_inputhook = os.environ.get("INSTALL_QT_INPUTHOOK",
129
"").lower() == "true"
130
if os.name == 'nt' and not qt_inputhook:
135
"""Run object editor test"""
136
import datetime, numpy as np
137
from spyderlib.pil_patch import Image
138
image = Image.fromarray(np.random.random_integers(255, size=(100, 100)))
139
example = {'str': 'kjkj kj k j j kj k jkj',
140
'list': [1, 3, 4, 'kjkj', None],
141
'dict': {'d': 1, 'a': np.random.rand(10, 10), 'b': [1, 2]},
143
'array': np.random.rand(10, 10),
145
'date': datetime.date(1945, 5, 8),
146
'datetime': datetime.datetime(1945, 5, 8),
149
class Foobar(object):
155
print oedit(np.random.rand(10, 10))
156
print oedit(oedit.__doc__)
159
if __name__ == "__main__":