mwxlib 1.0.0__py3-none-any.whl → 1.8.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mwx/__init__.py +6 -4
- mwx/bookshelf.py +144 -68
- mwx/controls.py +444 -378
- mwx/framework.py +567 -546
- mwx/graphman.py +745 -726
- mwx/images.py +16 -0
- mwx/matplot2.py +244 -235
- mwx/matplot2g.py +812 -751
- mwx/matplot2lg.py +218 -209
- mwx/mgplt.py +20 -22
- mwx/nutshell.py +1119 -1015
- mwx/plugins/ffmpeg_view.py +96 -90
- mwx/plugins/fft_view.py +13 -15
- mwx/plugins/frame_listview.py +68 -75
- mwx/plugins/line_profile.py +1 -1
- mwx/py/filling.py +13 -14
- mwx/testsuite.py +38 -0
- mwx/utilus.py +284 -219
- mwx/wxmon.py +43 -44
- mwx/wxpdb.py +83 -84
- mwx/wxwil.py +19 -18
- mwx/wxwit.py +38 -45
- {mwxlib-1.0.0.dist-info → mwxlib-1.8.0.dist-info}/METADATA +12 -5
- mwxlib-1.8.0.dist-info/RECORD +28 -0
- {mwxlib-1.0.0.dist-info → mwxlib-1.8.0.dist-info}/WHEEL +1 -1
- mwxlib-1.0.0.dist-info/LICENSE +0 -21
- mwxlib-1.0.0.dist-info/RECORD +0 -28
- {mwxlib-1.0.0.dist-info → mwxlib-1.8.0.dist-info}/top_level.txt +0 -0
mwx/plugins/frame_listview.py
CHANGED
|
@@ -6,7 +6,7 @@ import wx
|
|
|
6
6
|
from wx import aui
|
|
7
7
|
from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin
|
|
8
8
|
|
|
9
|
-
from mwx.framework import CtrlInterface, Menu, StatusBar
|
|
9
|
+
from mwx.framework import CtrlInterface, Menu, StatusBar, pack
|
|
10
10
|
from mwx.controls import Icon, Clipboard
|
|
11
11
|
from mwx.graphman import Layer
|
|
12
12
|
|
|
@@ -21,23 +21,23 @@ class CheckList(wx.ListCtrl, ListCtrlAutoWidthMixin, CtrlInterface):
|
|
|
21
21
|
@property
|
|
22
22
|
def selected_items(self):
|
|
23
23
|
return filter(self.IsSelected, range(self.ItemCount))
|
|
24
|
-
|
|
24
|
+
|
|
25
25
|
@property
|
|
26
26
|
def checked_items(self):
|
|
27
27
|
return filter(self.IsItemChecked, range(self.ItemCount))
|
|
28
|
-
|
|
28
|
+
|
|
29
29
|
@property
|
|
30
30
|
def focused_item(self):
|
|
31
31
|
return self.FocusedItem
|
|
32
|
-
|
|
32
|
+
|
|
33
33
|
@property
|
|
34
34
|
def all_items(self):
|
|
35
35
|
rows = range(self.ItemCount)
|
|
36
36
|
cols = range(self.ColumnCount)
|
|
37
|
-
|
|
37
|
+
# return [[self.GetItemText(j, k) for k in cols] for j in rows]
|
|
38
38
|
for j in rows:
|
|
39
39
|
yield [self.GetItemText(j, k) for k in cols]
|
|
40
|
-
|
|
40
|
+
|
|
41
41
|
def __init__(self, parent, target, **kwargs):
|
|
42
42
|
wx.ListCtrl.__init__(self, parent, size=(400,130),
|
|
43
43
|
style=wx.LC_REPORT|wx.LC_HRULES, **kwargs)
|
|
@@ -51,8 +51,8 @@ class CheckList(wx.ListCtrl, ListCtrlAutoWidthMixin, CtrlInterface):
|
|
|
51
51
|
|
|
52
52
|
self.__dir = True
|
|
53
53
|
|
|
54
|
-
_alist = (
|
|
55
|
-
("id",
|
|
54
|
+
_alist = ( # assoc-list of column names
|
|
55
|
+
("id", 45),
|
|
56
56
|
("name", 160),
|
|
57
57
|
("shape", 90),
|
|
58
58
|
("dtype", 60),
|
|
@@ -65,16 +65,17 @@ class CheckList(wx.ListCtrl, ListCtrlAutoWidthMixin, CtrlInterface):
|
|
|
65
65
|
|
|
66
66
|
for j, frame in enumerate(self.Target.all_frames):
|
|
67
67
|
self.InsertItem(j, str(j))
|
|
68
|
-
self.UpdateInfo(frame)
|
|
68
|
+
self.UpdateInfo(frame) # update all --> 計算が入ると時間がかかる
|
|
69
69
|
|
|
70
|
-
self.handler.update({
|
|
70
|
+
self.handler.update({ # DNA<frame_listview>
|
|
71
71
|
0 : {
|
|
72
|
-
'Lbutton dblclick' : (0, self.OnShowItems),
|
|
73
|
-
'enter pressed' : (0, self.OnShowItems),
|
|
74
|
-
'delete pressed' : (0, self.OnRemoveItems),
|
|
72
|
+
'Lbutton dblclick' : (0, self.OnShowItems), # -> frame_shown
|
|
73
|
+
'enter pressed' : (0, self.OnShowItems), # -> frame_shown
|
|
74
|
+
'delete pressed' : (0, self.OnRemoveItems), # -> frame_removed/shown
|
|
75
75
|
'C-a pressed' : (0, self.OnSelectAllItems),
|
|
76
|
-
'C-
|
|
77
|
-
'C-
|
|
76
|
+
'C-c pressed' : (0, self.OnCopyInfo),
|
|
77
|
+
'C-l pressed' : (0, self.OnEditLocalUnit),
|
|
78
|
+
'f2 pressed' : (0, self.OnEditAnnotation),
|
|
78
79
|
'M-up pressed' : (0, self.Target.OnPageUp),
|
|
79
80
|
'M-down pressed' : (0, self.Target.OnPageDown),
|
|
80
81
|
},
|
|
@@ -84,21 +85,21 @@ class CheckList(wx.ListCtrl, ListCtrlAutoWidthMixin, CtrlInterface):
|
|
|
84
85
|
self.Bind(wx.EVT_LIST_COL_CLICK, self.OnSortItems)
|
|
85
86
|
self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected)
|
|
86
87
|
|
|
87
|
-
self.context = {
|
|
88
|
+
self.context = { # DNA<GraphPlot>
|
|
88
89
|
None: {
|
|
89
|
-
'frame_shown' : [
|
|
90
|
-
'frame_hidden' : [
|
|
91
|
-
'frame_loaded' : [
|
|
92
|
-
'frame_removed' : [
|
|
93
|
-
'frame_modified' : [
|
|
94
|
-
'frame_updated' : [
|
|
90
|
+
'frame_shown' : [None, self.on_frame_shown],
|
|
91
|
+
'frame_hidden' : [None, self.on_frame_hidden],
|
|
92
|
+
'frame_loaded' : [None, self.on_frame_loaded],
|
|
93
|
+
'frame_removed' : [None, self.on_frames_removed],
|
|
94
|
+
'frame_modified' : [None, self.UpdateInfo],
|
|
95
|
+
'frame_updated' : [None, self.UpdateInfo],
|
|
95
96
|
}
|
|
96
97
|
}
|
|
97
98
|
self.Target.handler.append(self.context)
|
|
98
99
|
|
|
99
100
|
self.menu = [
|
|
100
101
|
(100, "Edit localunit", Icon('image'),
|
|
101
|
-
self.
|
|
102
|
+
self.OnEditLocalUnit,
|
|
102
103
|
lambda v: v.Enable(self.focused_item != -1)),
|
|
103
104
|
|
|
104
105
|
(101, "Edit annotation", Icon('pencil'),
|
|
@@ -111,13 +112,11 @@ class CheckList(wx.ListCtrl, ListCtrlAutoWidthMixin, CtrlInterface):
|
|
|
111
112
|
]
|
|
112
113
|
self.Bind(wx.EVT_CONTEXT_MENU,
|
|
113
114
|
lambda v: Menu.Popup(self, self.menu))
|
|
114
|
-
|
|
115
|
+
|
|
115
116
|
def Destroy(self):
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
return wx.ListCtrl.Destroy(self)
|
|
120
|
-
|
|
117
|
+
self.Target.handler.remove(self.context)
|
|
118
|
+
return wx.ListCtrl.Destroy(self)
|
|
119
|
+
|
|
121
120
|
def UpdateInfo(self, frame):
|
|
122
121
|
ls = ("{}".format(frame.index),
|
|
123
122
|
"{}".format(frame.name),
|
|
@@ -130,113 +129,107 @@ class CheckList(wx.ListCtrl, ListCtrlAutoWidthMixin, CtrlInterface):
|
|
|
130
129
|
j = frame.index
|
|
131
130
|
for k, v in enumerate(ls):
|
|
132
131
|
self.SetItem(j, k, v)
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
132
|
+
self.CheckItem(j, frame.pathname is not None)
|
|
133
|
+
|
|
136
134
|
def OnShowItems(self, evt):
|
|
137
135
|
self.Target.select(self.focused_item)
|
|
138
|
-
|
|
136
|
+
|
|
139
137
|
def OnRemoveItems(self, evt):
|
|
140
138
|
del self.Target[self.selected_items]
|
|
141
|
-
|
|
142
|
-
def OnSortItems(self, evt):
|
|
139
|
+
|
|
140
|
+
def OnSortItems(self, evt): # <wx._controls.ListEvent>
|
|
143
141
|
col = evt.Column
|
|
144
|
-
if col == 0:
|
|
142
|
+
if col == 0: # reverse the first column
|
|
145
143
|
self.__dir = False
|
|
146
|
-
self.__dir = not self.__dir
|
|
144
|
+
self.__dir = not self.__dir # toggle 0:ascend/1:descend
|
|
147
145
|
|
|
148
146
|
frames = self.Target.all_frames
|
|
149
147
|
if frames:
|
|
150
148
|
def _eval(x):
|
|
151
149
|
try:
|
|
152
|
-
return eval(x[col].replace('*', ''))
|
|
150
|
+
return eval(x[col].replace('*', '')) # localunit* とか
|
|
153
151
|
except Exception:
|
|
154
152
|
return x[col]
|
|
155
153
|
frame = self.Target.frame
|
|
156
154
|
items = sorted(self.all_items, reverse=self.__dir, key=_eval)
|
|
157
|
-
frames[:] = [frames[int(c[0])] for c in items]
|
|
155
|
+
frames[:] = [frames[int(c[0])] for c in items] # sort by new Id of items
|
|
158
156
|
|
|
159
157
|
lc = list(self.checked_items)
|
|
160
158
|
|
|
161
159
|
for j, c in enumerate(items):
|
|
162
160
|
self.Select(j, False)
|
|
163
161
|
self.CheckItem(j, int(c[0]) in lc)
|
|
164
|
-
for k, v in enumerate(c[1:]):
|
|
162
|
+
for k, v in enumerate(c[1:]): # update data except for id(0)
|
|
165
163
|
self.SetItem(j, k+1, v)
|
|
166
|
-
self.Target.select(frame)
|
|
167
|
-
|
|
164
|
+
self.Target.select(frame) # invokes [frame_shown] to select the item
|
|
165
|
+
|
|
168
166
|
def OnSelectAllItems(self, evt):
|
|
169
167
|
for j in range(self.ItemCount):
|
|
170
168
|
self.Select(j)
|
|
171
|
-
|
|
172
|
-
def OnLoadItems(self, evt):
|
|
173
|
-
self.parent.parent.load_index(view=self.Target)
|
|
174
|
-
|
|
175
|
-
def OnSaveItems(self, evt):
|
|
176
|
-
selected_frames = [self.Target.all_frames[j] for j in self.selected_items]
|
|
177
|
-
if selected_frames:
|
|
178
|
-
self.parent.message("Exporting {} frames.".format(len(selected_frames)))
|
|
179
|
-
self.parent.parent.save_index(frames=selected_frames)
|
|
180
|
-
else:
|
|
181
|
-
self.parent.message("No frame selected.")
|
|
182
|
-
|
|
169
|
+
|
|
183
170
|
def OnCopyInfo(self, evt):
|
|
184
171
|
selected_frames = [self.Target.all_frames[j] for j in self.selected_items]
|
|
185
172
|
if selected_frames:
|
|
186
|
-
text = ''
|
|
187
|
-
|
|
188
|
-
text += pformat(frame.attributes, sort_dicts=0) # ALL attributes
|
|
189
|
-
## text += '{}\n{}\n'.format(frame.name, frame.annotation)
|
|
173
|
+
text = '\n'.join(pformat(frame.attributes, sort_dicts=0) # ALL attributes
|
|
174
|
+
for frame in selected_frames)
|
|
190
175
|
Clipboard.write(text)
|
|
176
|
+
with wx.Dialog(self,
|
|
177
|
+
title="Frame Properties",
|
|
178
|
+
style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER) as dlg:
|
|
179
|
+
textctrl = wx.TextCtrl(dlg, value=text, style=wx.TE_MULTILINE|wx.TE_READONLY)
|
|
180
|
+
dlg.SetSizer(pack(dlg, [textctrl], style=(1, wx.ALL | wx.EXPAND, 10)))
|
|
181
|
+
dlg.ShowModal()
|
|
191
182
|
else:
|
|
192
183
|
self.parent.message("No frame selected.")
|
|
193
|
-
|
|
194
|
-
def
|
|
184
|
+
|
|
185
|
+
def OnEditLocalUnit(self, evt):
|
|
195
186
|
frame = self.Target.all_frames[self.focused_item]
|
|
196
187
|
with wx.TextEntryDialog(self, frame.name,
|
|
197
188
|
'Enter localunit', repr(frame.localunit)) as dlg:
|
|
198
189
|
if dlg.ShowModal() == wx.ID_OK:
|
|
199
190
|
frame.unit = eval(dlg.Value or 'None')
|
|
200
|
-
|
|
191
|
+
self.SetFocus()
|
|
192
|
+
|
|
201
193
|
def OnEditAnnotation(self, evt):
|
|
202
194
|
frame = self.Target.all_frames[self.focused_item]
|
|
203
195
|
with wx.TextEntryDialog(self, frame.name,
|
|
204
196
|
'Enter an annotation', frame.annotation) as dlg:
|
|
205
197
|
if dlg.ShowModal() == wx.ID_OK:
|
|
206
198
|
frame.annotation = dlg.Value
|
|
207
|
-
|
|
199
|
+
self.SetFocus()
|
|
200
|
+
|
|
208
201
|
def OnItemSelected(self, evt):
|
|
209
202
|
frame = self.Target.all_frames[evt.Index]
|
|
210
203
|
self.parent.message(frame.pathname)
|
|
211
204
|
evt.Skip()
|
|
212
|
-
|
|
205
|
+
|
|
213
206
|
## --------------------------------
|
|
214
|
-
## Actions of frame-handler
|
|
207
|
+
## Actions of frame-handler.
|
|
215
208
|
## --------------------------------
|
|
216
|
-
|
|
209
|
+
|
|
217
210
|
def on_frame_loaded(self, frame):
|
|
218
211
|
j = frame.index
|
|
219
212
|
self.InsertItem(j, str(j))
|
|
220
|
-
for k in range(j+1, self.ItemCount):
|
|
213
|
+
for k in range(j+1, self.ItemCount): # id(0) を更新する
|
|
221
214
|
self.SetItem(k, 0, str(k))
|
|
222
215
|
self.UpdateInfo(frame)
|
|
223
|
-
|
|
216
|
+
|
|
224
217
|
def on_frame_shown(self, frame):
|
|
225
218
|
j = frame.index
|
|
226
219
|
self.SetItemFont(j, self.Font.Bold())
|
|
227
220
|
self.Select(j)
|
|
228
221
|
self.Focus(j)
|
|
229
|
-
|
|
222
|
+
|
|
230
223
|
def on_frame_hidden(self, frame):
|
|
231
224
|
j = frame.index
|
|
232
225
|
self.SetItemFont(j, self.Font)
|
|
233
226
|
self.Select(j, False)
|
|
234
|
-
|
|
227
|
+
|
|
235
228
|
def on_frames_removed(self, indices):
|
|
236
229
|
with wx.FrozenWindow(self):
|
|
237
230
|
for j in reversed(indices):
|
|
238
231
|
self.DeleteItem(j)
|
|
239
|
-
for k in range(self.ItemCount):
|
|
232
|
+
for k in range(self.ItemCount): # id(0) を更新する
|
|
240
233
|
self.SetItem(k, 0, str(k))
|
|
241
234
|
|
|
242
235
|
|
|
@@ -246,15 +239,15 @@ class Plugin(Layer):
|
|
|
246
239
|
menukey = "Plugins/Extensions/&Buffer listbox\tAlt+b"
|
|
247
240
|
caption = "Property list"
|
|
248
241
|
dockable = False
|
|
249
|
-
|
|
242
|
+
|
|
250
243
|
@property
|
|
251
244
|
def all_pages(self):
|
|
252
245
|
return [self.nb.GetPage(i) for i in range(self.nb.PageCount)]
|
|
253
|
-
|
|
246
|
+
|
|
254
247
|
@property
|
|
255
248
|
def message(self):
|
|
256
249
|
return self.statusline
|
|
257
|
-
|
|
250
|
+
|
|
258
251
|
def Init(self):
|
|
259
252
|
self.nb = aui.AuiNotebook(self, size=(400,150),
|
|
260
253
|
style = (aui.AUI_NB_DEFAULT_STYLE|aui.AUI_NB_RIGHT)
|
|
@@ -275,12 +268,12 @@ class Plugin(Layer):
|
|
|
275
268
|
self.parent.select_view(self.nb.CurrentPage.Target)
|
|
276
269
|
evt.Skip()
|
|
277
270
|
self.nb.Bind(wx.EVT_CHILD_FOCUS, on_focus_set)
|
|
278
|
-
|
|
271
|
+
|
|
279
272
|
def attach(self, target, caption):
|
|
280
273
|
if target not in [lc.Target for lc in self.all_pages]:
|
|
281
274
|
lc = CheckList(self, target)
|
|
282
275
|
self.nb.AddPage(lc, caption)
|
|
283
|
-
|
|
276
|
+
|
|
284
277
|
def detach(self, target):
|
|
285
278
|
for k, lc in enumerate(self.all_pages):
|
|
286
279
|
if target is lc.Target:
|
mwx/plugins/line_profile.py
CHANGED
mwx/py/filling.py
CHANGED
|
@@ -3,8 +3,7 @@
|
|
|
3
3
|
the local namespace or any object.
|
|
4
4
|
"""
|
|
5
5
|
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
|
6
|
-
|
|
7
|
-
# Tags: py3-port
|
|
6
|
+
# Modified by Kazuya O'moto <komoto@jeol.co.jp>
|
|
8
7
|
|
|
9
8
|
import wx
|
|
10
9
|
import six
|
|
@@ -18,8 +17,8 @@ import types
|
|
|
18
17
|
import warnings
|
|
19
18
|
|
|
20
19
|
|
|
21
|
-
COMMONTYPES = [getattr(types, t) for t in dir(types)
|
|
22
|
-
if not t.startswith('_')
|
|
20
|
+
COMMONTYPES = [getattr(types, t) for t in dir(types)
|
|
21
|
+
if not t.startswith('_')
|
|
23
22
|
and t not in ('ClassType', 'InstanceType', 'ModuleType')]
|
|
24
23
|
|
|
25
24
|
DOCTYPES = ('BuiltinFunctionType', 'BuiltinMethodType', 'ClassType',
|
|
@@ -27,7 +26,7 @@ DOCTYPES = ('BuiltinFunctionType', 'BuiltinMethodType', 'ClassType',
|
|
|
27
26
|
'LambdaType', 'MethodType', 'ModuleType',
|
|
28
27
|
'UnboundMethodType', 'method-wrapper')
|
|
29
28
|
|
|
30
|
-
SIMPLETYPES = [getattr(types, t) for t in dir(types)
|
|
29
|
+
SIMPLETYPES = [getattr(types, t) for t in dir(types)
|
|
31
30
|
if not t.startswith('_') and t not in DOCTYPES]
|
|
32
31
|
|
|
33
32
|
#del t
|
|
@@ -141,7 +140,7 @@ class FillingTree(wx.TreeCtrl):
|
|
|
141
140
|
def filter(self, obj, key):
|
|
142
141
|
"""Filter function that determines whether the item is displayed."""
|
|
143
142
|
if wx.Platform == '__WXMSW__':
|
|
144
|
-
if key == 'DropTarget':
|
|
143
|
+
if key == 'DropTarget': # Windows bug fix.
|
|
145
144
|
return False
|
|
146
145
|
return True
|
|
147
146
|
|
|
@@ -212,6 +211,7 @@ class FillingTree(wx.TreeCtrl):
|
|
|
212
211
|
def display(self, rooting=True):
|
|
213
212
|
"""Display the current item data.
|
|
214
213
|
Called when an item/branch needs to be updated.
|
|
214
|
+
|
|
215
215
|
Args:
|
|
216
216
|
rooting: True if the current item must be updated
|
|
217
217
|
False otherwise to reduce overheads.
|
|
@@ -219,7 +219,7 @@ class FillingTree(wx.TreeCtrl):
|
|
|
219
219
|
item = self.item
|
|
220
220
|
if not item:
|
|
221
221
|
return
|
|
222
|
-
parent = self.GetItemParent(item)
|
|
222
|
+
parent = self.GetItemParent(item) # Check a parent one above.
|
|
223
223
|
if parent:
|
|
224
224
|
def _roots(item):
|
|
225
225
|
"""Retrace the root of parent/item data.
|
|
@@ -231,8 +231,8 @@ class FillingTree(wx.TreeCtrl):
|
|
|
231
231
|
obj = self.GetItemData(parent)
|
|
232
232
|
key = self.GetItemText(item)
|
|
233
233
|
try:
|
|
234
|
-
# data = self.objGetChildren(obj)[key]
|
|
235
|
-
data = getattr(obj, key)
|
|
234
|
+
# data = self.objGetChildren(obj)[key] # overheads...
|
|
235
|
+
data = getattr(obj, key) # easier way to access here.
|
|
236
236
|
if self.GetItemData(item) is not data:
|
|
237
237
|
self.SetItemData(item, data)
|
|
238
238
|
return item
|
|
@@ -242,15 +242,15 @@ class FillingTree(wx.TreeCtrl):
|
|
|
242
242
|
root = _roots(item)
|
|
243
243
|
if rooting:
|
|
244
244
|
if root and self.IsExpanded(root):
|
|
245
|
-
self.updateChildren(root)
|
|
245
|
+
self.updateChildren(root) # Update roots items.
|
|
246
246
|
if parent != root:
|
|
247
|
-
self.updateChildren(parent)
|
|
247
|
+
self.updateChildren(parent) # Update parent items.
|
|
248
248
|
if self.IsExpanded(item):
|
|
249
|
-
self.updateChildren(item)
|
|
249
|
+
self.updateChildren(item) # Update the current item if necessary.
|
|
250
250
|
self.setText('')
|
|
251
251
|
obj = self.GetItemData(item)
|
|
252
252
|
if wx.Platform == '__WXMSW__':
|
|
253
|
-
if obj is None:
|
|
253
|
+
if obj is None: # Windows bug fix.
|
|
254
254
|
return
|
|
255
255
|
self.SetItemHasChildren(item, self.objHasChildren(obj))
|
|
256
256
|
otype = type(obj)
|
|
@@ -403,7 +403,6 @@ class Filling(wx.SplitterWindow):
|
|
|
403
403
|
config.WriteInt('View/Zoom/Filling', self.text.GetZoom())
|
|
404
404
|
|
|
405
405
|
|
|
406
|
-
|
|
407
406
|
class FillingFrame(wx.Frame):
|
|
408
407
|
"""Frame containing the namespace tree component."""
|
|
409
408
|
|
mwx/testsuite.py
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#! python3
|
|
2
|
+
"""Test suite for App, Frame, and ControlPanel.
|
|
3
|
+
|
|
4
|
+
Get the wx.App or wx.Frame instance and start the main-loop if needed.
|
|
5
|
+
|
|
6
|
+
Usage:
|
|
7
|
+
with testApp() as app:
|
|
8
|
+
frm = wx.Frame(None)
|
|
9
|
+
frm.Show()
|
|
10
|
+
|
|
11
|
+
Is equivalent to:
|
|
12
|
+
app = wx.App()
|
|
13
|
+
frm = wx.Frame(None)
|
|
14
|
+
frm.Show()
|
|
15
|
+
app.MainLoop()
|
|
16
|
+
"""
|
|
17
|
+
from contextlib import contextmanager
|
|
18
|
+
import wx
|
|
19
|
+
|
|
20
|
+
__all__ = ["testApp", "testFrame"]
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@contextmanager
|
|
24
|
+
def testApp():
|
|
25
|
+
app = wx.GetApp() or wx.App()
|
|
26
|
+
yield app
|
|
27
|
+
if not app.GetMainLoop():
|
|
28
|
+
app.MainLoop()
|
|
29
|
+
## wx.App.run = staticmethod(testApp)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@contextmanager
|
|
33
|
+
def testFrame(**kwargs):
|
|
34
|
+
with testApp():
|
|
35
|
+
frm = wx.Frame(None, **kwargs)
|
|
36
|
+
yield frm
|
|
37
|
+
frm.Show()
|
|
38
|
+
## wx.Frame.run = staticmethod(testFrame)
|