diff --git a/imagepy/app/imagepy.py b/imagepy/app/imagepy.py index d5662a0a..042b77f3 100644 --- a/imagepy/app/imagepy.py +++ b/imagepy/app/imagepy.py @@ -2,7 +2,7 @@ import time, threading sys.path.append('../../../') import wx.lib.agw.aui as aui -from sciwx.widgets import MenuBar, ToolBar, ChoiceBook, ParaDialog, WorkFlowPanel, ProgressBar +from sciwx.widgets import MenuBar, RibbonBar, ToolBar, ChoiceBook, ParaDialog, WorkFlowPanel, ProgressBar from sciwx.canvas import CanvasNoteBook from sciwx.grid import GridNoteBook from sciwx.mesh import Canvas3DNoteBook @@ -147,6 +147,8 @@ def load_widget(self, data): def init_menu(self): self.menubar = MenuBar(self) + # self.menubar = RibbonBar(self) + # self.auimgr.AddPane( self.menubar, aui.AuiPaneInfo() .CaptionVisible(False) .Top() .PinButton( True ).Dock().Resizable().MinSize(wx.Size(1000, 130)).FloatingSize( wx.DefaultSize ).Layer(5) ) def init_tool(self): sizer = wx.BoxSizer(wx.VERTICAL) diff --git a/imagepy/app/loader.py b/imagepy/app/loader.py index 99a34a2e..1a411e18 100644 --- a/imagepy/app/loader.py +++ b/imagepy/app/loader.py @@ -6,7 +6,7 @@ """ import os, sys, os.path as osp from glob import glob -from sciapp.action import Macros, Widget#, Report +from sciapp.action import Macros, Widget, Report from .. import root_dir from .manager import DocumentManager, DictManager from codecs import open @@ -23,9 +23,9 @@ def extend_plugins(path, lst, err): rst = [] for i in lst: if isinstance(i, tuple) or i=='-': rst.append(i) - elif i[-3:] == 'rpt': pass - #pt = os.path.join(root_dir,path) - #rst.append(Report(i[:-4], pt+'/'+i)) + elif i[-3:] == 'rpt': + pt = os.path.join(root_dir,path) + rst.append(Report(i[:-4], pt+'/'+i)) elif i[-3:] in {'.md', '.mc', '.wf'}: p = os.path.join(os.path.join(root_dir, path), i).replace('\\','/') rst.append(Macros(i[:-3], ['Open>{"path":"%s"}'%p])) diff --git a/imagepy/data/config.json b/imagepy/data/config.json index fe7b9a33..b7722ba7 100644 --- a/imagepy/data/config.json +++ b/imagepy/data/config.json @@ -1 +1 @@ -[["uistyle", "imagepy", null], ["mea_style", {"color": [0, 0, 255], "fcolor": [255, 255, 255], "fill": false, "lw": 2, "tcolor": [0, 255, 0], "size": 12}, null], ["mark_style", {"color": [0, 255, 0], "fcolor": [255, 255, 255], "fill": false, "lw": 1, "tcolor": [255, 0, 0], "size": 8}, null], ["recent", ["C:/Users/54631/Desktop/\u6d77\u51b0\u62a5\u4ef7/testmacros.mc", "C:\\Users\\Administrator\\Downloads\\\u7d20\u6750\u2014\u8f66\u5934\\\u6d4b\u8bd5-JK1-\u52ff\u5220\\20170201\\In-20170201151126911-\u6842J73220-\u9ec4-qj-1.jpg", "C:/Users/Administrator/Desktop/imagepy/imagepy/plugins/demoplugin/menus/Demos/Macros Demo/Macros Gaussian Invert.mc", "DEM.mc"], null], ["roi_style", {"color": [255, 255, 0], "fcolor": [255, 255, 255], "fill": false, "lw": 1, "tcolor": [255, 255, 0], "size": 8}, null], ["language", "English", null]] \ No newline at end of file +[["language", "English", null], ["roi_style", {"color": [255, 255, 0], "fcolor": [255, 255, 255], "fill": false, "lw": 1, "tcolor": [255, 255, 0], "size": 8}, null], ["recent", ["C:/Users/54631/Desktop/\u6d77\u51b0\u62a5\u4ef7/testmacros.mc", "C:\\Users\\Administrator\\Downloads\\\u7d20\u6750\u2014\u8f66\u5934\\\u6d4b\u8bd5-JK1-\u52ff\u5220\\20170201\\In-20170201151126911-\u6842J73220-\u9ec4-qj-1.jpg", "C:/Users/Administrator/Desktop/imagepy/imagepy/plugins/demoplugin/menus/Demos/Macros Demo/Macros Gaussian Invert.mc", "DEM.mc"], null], ["mark_style", {"color": [0, 255, 0], "fcolor": [255, 255, 255], "fill": false, "lw": 1, "tcolor": [255, 0, 0], "size": 8}, null], ["mea_style", {"color": [0, 0, 255], "fcolor": [255, 255, 255], "fill": false, "lw": 2, "tcolor": [0, 255, 0], "size": 12}, null], ["uistyle", "imagepy", null]] \ No newline at end of file diff --git a/imagepy/menus/Analysis/statistic_plg.py b/imagepy/menus/Analysis/statistic_plg.py index ee3d041a..0cc1d79c 100644 --- a/imagepy/menus/Analysis/statistic_plg.py +++ b/imagepy/menus/Analysis/statistic_plg.py @@ -96,7 +96,7 @@ def run(self, ips, imgs, para = None): img = imgs[i] if msk is None else imgs[i][msk] maxv = img.max() if maxv==0:continue - ct = np.histogram(img, maxv, [1,maxv+1])[0] + ct = np.histogram(img, maxv+1, [0,maxv])[0] titles = ['slice','value','count'] dt = [[i]*len(ct), list(range(maxv+1)), ct] if not para['slice']: diff --git a/imagepy/menus/File/new_plg.py b/imagepy/menus/File/new_plg.py index 50c8b99d..bd543927 100644 --- a/imagepy/menus/File/new_plg.py +++ b/imagepy/menus/File/new_plg.py @@ -8,7 +8,7 @@ import numpy as np class Plugin(Free): - title = 'New Image' + title = 'New' para = {'name':'Undefined','width':300, 'height':300, 'type':'8-bit','slice':1} view = [(str, 'name', 'name', ''), (int, 'width', (1,10240), 0, 'width', 'pix'), diff --git a/imagepy/menus/Plugins/Coins Report.rpt b/imagepy/menus/Plugins/Coins Report.rpt new file mode 100644 index 00000000..3dc3d615 Binary files /dev/null and b/imagepy/menus/Plugins/Coins Report.rpt differ diff --git a/imagepy/menus/Process/Threshold/threshold_plgs.py b/imagepy/menus/Process/Threshold/threshold_plgs.py index 2d46189a..063487ea 100644 --- a/imagepy/menus/Process/Threshold/threshold_plgs.py +++ b/imagepy/menus/Process/Threshold/threshold_plgs.py @@ -81,7 +81,7 @@ class Niblack(Filter): (float, 'k', (0, 1), 2, 'offset', '')] def run(self, ips, snap, img, para = None): - if para['size']%2==0: return IPy.alert('size must be Odd') + if para['size']%2==0: return self.app.alert('size must be Odd') img[:] = (snap>threshold_niblack(snap, para['size'], para['k']))*ips.range[1] class Sauvola(Filter): @@ -92,7 +92,7 @@ class Sauvola(Filter): (float, 'k', (0, 1), 2, 'offset', '')] def run(self, ips, snap, img, para = None): - if para['size']%2==0: return IPy.alert('size must be Odd') + if para['size']%2==0: return self.app.alert('size must be Odd') img[:] = (snap>threshold_sauvola(snap, para['size'], para['k']))*ips.range[1] plgs = [SimpleThreshold, Auto, '-', Local, Niblack, Sauvola, '-', Hysteresis] \ No newline at end of file diff --git a/sciapp/action/__init__.py b/sciapp/action/__init__.py index 3faee3d4..bf720152 100644 --- a/sciapp/action/__init__.py +++ b/sciapp/action/__init__.py @@ -4,4 +4,4 @@ from .plugin.mea_tools import * from .plugin.shp_tools import * from .plugin.roi_tools import * -from .advanced import Filter, Free, Simple, Table, Macros, Widget, dataio \ No newline at end of file +from .advanced import Filter, Free, Simple, Table, Macros, Widget, dataio, Report \ No newline at end of file diff --git a/sciapp/action/advanced/__init__.py b/sciapp/action/advanced/__init__.py index 1ad42725..8ee8c376 100644 --- a/sciapp/action/advanced/__init__.py +++ b/sciapp/action/advanced/__init__.py @@ -3,4 +3,5 @@ from .table import Table from .free import Free from .macros import Macros -from .widget import Widget \ No newline at end of file +from .widget import Widget +from .report import Report \ No newline at end of file diff --git a/sciapp/action/advanced/report.py b/sciapp/action/advanced/report.py new file mode 100644 index 00000000..a42922bd --- /dev/null +++ b/sciapp/action/advanced/report.py @@ -0,0 +1,66 @@ +# -*- coding: utf-8 -*- +""" +Created on Thu Dec 29 01:48:23 2016 +@author: yxl +""" +import wx +from sciapp import app +from sciapp.action.advanced.dataio import ReaderManager +# from imagepy.core.manager import ReaderManager, ViewerManager +from sciwx.widgets.propertygrid import GridDialog +from sciapp.util import xlreport +from time import time +import openpyxl as pyxl + +class Report: + def __init__(self, title, cont): + self.title = title + self.cont = cont + + def __call__(self): return self + + def runasyn(self, wb, info, key, para = None, callback = None): + self.app.add_task(self) + for i in para: + if i in key and key[i][0] == 'img': + ips = self.app.get_img(para[i]) + para[i] = ips if ips is None else ips.img + + if i in key and key[i][0] == 'tab': + tps = self.app.get_table(para[i]) + para[i] = tps if tps is None else tps.data + + start = time() + xlreport.fill_value(wb, info, para) + wb.save(para['path']) + self.app.info('%s: cost %.3fs'%(self.title, time()-start)) + self.app.remove_task(self) + if callback!=None:callback() + + def start(self, app, para=None, callafter=None): + self.app = app + wb = pyxl.load_workbook(self.cont) + xlreport.repair(wb) + info, key = xlreport.parse(wb) + + if para is not None: + return self.runasyn(wb, info, para, callafter) + dialog = GridDialog(self.app, self.title, info, key) + rst = dialog.ShowModal() + para = dialog.GetValue() + + dialog.Destroy() + if rst != 5100: return + filt = ['XLSX', 'xlsx', 'xlsx'] + path = self.app.get_path('Save..', filt, 'save') + if not path: return + para['path'] = path + self.app.record_macros('{}>{}'.format(self.title, para)) + self.runasyn(wb, info, key, para, callafter) + +def show_rpt(data, title): + wx.CallAfter(Report(title, data).start) + +# ViewerManager.add('rpt', show_rpt) +def read_rpt(path): return path +ReaderManager.add('rpt', read_rpt, tag='rpt') \ No newline at end of file diff --git a/sciapp/app.py b/sciapp/app.py index ad974f2e..afb3627b 100644 --- a/sciapp/app.py +++ b/sciapp/app.py @@ -6,7 +6,7 @@ def __init__(self, asyn=True): self.asyn = asyn self.managers = {} self.img_manager = self.manager('img') - #self.wimg_manager = self.manager('wimg') + self.wimg_manager = self.manager('wimg') self.tab_manager = self.manager('tab') #self.wtab_manager = self.manager('wtab') self.mesh_manager = self.manager('mesh') @@ -40,6 +40,9 @@ def show_img(self, img, name): self.img_manager.add(img.name, img) print(img.info) + def add_img_win(self, win, name): + self.wimg_manager.add(name, win) + def close_img(self, name): self.img_manager.remove(name) print('close image:', name) diff --git a/sciapp/util/xlreport.py b/sciapp/util/xlreport.py new file mode 100644 index 00000000..18b3931c --- /dev/null +++ b/sciapp/util/xlreport.py @@ -0,0 +1,116 @@ +import openpyxl as pyxl +from openpyxl.utils.units import cm_to_EMU, EMU_to_pixels +from io import BytesIO +from openpyxl.drawing.image import Image +from PIL import Image as PImage +import numpy as np +import pandas as pd +from copy import copy + +if not '.rpt' in pyxl.reader.excel.SUPPORTED_FORMATS: + pyxl.reader.excel.SUPPORTED_FORMATS += ('.rpt',) + +def parse(wb): + rst, key = [], {} + for ws in wb.worksheets: + rst.append((ws.title, [])) + for row in ws.rows: + for cell in row: + if not isinstance(cell.value, str):continue + if cell.value[0]+cell.value[-1] != '{}': continue + cont = cell.value[1:-1].strip() + tp = cont.split(' ')[0] + cont = cont[len(tp):].strip() + note, value = 'no description', None + if '#' in cont: + note = cont.split('#')[-1].strip() + cont = cont[:cont.index('#')].strip() + if '=' in cont: + value = cont.split('=')[1].strip() + name = cont[:cont.index('=')].strip() + else: name = cont + + rst[-1][-1].append(((cell.row, cell.col_idx), + [tp, name, value, note])) + key[name] = [tp, name, value, note] + return rst, key + +def trans(img, W, H, margin, scale): + h, w = img.shape[:2] + h2, w2 = int(h/margin), int(w/margin) + if scale: + if W/H > w/h: w2 = int(W/H*h2) + if H/W > h/w: h2 = int(H/W*w2) + newshp = (h2, w2) if img.ndim==2 else (h2, w2, 3) + blank = np.ones(newshp, dtype=np.uint8) * 255 + blank[(h2-h)//2:(h2-h)//2+h, (w2-w)//2:(w2-w)//2+w] = img + return blank + +def add_image(wb, ws, pos, key, img): + if img is None: return + w, h, margin, scale = eval(key[2]) + img = trans(img, w, h, margin, scale==0) + img = PImage.fromarray(img) + image_file = BytesIO() + img.save(image_file, 'png') + ref = BytesIO(image_file.getvalue()) + image = Image(img) + image.ref = ref + image.height = EMU_to_pixels(cm_to_EMU(h)) + image.width = EMU_to_pixels(cm_to_EMU(w)) + wb[ws].add_image(image, wb[ws].cell(*pos).coordinate) + +def add_table(wb, ws, pos, key, data): + if data is None: return + vs = data.values + idx, cols = data.index, data.columns + dr, dc, ir, ic = 1, 1, 0, 0 + if key[2] != None: dr, dc, ir, ic = eval(key[2]) + for r in range(vs.shape[0]): + if ir!=0: wb[ws].cell(pos[0]+r*dr, pos[1]+ir, idx[r]) + for c in range(vs.shape[1]): + if ic!=0: wb[ws].cell(pos[0]+ic, pos[1]+c*dc, cols[c]) + for r in range(vs.shape[0]): + for c in range(vs.shape[1]): + wb[ws].cell(pos[0]+r*dr, pos[1]+c*dc, vs[r,c]) + +def fill_value(wb, infos, para): + for worksheet in infos: + ws, info = worksheet + for pos, key in info: + if not key[1] in para: continue + if key[0] in ('str', 'int', 'float', 'bool', 'txt', 'list', 'date'): + wb[ws].cell(pos[0], pos[1], para[key[1]]) + if key[0] == 'img': + add_image(wb, ws, pos, key, para[key[1]]) + if key[0] == 'tab': + add_table(wb, ws, pos, key, para[key[1]]) + +def repair(wb): + for ws in wb.worksheets: + for cr in ws.merged_cells: + ltc = ws.cell(cr.min_row, cr.min_col) + vb, hb = ltc.border.left, ltc.border.top + for r in range(cr.min_row, cr.max_row+1): + for c in range(cr.min_col, cr.max_col+1): + cur = copy(ws.cell(r, c).border) + cur.left, cur.right = copy(vb), copy(vb) + cur.top, cur.bottom = copy(hb), copy(hb) + ws.cell(r, c).border = cur + +if __name__ == '__main__': + rst = pd.read_csv('rst.csv') + img = np.arange(10000, dtype=np.uint8).reshape((100,100)) + data = {'Sample_ID':'Coins-0001', 'Operator_Name':'YX Dragon', 'Date':'2019-02-05', + 'Record':rst, 'Original_Image':img, 'Mask_Image':img} + + wb = pyxl.load_workbook('Coins Report.xlsx',) + repair(wb) + ws = wb.active + + + infos = parse(wb) + print(infos) + fill_value(wb, infos, data) + wb.save('new.xlsx') + diff --git a/sciwx/canvas/canvas.py b/sciwx/canvas/canvas.py index ba31e383..2235f269 100644 --- a/sciwx/canvas/canvas.py +++ b/sciwx/canvas/canvas.py @@ -190,7 +190,7 @@ def move(self, dx, dy, coord='win'): self.update() def on_size(self, event): - if max(self.GetClientSize())>20: + if max(self.GetClientSize())>20 and self.images[0].img is not None: self.initBuffer() if len(self.images)+len(self.marks)==0: return if self.conbox[2] - self.conbox[0] > 1: self.update() diff --git a/sciwx/canvas/mcanvas.py b/sciwx/canvas/mcanvas.py index 8551bdd8..bafc9be8 100644 --- a/sciwx/canvas/mcanvas.py +++ b/sciwx/canvas/mcanvas.py @@ -258,6 +258,8 @@ def on_scroll(self, event): self.canvas.on_idle(event) def on_idle(self, event): + if self.image.img is None: + return image, info = self.image, self.lab_info.GetLabel() imgs = image.slices, image.channels, image.cn, image.cur selfs = self.pages ,self.chans, self.cn, self.cur diff --git a/sciwx/widgets/propertygrid.py b/sciwx/widgets/propertygrid.py new file mode 100644 index 00000000..60eb5f60 --- /dev/null +++ b/sciwx/widgets/propertygrid.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python + +import sys, time, math, os.path + +import wx, wx.adv +import wx.propgrid as wxpg + +from six import exec_ +_ = wx.GetTranslation + +data = [('Sheet1', [((4, 5), ['str', 'Sample_ID', '5', "image's name"]), ((4, 17), ['str', 'Operator_Name', None, 'your name']), ((4, 30), ['date', 'Date', None, 'today']), ((10, 1), ['img', 'Original_Image', '[8.16,5.76,0.9,0]', 'the original image']), ((10, 20), ['img', 'Mask_Image', '[8.16,5.76,0.9,0]', '']), ((28, 1), ['tab', 'Record', '[1,3,0,0]', 'records'])]), ('Sheet2', [((0,0), ['list', 'a', '[1,2,345]', 'nothing'])]), ('Sheet3', [])] +key = {'Sample_ID': ['str', 'Sample_ID', '5', "image's name"], 'Operator_Name': ['str', 'Operator_Name', None, 'your name'], 'Date': ['date', 'Date', None, 'today'], 'Original_Image': ['img', 'Original_Image', '[8.16,5.76,0.9,0]', 'the original image'], 'Mask_Image': ['img', 'Mask_Image', '[8.16,5.76,0.9,0]', ''], 'Record': ['tab', 'Record', '[1,3,0,0]', 'records']} + +class GridDialog( wx.Dialog ): + + def __init__( self, parent, title, tree, key): + wx.Dialog.__init__ (self, parent, -1, title, style = wx.DEFAULT_DIALOG_STYLE, size = wx.Size((300, 480))) + # wx.Panel.__init__(self, parent, wx.ID_ANY) + self.app = parent + + self.panel = panel = wx.Panel(self, wx.ID_ANY) + topsizer = wx.BoxSizer(wx.VERTICAL) + + # Difference between using PropertyGridManager vs PropertyGrid is that + # the manager supports multiple pages and a description box. + self.pg = pg = wxpg.PropertyGridManager(panel, + style=wxpg.PG_SPLITTER_AUTO_CENTER) + + # Show help as tooltips + pg.SetExtraStyle(wxpg.PG_EX_HELP_AS_TOOLTIPS) + + pg.Bind( wxpg.EVT_PG_CHANGED, self.OnPropGridChange ) + pg.Bind( wxpg.EVT_PG_SELECTED, self.OnPropGridSelect ) + + pg.AddPage('Page 1') + self.key = key + for page in tree: + pg.Append(wxpg.PropertyCategory(page[0])) + for item in page[1]: + v = item[1] + if v[0] == 'int': pg.Append( wxpg.IntProperty(v[1], value=int(v[2]) or 0)) + if v[0] == 'float': pg.Append( wxpg.FloatProperty(v[1], value=float(v[2]) or 0)) + if v[0] == 'str': pg.Append( wxpg.StringProperty(v[1], value=v[2] or '')) + if v[0] == 'txt': pg.Append( wxpg.LongStringProperty(v[1], value=v[2] or '')) + if v[0] == 'bool': pg.Append( wxpg.BoolProperty(v[1])) + if v[0] == 'date': pg.Append( wxpg.DateProperty(v[1], value=wx.DateTime.Now())) + if v[0] == 'list': pg.Append( wxpg.EnumProperty(v[1], v[1], [i.strip() for i in v[2][1:-1].split(',')])) + if v[0] == 'img': pg.Append( wxpg.EnumProperty(v[1], v[1], self.app.img_names())) + if v[0] == 'tab': pg.Append( wxpg.EnumProperty(v[1], v[1], self.app.table_names())) + + topsizer.Add(pg, 1, wx.EXPAND) + self.txt_info = wx.TextCtrl( self, wx.ID_ANY, 'information', wx.DefaultPosition, wx.Size(80, 80), wx.TE_MULTILINE|wx.TRANSPARENT_WINDOW ) + topsizer.Add(self.txt_info, 0, wx.EXPAND|wx.ALL, 0) + rowsizer = wx.BoxSizer(wx.HORIZONTAL) + but = wx.Button(panel, wx.ID_OK, "OK") + rowsizer.Add(but,1) + #but.Bind( wx.EVT_BUTTON, self.OnGetPropertyValues ) + but = wx.Button(panel, wx.ID_CANCEL,"Cancel") + rowsizer.Add(but,1) + topsizer.Add(rowsizer,0,wx.EXPAND) + + panel.SetSizer(topsizer) + topsizer.SetSizeHints(panel) + + sizer = wx.BoxSizer(wx.VERTICAL) + sizer.Add(panel, 1, wx.EXPAND) + self.SetSizer(sizer) + self.SetAutoLayout(True) + + def GetValue(self): + return self.pg.GetPropertyValues(as_strings=True) + + def OnGetPropertyValues(self,event): + para = self.pg.GetPropertyValues(inc_attributes=True) + + def OnPropGridChange(self, event): + p = event.GetProperty() + if p: print('%s changed to "%s"\n' % (p.GetName(),p.GetValueAsString())) + + def OnPropGridSelect(self, event): + p = event.GetProperty() + if p: self.txt_info.SetValue('%s: %s'%(p.GetName(), self.key[p.GetName()][3])) + +if __name__ == '__main__': + app = wx.App(False) + frame = GridDialog(None, 'Property Grid', data, key) + rst = frame.ShowModal() == wx.ID_OK + app.MainLoop() \ No newline at end of file diff --git a/sciwx/widgets/ribbonbar.py b/sciwx/widgets/ribbonbar.py index 80638446..a8e61471 100644 --- a/sciwx/widgets/ribbonbar.py +++ b/sciwx/widgets/ribbonbar.py @@ -69,7 +69,10 @@ def parse(self, ks, vs, pt): def parse(self, ks, vs, pt, short, rst): page = rb.RibbonPage( self, wx.ID_ANY, ks , wx.NullBitmap , 0 ) panel = toolbar = None + for kv1 in vs: + if len(kv1) == 2: + kv1 = (kv1[0], None, kv1[1]) if kv1 == '-': continue pname = kv1[0] if isinstance(kv1[2], list) else '--' if panel is None and not isinstance(kv1[2], list): @@ -85,6 +88,8 @@ def parse(self, ks, vs, pt, short, rst): panel = rb.RibbonPanel( page, wx.ID_ANY, pname , make_logo(kv1[1] or kv1[0][0]) , wx.DefaultPosition, wx.DefaultSize, rb.RIBBON_PANEL_DEFAULT_STYLE ) toolbar = rb.RibbonButtonBar( panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, 0) for kv2 in kv1[2]: + if len(kv2) == 2: + kv2 = (kv2[0], None, kv2[1]) if kv2 == '-': continue btn = toolbar.AddSimpleButton( wx.NewId(), kv2[0], make_logo(kv2[1] or kv2[0][0]), wx.EmptyString) toolbar.Bind(rb.EVT_RIBBONBUTTONBAR_CLICKED, lambda e, p=kv2[2]:p().start(self.app), id=btn.id) @@ -98,11 +103,14 @@ def Append(self, id, item, menu): def load(self, data, shortcut={}): rst = [] - for k,l,v in data[1]: - self.parse(k, v, self, shortcut, rst) + for klv in data[1]: + if len(klv) == 2: + self.parse(klv[0], klv[1], self, shortcut, rst) + else: + self.parse(klv[0], klv[2], self, shortcut, rst) + rst = [(*hot_key(i[0]), i[1]) for i in rst] - acc = wx.AcceleratorTable(rst) - self.GetParent().SetAcceleratorTable(acc) + return wx.AcceleratorTable(rst) def on_menu(self, event): print('here') @@ -124,15 +132,27 @@ def start(self, app): def __call__(self): return self + # data = ('menu', [ + # ('File', None, [ + # ('Open CV', (255,0,0), P('O')), + # '-', + # ('Close', None, P('C'))]), + # ('Edit', None, [('Copy', None, P('C')), + # ('A', None, [('B', None, P('B')), + # ('C', None, P('C'))]), + # ('Paste', None, P('P'))])]) + data = ('menu', [ - ('File', None, [ - ('Open CV', (255,0,0), P('O')), + ('File', [ + ('Open', P('O')), '-', - ('Close', None, P('C'))]), - ('Edit', None, [('Copy', None, P('C')), - ('A', None, [('B', None, P('B')), - ('C', None, P('C'))]), - ('Paste', None, P('P'))])]) + ('Close', P('C'))]), + ('Edit', [ + ('Copy', P('C')), + ('A', [ + ('B', P('B')), + ('C', P('C'))]), + ('Paste', P('P'))])]) app = wx.App() frame = wx.Frame(None) diff --git a/sciwx/widgets/toolbar.py b/sciwx/widgets/toolbar.py index 993fd7ee..41c84da5 100644 --- a/sciwx/widgets/toolbar.py +++ b/sciwx/widgets/toolbar.py @@ -23,9 +23,10 @@ def make_logo(obj): a = memoryview(rgb[::3]).tolist() a = bytes([255-i for i in a]) bmp = wx.Bitmap.FromBufferAndAlpha(16, 16, rgb, a) - img = bmp.ConvertToImage() - img.Resize((20,20), (2,2)) - return img.ConvertToBitmap() + # img = bmp.ConvertToImage() + # img.Resize((20,20), (2,2)) + # return img.ConvertToBitmap() + return bmp class ToolBar(wx.Panel): def __init__(self, parent, vertical=False):