def create_frame(self, parent, size=(750, 450), **kwds): self.parent = parent kwds['style'] = wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL kwds['size'] = size wx.Frame.__init__(self, parent, -1, 'Epics PV Strip Chart', **kwds) self.build_statusbar() self.plotpanel = PlotPanel(self, trace_color_callback=self.onTraceColor) self.plotpanel.BuildPanel() self.plotpanel.messenger = self.write_message self.build_pvpanel() self.build_btnpanel() self.build_menus() self.SetBackgroundColour(wx.Colour(*BGCOL)) mainsizer = wx.BoxSizer(wx.VERTICAL) p1 = wx.Panel(self) p1.SetBackgroundColour(wx.Colour(*BGCOL)) s1 = wx.BoxSizer(wx.HORIZONTAL) n = LabelEntry(p1, '', labeltext=' Add PV: ', size=300, action=self.onPVname) self.pvmsg = SimpleText(p1, ' ', minsize=(75, -1), style=LSTY | wx.EXPAND) s1.Add(n.label, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER, 10) s1.Add(n, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER, 10) s1.Add(self.pvmsg, 1, wx.ALIGN_LEFT | wx.ALIGN_CENTER, 10) p1.SetAutoLayout(True) p1.SetSizer(s1) s1.Fit(p1) mainsizer.Add(p1, 0, wx.GROW | wx.EXPAND, 5) mainsizer.Add( wx.StaticLine(self, size=(250, -1), style=wx.LI_HORIZONTAL), 0, wx.EXPAND | wx.GROW, 8) mainsizer.Add(self.pvpanel, 0, wx.EXPAND, 5) mainsizer.Add( wx.StaticLine(self, size=(250, -1), style=wx.LI_HORIZONTAL), 0, wx.EXPAND | wx.GROW, 8) mainsizer.Add(self.btnpanel, 0, wx.EXPAND, 5) mainsizer.Add(self.plotpanel, 1, wx.EXPAND, 5) self.SetAutoLayout(True) self.SetSizer(mainsizer) self.Fit() try: self.SetIcon(wx.Icon(ICON_FILE, wx.BITMAP_TYPE_ICO)) except: pass self.Refresh()
def __init__(self, parent, name, **kws): title = "Video Capture" wx.Dialog.__init__(self, parent, wx.ID_ANY, title=title) panel = GridPanel(self, ncols=3, nrows=2, pad=2, itemstyle=LCEN) self.filename = wx.TextCtrl(panel, -1, 'Capture.avi', size=(150, -1)) self.runtime = wx.TextCtrl(panel, -1, '15.0', size=(150, -1)) panel.Add(SimpleText(panel, 'File Name : '), newrow=True) panel.Add(self.filename) panel.Add(SimpleText(panel, 'Run Time: '), newrow=True) panel.Add(self.runtime) panel.Add(OkCancel(panel), dcol=2, newrow=True) panel.pack()
def build_btnpanel(self): panel = self.btnpanel = wx.Panel(self, ) panel.SetBackgroundColour(wx.Colour(*BGCOL)) btnsizer = wx.BoxSizer(wx.HORIZONTAL) self.pause_btn = wx.Button(panel, label='Pause', size=(100, 30)) self.resume_btn = wx.Button(panel, label='Resume', size=(100, 30)) self.resume_btn.Disable() self.pause_btn.Bind(wx.EVT_BUTTON, self.onPause) self.resume_btn.Bind(wx.EVT_BUTTON, self.onPause) time_label = SimpleText(panel, ' Time Range: ', minsize=(85, -1), style=LSTY) self.time_choice = MyChoice(panel, size=(120, -1), choices=('seconds', 'minutes', 'hours')) self.time_choice.SetStringSelection(self.timelabel) self.time_choice.Bind(wx.EVT_CHOICE, self.onTimeChoice) self.time_ctrl = FloatCtrl(panel, value=-self.tmin, precision=2, size=(90, -1), action=self.onDisplayTimeVal) btnsizer.Add(self.pause_btn, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER, 2) btnsizer.Add(self.resume_btn, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER, 2) btnsizer.Add(time_label, 1, wx.ALIGN_CENTER_HORIZONTAL, 2) btnsizer.Add(self.time_ctrl, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER, 2) btnsizer.Add(self.time_choice, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER, 2) panel.SetAutoLayout(True) panel.SetSizer(btnsizer) btnsizer.Fit(panel)
def __init__(self, parent, posname, inst, **kws): self.posname = posname self.inst = inst title = "Rename Position '%s' for '%s' ?" % (posname, inst.name) wx.Dialog.__init__(self, parent, wx.ID_ANY, title=title) panel = wx.Panel(self) colors = GUIColors() self.SetFont(parent.GetFont()) titlefont = self.GetFont() titlefont.PointSize += 2 titlefont.SetWeight(wx.BOLD) panel.SetBackgroundColour(colors.bg) sizer = wx.GridBagSizer(10, 3) labstyle = wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL rlabstyle = wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL | wx.ALL tstyle = wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL label1 = SimpleText(panel, 'Old name = %s' % posname, style=tstyle) label2 = SimpleText(panel, 'New name = ', style=tstyle) self.newname = wx.TextCtrl(panel, value=posname, size=(225, 25)) sizer.Add(label1, (0, 0), (1, 2), labstyle, 1) sizer.Add(label2, (1, 0), (1, 1), labstyle, 1) sizer.Add(self.newname, (1, 1), (1, 1), labstyle, 1) sizer.Add(wx.StaticLine(panel, size=(250, -1), style=wx.LI_HORIZONTAL), (2, 0), (1, 2), wx.ALIGN_CENTER | wx.GROW | wx.ALL, 0) btnsizer = wx.StdDialogButtonSizer() btn = wx.Button(panel, wx.ID_OK) btn.SetDefault() btnsizer.AddButton(btn) btnsizer.AddButton(wx.Button(panel, wx.ID_CANCEL)) btnsizer.Realize() sizer.Add(btnsizer, (3, 0), (1, 2), wx.ALIGN_CENTER_VERTICAL | wx.ALL, 1) pack(panel, sizer) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(panel, 0, 0, 0) pack(self, sizer)
def build_pvpanel(self): panel = self.pvpanel = wx.Panel(self) panel.SetBackgroundColour(wx.Colour(*BGCOL)) sizer = self.pvsizer = wx.GridBagSizer(4, 5) name = SimpleText(panel, ' PV: ', minsize=(65, -1), style=LSTY) colr = SimpleText(panel, ' Color ', minsize=(50, -1), style=LSTY) logs = SimpleText(panel, ' Log? ', minsize=(50, -1), style=LSTY) ymin = SimpleText(panel, ' Y Min ', minsize=(85, -1), style=LSTY) ymax = SimpleText(panel, ' Y Max ', minsize=(85, -1), style=LSTY) desc = SimpleText(panel, ' Label ', minsize=(85, -1), style=LSTY) side = SimpleText(panel, ' Side ', minsize=(85, -1), style=LSTY) sizer.Add(name, (0, 0), (1, 1), LSTY | wx.EXPAND, 2) sizer.Add(colr, (0, 1), (1, 1), LSTY, 1) sizer.Add(logs, (0, 2), (1, 1), LSTY, 1) sizer.Add(ymin, (0, 3), (1, 1), LSTY, 1) sizer.Add(ymax, (0, 4), (1, 1), LSTY, 1) sizer.Add(desc, (0, 5), (1, 1), LSTY, 1) sizer.Add(side, (0, 6), (1, 1), LSTY, 1) self.npv_rows = 0 for i in range(4): self.AddPV_row() panel.SetAutoLayout(True) panel.SetSizer(sizer) sizer.Fit(panel)
def build_dialog(self, positions): self.positions = positions panel = scrolled.ScrolledPanel(self) self.checkboxes = {} sizer = wx.GridBagSizer(len(positions)+5, 4) sizer.SetVGap(2) sizer.SetHGap(3) bkws = dict(size=(95, -1)) btn_ok = add_button(panel, "Erase Selected", action=self.onOK, **bkws) btn_all = add_button(panel, "Select All", action=self.onAll, **bkws) btn_none = add_button(panel, "Select None", action=self.onNone, **bkws) brow = wx.BoxSizer(wx.HORIZONTAL) brow.Add(btn_all , 0, ALL_EXP|wx.ALIGN_LEFT, 1) brow.Add(btn_none, 0, ALL_EXP|wx.ALIGN_LEFT, 1) brow.Add(btn_ok , 0, ALL_EXP|wx.ALIGN_LEFT, 1) sizer.Add(SimpleText(panel, ' Note: ERASING POSITIONS CANNOT BE UNDONE!! Use "Export Positions" to Save!', colour=wx.Colour(200, 0, 0)), (0, 0), (1, 2), LEFT_CEN, 2) sizer.Add(SimpleText(panel, ' Use "Export Positions" to Save Positions!', colour=wx.Colour(200, 0, 0)), (1, 0), (1, 2), LEFT_CEN, 2) sizer.Add(brow, (2, 0), (1, 3), LEFT_CEN, 2) sizer.Add(SimpleText(panel, ' Position Name'), (3, 0), (1, 1), LEFT_CEN, 2) sizer.Add(SimpleText(panel, 'Erase?'), (3, 1), (1, 1), LEFT_CEN, 2) sizer.Add(SimpleText(panel, ' Position Name'), (3, 2), (1, 1), LEFT_CEN, 2) sizer.Add(SimpleText(panel, 'Erase?'), (3, 3), (1, 1), LEFT_CEN, 2) sizer.Add(wx.StaticLine(panel, size=(500, 2)), (4, 0), (1, 4), LEFT_CEN, 2) irow = 4 for ip, pname in enumerate(positions): cbox = self.checkboxes[pname] = wx.CheckBox(panel, -1, "") cbox.SetValue(True) if ip % 2 == 0: irow += 1 icol = 0 else: icol = 2 sizer.Add(SimpleText(panel, " %s "%pname), (irow, icol), (1, 1), LEFT_CEN, 2) sizer.Add(cbox, (irow, icol+1), (1, 1), LEFT_CEN, 2) irow += 1 sizer.Add(wx.StaticLine(panel, size=(500, 2)), (irow, 0), (1, 4), LEFT_CEN, 2) pack(panel, sizer) panel.SetMinSize((700, 550)) panel.SetupScrolling() mainsizer = wx.BoxSizer(wx.VERTICAL) mainsizer.Add(panel, 1, ALL_EXP|wx.GROW|wx.ALIGN_LEFT, 1) pack(self, mainsizer) self.SetMinSize((700, 550)) self.Raise() self.Show()
def __init__(self, parent=None, filelist=None, title='Select Instruments File'): wx.Dialog.__init__(self, parent, wx.ID_ANY, title=title) #panel = wx.Panel(self) self.colors = GUIColors() self.SetBackgroundColour(self.colors.bg) if parent is not None: self.SetFont(parent.GetFont()) flist = [] for fname in filelist: if os.path.exists(fname): flist.append(fname) self.filebrowser = FileBrowser(self, size=(600, -1)) self.filebrowser.SetHistory(flist) self.filebrowser.SetLabel('File:') self.filebrowser.fileMask = EIN_WILDCARD if filelist is not None: self.filebrowser.SetValue(filelist[0]) self.message = SimpleText(self, 'Select DB File', size=(500,-1)) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.message, 0, wx.ALIGN_CENTER|wx.ALL|wx.GROW, 1) sizer.Add(self.filebrowser, 1, wx.ALIGN_CENTER|wx.ALL|wx.GROW, 1) line = wx.StaticLine(self, -1, size=(20,-1), style=wx.LI_HORIZONTAL) sizer.Add(line, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.RIGHT|wx.TOP, 5) btnsizer = wx.StdDialogButtonSizer() if wx.Platform != "__WXMSW__": btn = wx.ContextHelpButton(self) btnsizer.AddButton(btn) btn = wx.Button(self, wx.ID_OK) btn.SetHelpText("Use this Instruments File") btn.SetDefault() btnsizer.AddButton(btn) btn = wx.Button(self, wx.ID_CANCEL) btnsizer.AddButton(btn) btnsizer.Realize() sizer.Add(btnsizer, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) self.SetSizer(sizer) sizer.Fit(self)
def __init__(self, parent=None, pos=(-1, -1), inst=None, db=None, page=None): title = 'New Position' if inst is not None: title = 'New Position for Instrument %s ' % inst.name style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL wx.Frame.__init__(self, None, -1, title, size=(350, 450), style=style, pos=pos) self.Handle_FocusEvents() panel = scrolled.ScrolledPanel(self, size=(400, 500), style=wx.GROW|wx.TAB_TRAVERSAL) colors = GUIColors() font = self.GetFont() if parent is not None: font = parent.GetFont() titlefont = font titlefont.PointSize += 1 titlefont.SetWeight(wx.BOLD) panel.SetBackgroundColour(colors.bg) self.parent = parent self.page = page self.db = db self.inst = db.get_instrument(inst) STY = wx.GROW|wx.ALL|wx.ALIGN_CENTER_VERTICAL LSTY = wx.ALIGN_LEFT|wx.GROW|wx.ALL|wx.ALIGN_CENTER_VERTICAL RSTY = wx.ALIGN_RIGHT|STY CSTY = wx.ALIGN_CENTER|STY CEN = wx.ALIGN_CENTER|wx.GROW|wx.ALL LEFT = wx.ALIGN_LEFT|wx.GROW|wx.ALL self.name = wx.TextCtrl(panel, value='', size=(200, -1)) sizer = wx.GridBagSizer(12, 3) ir = 0 sizer.Add(SimpleText(panel, " New Position for '%s'" % self.inst.name, font=titlefont, colour=colors.title), (ir, 0), (1, 2), LSTY, 2) ir += 1 sizer.Add(SimpleText(panel, 'Position Name:'), (ir, 0), (1, 1), LSTY, 2) sizer.Add(self.name, (ir, 1), (1, 2), LSTY, 2) ir += 1 sizer.Add(SimpleText(panel, 'PV Name:'), (ir, 0), (1, 1), LSTY, 2) sizer.Add(SimpleText(panel, 'Position:'), (ir, 1), (1, 1), LSTY, 2) ir += 1 sizer.Add(wx.StaticLine(panel, size=(195, -1), style=wx.LI_HORIZONTAL), (ir, 0), (1, 3), CEN, 2) self.positions = [] ir += 1 for p in self.inst.pvs: val = wx.TextCtrl(panel, value='', size=(150, -1)) sizer.Add(SimpleText(panel, p.name), (ir, 0), (1, 1), LSTY, 2) sizer.Add(val, (ir, 1), (1, 1), LSTY, 2) self.positions.append(val) ir += 1 sizer.Add(wx.StaticLine(panel, size=(195, -1), style=wx.LI_HORIZONTAL), (ir, 0), (1, 3), CEN, 2) btn_panel = wx.Panel(panel, size=(75, -1)) btn_sizer = wx.BoxSizer(wx.HORIZONTAL) btn_ok = add_button(btn_panel, 'OK', size=(70, -1), action=self.onOK) btn_cancel = add_button(btn_panel, 'Cancel', size=(70, -1), action=self.onCancel) btn_sizer.Add(btn_ok, 0, wx.ALIGN_LEFT, 2) btn_sizer.Add(btn_cancel, 0, wx.ALIGN_RIGHT, 2) pack(btn_panel, btn_sizer) ir += 1 sizer.Add(btn_panel, (ir, 0), (1, 3), CEN, 2) ir += 1 sizer.Add(wx.StaticLine(panel, size=(195, -1), style=wx.LI_HORIZONTAL), (ir, 0), (1, 3), CEN, 2) pack(panel, sizer) panel.SetupScrolling() self.Layout() self.Show() self.Raise()
def __init__(self, parent=None, pos=(-1, -1), inst=None, db=None, epics_pvs=None): self.epics_pvs = epics_pvs if self.epics_pvs is None: self.epics_pvs = {} title = 'Add New Instrument' if inst is not None: title = 'Edit Instrument %s ' % inst.name style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL wx.Frame.__init__(self, None, -1, title, style=style, pos=pos) self.Handle_FocusEvents() panel = scrolled.ScrolledPanel(self, size=(500, 650), style=wx.GROW|wx.TAB_TRAVERSAL, name='p1') self.colors = GUIColors() font = self.GetFont() if parent is not None: font = parent.GetFont() titlefont = font titlefont.PointSize += 1 titlefont.SetWeight(wx.BOLD) panel.SetBackgroundColour(self.colors.bg) self.parent = parent self.db = db self.inst = db.get_instrument(inst) self.connecting_pvs = {} STY = wx.GROW|wx.ALL|wx.ALIGN_CENTER_VERTICAL LSTY = wx.ALIGN_LEFT|wx.GROW|wx.ALL|wx.ALIGN_CENTER_VERTICAL RSTY = wx.ALIGN_RIGHT|STY CSTY = wx.ALIGN_CENTER|STY CEN = wx.ALIGN_CENTER|wx.GROW|wx.ALL LEFT = wx.ALIGN_LEFT|wx.GROW|wx.ALL self.etimer = wx.Timer(self) self.etimer_count = 0 self.Bind(wx.EVT_TIMER, self.onTimer, self.etimer) sizer = wx.GridBagSizer(12, 3) # Name row label = SimpleText(panel, 'Instrument Name: ', minsize=(150, -1), style=LSTY) self.name = wx.TextCtrl(panel, value='', size=(260, -1)) sizer.Add(label, (0, 0), (1, 1), LSTY, 2) sizer.Add(self.name, (0, 1), (1, 2), LSTY, 2) sizer.Add(wx.StaticLine(panel, size=(195, -1), style=wx.LI_HORIZONTAL), (1, 0), (1, 3), CEN, 2) irow = 2 self.curpvs, self.newpvs = [], {} if inst is not None: self.name.SetValue(inst.name) sizer.Add(SimpleText(panel, 'Current PVs:', font=titlefont, colour=self.colors.title, style=LSTY), (2, 0), (1, 1), LSTY, 2) sizer.Add(SimpleText(panel, 'Display Type:', colour=self.colors.title, style=CSTY), (2, 1), (1, 1), LSTY, 2) sizer.Add(SimpleText(panel, 'Remove?:', colour=self.colors.title, style=CSTY), (2, 2), (1, 1), RSTY, 2) opvs = db.get_ordered_instpvs(inst) for instpvs in self.db.get_ordered_instpvs(inst): pv = instpvs.pv irow += 1 if pv.name in self.epics_pvs: pvchoices = get_pvtypes(self.epics_pvs[pv.name], instrument) else: pvchoices = get_pvtypes(pv, instrument) label= SimpleText(panel, pv.name, minsize=(175, -1), style=LSTY) try: itype = pvchoices.index(pv.pvtype.name) except ValueError: itype = 0 pvtype = PVTypeChoice(panel, choices=pvchoices) pvtype.SetSelection(itype) pvtype.SetStringSelection(pv.pvtype.name) del_pv = YesNo(panel, defaultyes=False) self.curpvs.append((pv.name, label, pvtype, del_pv)) sizer.Add(label, (irow, 0), (1, 1), LSTY, 3) sizer.Add(pvtype, (irow, 1), (1, 1), CSTY, 3) sizer.Add(del_pv, (irow, 2), (1, 1), RSTY, 3) irow += 1 sizer.Add(wx.StaticLine(panel, size=(150, -1), style=wx.LI_HORIZONTAL), (irow, 0), (1, 3), CEN, 0) irow += 1 txt =SimpleText(panel, 'New PVs:', font=titlefont, colour=self.colors.title, style=LSTY) sizer.Add(txt, (irow, 0), (1, 1), LEFT, 3) sizer.Add(SimpleText(panel, 'Display Type', colour=self.colors.title, style=CSTY), (irow, 1), (1, 1), LSTY, 2) sizer.Add(SimpleText(panel, 'Remove?', colour=self.colors.title, style=CSTY), (irow, 2), (1, 1), RSTY, 2) # New PVs for npv in range(5): irow += 1 name = pvNameCtrl(self, panel, value='', size=(175, -1)) pvtype = PVTypeChoice(panel) del_pv = YesNo(panel, defaultyes=False) pvtype.Disable() del_pv.Disable() sizer.Add(name, (irow, 0), (1, 1), LSTY, 3) sizer.Add(pvtype, (irow, 1), (1, 1), CSTY, 3) sizer.Add(del_pv, (irow, 2), (1, 1), RSTY, 3) self.newpvs[name.GetId()] = dict(index=npv, name=name, type=pvtype, delpv=del_pv) btn_panel = wx.Panel(panel, size=(75, -1)) btn_sizer = wx.BoxSizer(wx.HORIZONTAL) btn_ok = add_button(btn_panel, 'Done', size=(70, -1), action=self.OnDone) btn_cancel = add_button(btn_panel, 'Cancel', size=(70, -1), action=self.onCancel) btn_sizer.Add(btn_ok, 0, wx.ALIGN_LEFT, 2) btn_sizer.Add(btn_cancel, 0, wx.ALIGN_RIGHT, 2) pack(btn_panel, btn_sizer) irow += 1 sizer.Add(wx.StaticLine(panel, size=(150, -1), style=wx.LI_HORIZONTAL), (irow, 0), (1, 3), CEN, 2) sizer.Add(btn_panel, (irow+1, 1), (1, 2), CEN, 2) sizer.Add(wx.StaticLine(panel, size=(150, -1), style=wx.LI_HORIZONTAL), (irow+2, 0), (1, 3), CEN, 2) set_font_with_children(self, font) pack(panel, sizer) panel.SetupScrolling() mainsizer = wx.BoxSizer(wx.VERTICAL) mainsizer.Add(panel, 1, LSTY) pack(self, mainsizer) self.Layout() self.Show() self.Raise()
def build_dialog(self): positions = self.instdb.get_positionlist(self.offline) panel = scrolled.ScrolledPanel(self) self.checkboxes = OrderedDict() sizer = wx.GridBagSizer(len(positions) + 5, 4) sizer.SetVGap(2) sizer.SetHGap(3) bkws = dict(size=(95, -1)) btn_ok = add_button(panel, "Copy Selected", action=self.onOK, **bkws) btn_all = add_button(panel, "Select All", action=self.onAll, **bkws) btn_none = add_button(panel, "Select None", action=self.onNone, **bkws) brow = wx.BoxSizer(wx.HORIZONTAL) brow.Add(btn_all, 0, ALL_EXP | wx.ALIGN_LEFT, 1) brow.Add(btn_none, 0, ALL_EXP | wx.ALIGN_LEFT, 1) brow.Add(btn_ok, 0, ALL_EXP | wx.ALIGN_LEFT, 1) sizer.Add(brow, (0, 0), (1, 4), LEFT_CEN, 2) sizer.Add(SimpleText(panel, ' Add Suffix:'), (1, 0), (1, 1), LEFT_CEN, 2) self.suffix = wx.TextCtrl(panel, value="", size=(150, -1)) sizer.Add(self.suffix, (1, 1), (1, 3), LEFT_CEN, 2) sizer.Add(SimpleText(panel, ' Position Name'), (2, 0), (1, 1), LEFT_CEN, 2) sizer.Add(SimpleText(panel, 'Copy?'), (2, 1), (1, 1), LEFT_CEN, 2) sizer.Add(SimpleText(panel, ' Position Name'), (2, 2), (1, 1), LEFT_CEN, 2) sizer.Add(SimpleText(panel, 'Copy?'), (2, 3), (1, 1), LEFT_CEN, 2) sizer.Add(wx.StaticLine(panel, size=(500, 2)), (3, 0), (1, 4), LEFT_CEN, 2) irow = 3 for ip, pname in enumerate(positions): cbox = self.checkboxes[pname] = wx.CheckBox(panel, -1, "") cbox.SetValue(True) if ip % 2 == 0: irow += 1 icol = 0 else: icol = 2 sizer.Add(SimpleText(panel, " %s " % pname), (irow, icol), (1, 1), LEFT_CEN, 2) sizer.Add(cbox, (irow, icol + 1), (1, 1), LEFT_CEN, 2) irow += 1 sizer.Add(wx.StaticLine(panel, size=(500, 2)), (irow, 0), (1, 4), LEFT_CEN, 2) pack(panel, sizer) panel.SetMinSize((700, 550)) panel.SetupScrolling() mainsizer = wx.BoxSizer(wx.VERTICAL) mainsizer.Add(panel, 1, ALL_EXP | wx.GROW | wx.ALIGN_LEFT, 1) pack(self, mainsizer) self.SetMinSize((700, 550)) self.Raise() self.Show()
def buildDialog(self, parent, epics_motor, db_motor): self.checkboxes = {} pre = wx.PreDialog() pre.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP) pre.Create(parent, -1, 'Update Motor Settings?', style=wx.DEFAULT_DIALOG_STYLE) self.PostCreate(pre) sizer = wx.GridBagSizer(10, 4) labstyle = wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL rlabstyle = wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL | wx.ALL tstyle = wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL label = wx.StaticText(self, label="Update Motor Settings to '%s'?" % db_motor.name) sizer.Add(label, (0, 0), (1, 4), wx.ALIGN_CENTRE | wx.ALL, 5) titlefont = self.GetFont() titlefont.PointSize += 1 titlefont.SetWeight(wx.BOLD) # title row irow = 1 for i, word in enumerate( (' Field', 'Current Value', 'New Value', 'Change?')): txt = SimpleText(self, word, font=titlefont, size=(100, -1), colour=wx.Colour(80, 10, 10), style=tstyle) sizer.Add(txt, (irow, i), (1, 1), labstyle, 1) sizer.Add(wx.StaticLine(self, size=(150, -1), style=wx.LI_HORIZONTAL), (irow + 1, 0), (1, 4), wx.ALIGN_CENTER | wx.GROW | wx.ALL, 0) self.checkboxes = {} for irow, attr in enumerate(self._fields): suff = attr.upper() if attr in self._fieldmap: suff = self._fieldmap[attr] curval = epics_motor.get(suff, as_string=True) newval = str(getattr(db_motor, attr)) if curval is None: curval = 'unknown' label = SimpleText(self, suff) curr = SimpleText(self, curval) newv = SimpleText(self, newval) cbox = wx.CheckBox(self, -1, "Update") cbox.SetValue(True) self.checkboxes[suff] = (cbox, newval) sizer.Add(label, (irow + 3, 0), (1, 1), labstyle, 2) sizer.Add(curr, (irow + 3, 1), (1, 1), rlabstyle, 2) sizer.Add(newv, (irow + 3, 2), (1, 1), rlabstyle, 2) sizer.Add(cbox, (irow + 3, 3), (1, 1), rlabstyle, 2) sizer.Add(wx.StaticLine(self, size=(150, -1), style=wx.LI_HORIZONTAL), (irow + 4, 0), (1, 4), wx.ALIGN_CENTER | wx.GROW | wx.ALL, 0) btnsizer = wx.StdDialogButtonSizer() btn = wx.Button(self, wx.ID_OK) btn.SetDefault() btnsizer.AddButton(btn) btnsizer.AddButton(wx.Button(self, wx.ID_CANCEL)) btnsizer.Realize() sizer.Add(btnsizer, (irow + 5, 2), (1, 2), wx.ALIGN_CENTER_VERTICAL | wx.ALL, 1) self.SetSizer(sizer) sizer.Fit(self) self.ready = True
def redraw_leftpanel(self, force=False): """ redraws the left panel """ # print 'redraw leftpanel ', self.inst, (time.time() - self.last_draw) if (time.time() - self.last_draw) < 0.5: return self.Freeze() self.Hide() self.leftsizer.Clear() self.leftsizer.Add(self.toprow, 0, wx.ALIGN_LEFT | wx.TOP, 2) current_comps = [self.toprow] pvcomps = list(self.pv_components.items()) # print 'redraw leftpanel: ', self.inst, time.ctime() #, pvcomps skip = [] for icomp, val in enumerate(pvcomps): pvname, comp = val connected, pvtype, pv = comp grow = 0 #print(" comp : ", icomp, connected, pvtype, pv) panel = None if pvtype == 'motor': try: t0 = time.time() panel = MotorPanel(self.leftpanel, pvname) except PyDeadObjectError: pass elif pv is not None and hasattr( pv, 'pvname') and pv.pvname not in skip: panel = wx.Panel(self.leftpanel) sizer = wx.BoxSizer(wx.HORIZONTAL) label = SimpleText(panel, pvname, colour=self.colors.pvname, minsize=(250, -1), style=wx.ALIGN_LEFT) desc = '' if pvname.endswith('.VAL'): try: desc = epics.caget(pvname[:-3] + 'DESC') except: pass dlabel = SimpleText(panel, desc, colour=self.colors.pvname, minsize=(250, -1), style=wx.ALIGN_LEFT) # print(" Show PV ", pv, pvtype) if 'enum' in pvtype: ctrl = PVEnumChoice(panel, pv=pv, size=(150, -1)) elif 'string' in pvtype: # in ('string', 'unicode'): ctrl = PVTextCtrl(panel, pv=pv, size=(200, -1)) else: ctrl = PVFloatCtrl(panel, pv=pv, size=(150, -1)) current_comps.append(ctrl) current_comps.append(label) sizer.Add(label, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 2) sizer.Add(ctrl, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 2) sizer.Add(dlabel, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 2) if (pvtype != 'motor' and icomp < len(pvcomps) - 1 and pvcomps[icomp + 1][1][1] != 'motor'): # and False): pass a = """ conn, pvtype2, pv2 = pvcomps[icomp+1][1] skip.append(pv2.pvname) l2 = SimpleText(panel, ' %s' % pv2.pvname, colour=self.colors.pvname, minsize=(180,-1), style=wx.ALIGN_LEFT) if 'enum' in pvtype2: c2 = PVEnumChoice(panel, pv=pv2, size=(150, -1)) elif 'string' in pvtype2: # in ('string', 'unicode'): c2 = PVTextCtrl(panel, pv=pv2, size=(150, -1)) else: c2 = PVFloatCtrl(panel, pv=pv2, size=(150, -1)) sizer.Add(l2, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 2) sizer.Add(c2, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 2) current_comps.append(c2) current_comps.append(l2) """ pack(panel, sizer) if panel is not None: current_comps.append(panel) self.leftsizer.Add(panel, 0, wx.ALIGN_LEFT | wx.TOP | wx.ALL | wx.GROW, 1) pack(self.leftpanel, self.leftsizer) for wid in self.leftpanel.Children: if wid not in current_comps and wid != self.toprow: try: time.sleep(0.010) wid.Destroy() except PyDeadObjectError: pass self.Refresh() self.Layout() self.Thaw() self.Show() self.pos_list.SetBackgroundColour(wx.WHITE) self.pos_list.Enable() self.last_draw = time.time()
def redraw_leftpanel(self, force=False): """ redraws the left panel """ if (time.time() - self.last_draw) < 0.5: return print 'redraw left! ', time.ctime() self.Freeze() self.Hide() self.leftsizer.Clear() # print 'redraw left 1 ', time.ctime() self.leftsizer.Add(self.toprow, 0, wx.ALIGN_LEFT | wx.TOP, 2) current_comps = [self.toprow] pvcomps = list(self.pv_components.items()) skip = [] for icomp, val in enumerate(pvcomps): pvname, comp = val connected, pvtype, pv = comp grow = 0 panel = None if pvtype == 'motor': try: #print 'MotorPanel create ', self.inst.name, pvname t0 = time.time() panel = MotorPanel(self.leftpanel, pvname) #print 'MotorPanel done ', time.time()-t0 except PyDeadObjectError: #print 'Error making motorpanel' pass elif pv is not None and hasattr( pv, 'pvname') and pv.pvname not in skip: panel = wx.Panel(self.leftpanel) sizer = wx.BoxSizer(wx.HORIZONTAL) label = SimpleText(panel, ' %s' % pvname, colour=self.colors.pvname, minsize=(180, -1), style=wx.ALIGN_LEFT) if pvtype == 'enum': ctrl = PVEnumChoice(panel, pv=pv, size=(120, -1)) elif pvtype in ('string', 'unicode'): ctrl = PVTextCtrl(panel, pv=pv, size=(120, -1)) else: ctrl = PVFloatCtrl(panel, pv=pv, size=(120, -1)) current_comps.append(ctrl) current_comps.append(label) sizer.Add(label, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 2) sizer.Add(ctrl, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 2) if (pvtype != 'motor' and icomp < len(pvcomps) - 1 and pvcomps[icomp + 1][1][1] != 'motor'): # and False): conn, pvtype2, pv2 = pvcomps[icomp + 1][1] skip.append(pv2.pvname) l2 = SimpleText(panel, ' %s' % pv2.pvname, colour=self.colors.pvname, minsize=(180, -1), style=wx.ALIGN_LEFT) if pvtype2 == 'enum': c2 = PVEnumChoice(panel, pv=pv2, size=(120, -1)) elif pvtype2 in ('string', 'unicode'): c2 = PVTextCtrl(panel, pv=pv2, size=(120, -1)) else: c2 = PVFloatCtrl(panel, pv=pv2, size=(120, -1)) sizer.Add(l2, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 2) sizer.Add(c2, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 2) current_comps.append(c2) current_comps.append(l2) pack(panel, sizer) if panel is not None: current_comps.append(panel) self.leftsizer.Add(panel, 0, wx.ALIGN_LEFT | wx.TOP | wx.ALL | wx.GROW, 1) pack(self.leftpanel, self.leftsizer) for wid in self.leftpanel.Children: if wid not in current_comps and wid != self.toprow: try: time.sleep(0.010) wid.Destroy() except PyDeadObjectError: pass self.Refresh() self.Layout() self.Thaw() self.Show() print 'redraw left End ', time.ctime() self.last_draw = time.time()
def __init__(self, parent, inst, db=None, writer=None, pvlist=None, size=(-1, -1)): self.last_draw = 0 self.inst = inst self.pvlist = pvlist self.db = db self.write_message = writer self.pvs = {} self.pvdesc = {} self.pv_components = OrderedDict() wx.Panel.__init__(self, parent, size=size) #for p in self.db.get_ordered_instpvs(inst): # self.add_pv(p.pv.name) self.colors = colors = GUIColors() self.parent = parent self.SetFont(parent.GetFont()) titlefont = self.GetFont() titlefont.PointSize += 2 titlefont.SetWeight(wx.BOLD) splitter = wx.SplitterWindow(self, -1, style=wx.SP_3D | wx.SP_BORDER | wx.SP_LIVE_UPDATE) rpanel = wx.Panel(splitter, style=wx.BORDER_SUNKEN, size=(-1, 225)) self.leftpanel = wx.Panel(splitter, style=wx.BORDER_SUNKEN, size=(-1, 325)) # self.leftsizer = wx.GridBagSizer(12, 4) self.leftsizer = wx.BoxSizer(wx.VERTICAL) splitter.SetMinimumPaneSize(225) toprow = wx.Panel(self.leftpanel) self.inst_title = SimpleText(toprow, ' %s ' % inst.name, font=titlefont, colour=colors.title, minsize=(150, -1), style=wx.ALIGN_LEFT | wx.ALIGN_BOTTOM) self.pos_name = wx.TextCtrl(toprow, value="", size=(250, 25), style=wx.TE_PROCESS_ENTER) self.pos_name.Bind(wx.EVT_TEXT_ENTER, self.onSavePosition) topsizer = wx.BoxSizer(wx.HORIZONTAL) topsizer.Add(self.inst_title, 0, wx.ALIGN_CENTER | wx.ALIGN_CENTER_VERTICAL, 1) topsizer.Add( SimpleText(toprow, 'Save Current Position:', minsize=(180, -1), style=wx.ALIGN_CENTER), 1, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 1) topsizer.Add(self.pos_name, 0, wx.GROW | wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL, 1) pack(toprow, topsizer) self.toprow = toprow # start a timer to check for when to fill in PV panels timer_id = wx.NewId() # self.etimer = wx.Timer(self) self.etimer2 = wx.Timer(self) self.puttimer = wx.Timer(self) self.etimer_count = 0 self.etimer_poll = 25 # self.Bind(wx.EVT_TIMER, self.OnConnectTimer, self.etimer) self.Bind(wx.EVT_TIMER, self.OnEtimer2, self.etimer2) self.Bind(wx.EVT_TIMER, self.OnPutTimer, self.puttimer) rsizer = wx.BoxSizer(wx.VERTICAL) btn_goto = add_button(rpanel, "Go To", size=(70, -1), action=self.OnMove) btn_erase = add_button(rpanel, "Erase", size=(70, -1), action=self.onErase) brow = wx.BoxSizer(wx.HORIZONTAL) brow.Add(btn_goto, 0, ALL_EXP | wx.ALIGN_LEFT, 1) brow.Add(btn_erase, 0, ALL_EXP | wx.ALIGN_LEFT, 1) self.pos_list = wx.ListBox(rpanel, size=(225, -1)) self.pos_list.SetBackgroundColour(wx.WHITE) self.pos_list.Bind(wx.EVT_RIGHT_DOWN, self.onRightClick) self.pos_list.Bind(wx.EVT_LISTBOX, self.onPosSelect) self.pos_list.Bind(wx.EVT_LEFT_DCLICK, self.OnMove) self.pos_list.Clear() for pos in inst.positions: self.pos_list.Append(pos.name) rsizer.Add(brow, 0, wx.ALIGN_LEFT | wx.ALL) rsizer.Add(self.pos_list, 1, wx.EXPAND | wx.ALIGN_CENTER, 1) pack(rpanel, rsizer) splitter.SplitVertically(self.leftpanel, rpanel, -150) self.leftpanel.SetMinSize((750, 150)) rpanel.SetMinSize((150, -1)) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(splitter, 1, wx.GROW | wx.ALL, 0) pack(self, sizer) print ' start etimer2 for ', self.inst.name, time.ctime() self.etimer2.Start(1)
def __init__(self, parent=None, pos=(-1, -1), db=None): self.parent = parent self.db = db style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL labstyle = wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL rlabstyle = wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL|wx.ALL tstyle = wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL wx.Frame.__init__(self, None, -1, 'Epics Instruments: Select Instruments to Display') font = parent.GetFont() titlefont = self.GetFont() titlefont.PointSize += 2 titlefont.SetWeight(wx.BOLD) sizer = wx.GridBagSizer(10, 5) panel = wx.Panel(self) # title row self.colors = GUIColors() panel.SetBackgroundColour(self.colors.bg) title = SimpleText(panel, 'Show Instruments:', font=titlefont, colour=self.colors.title, style=tstyle) irow = 0 sizer.Add(title, (irow, 0), (1, 4), labstyle|wx.ALL, 3) self.hideframes = {} strlen = 24 for inst in self.db.get_all_instruments(): strlen = max(strlen, len(inst.name)) for inst in self.db.get_all_instruments(): irow += 1 isshown = inst.name in self.get_page_map() iname = (inst.name + ' '*strlen)[:strlen] cb = wx.CheckBox(panel, -1, iname)#, style=wx.ALIGN_RIGHT) cb.SetValue(isshown) self.hideframes[inst.name] = cb sizer.Add(cb, (irow, 0), (1, 1), labstyle, 5) irow += 1 sizer.Add(wx.StaticLine(panel, size=(150, -1), style=wx.LI_HORIZONTAL), (irow, 0), (1, 5), wx.ALIGN_CENTER|wx.GROW|wx.ALL, 5) btn_ok = add_button(panel, 'OK', size=(70, -1), action=self.OnOK) btn_cancel = add_button(panel, 'Cancel', size=(70, -1), action=self.OnCancel) irow += 1 sizer.Add(btn_ok, (irow, 0), (1, 1), labstyle|wx.ALL, 5) sizer.Add(btn_cancel, (irow, 1), (1, 1), labstyle|wx.ALL, 5) set_font_with_children(self, font) pack(panel, sizer) mainsizer = wx.BoxSizer(wx.VERTICAL) mainsizer.Add(panel, 1, wx.GROW|wx.ALL, 1) pack(self, mainsizer) self.Show() self.Raise()
def __init__(self, parent=None, pos=(-1, -1), db=None): self.parent = parent self.db = db style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL labstyle = wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL rlabstyle = wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL|wx.ALL tstyle = wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL wx.Frame.__init__(self, None, -1, 'Epics Instruments: Settings') font = parent.GetFont() titlefont = self.GetFont() titlefont.PointSize += 2 titlefont.SetWeight(wx.BOLD) sizer = wx.GridBagSizer(10, 5) panel = wx.Panel(self) # title row self.colors = GUIColors() panel.SetBackgroundColour(self.colors.bg) title = SimpleText(panel, 'Positions Settings', font=titlefont, minsize=(130, -1), colour=self.colors.title, style=tstyle) self.v_move = wx.CheckBox(panel, -1, 'Verify Move')# , style=wx.ALIGN_RIGHT) self.v_erase = wx.CheckBox(panel, -1, 'Verify Erase ')# style=wx.ALIGN_RIGHT) self.v_owrite = wx.CheckBox(panel, -1, 'Verify Overwrie')#, style=wx.ALIGN_RIGHT) self.v_move.SetValue(1==int(self.db.get_info('verify_move'))) self.v_erase.SetValue(1==int(self.db.get_info('verify_erase'))) self.v_owrite.SetValue(1==int(self.db.get_info('verify_overwrite'))) sizer.Add(title, (0, 0), (1, 1), labstyle|wx.ALL, 5) sizer.Add(self.v_move, (1, 0), (1, 1), labstyle, 5) sizer.Add(self.v_erase, (2, 0), (1, 1), labstyle, 5) sizer.Add(self.v_owrite,(3, 0), (1, 1), labstyle, 5) sizer.Add(wx.StaticLine(panel, size=(2, 50), style=wx.LI_VERTICAL), (0, 2), (4, 1), wx.ALIGN_CENTER|wx.GROW|wx.ALL, 3) title = SimpleText(panel, ' Epics Database Connection:', font=titlefont, colour=self.colors.title, style=tstyle) label = SimpleText(panel, 'DB Prefix:') self.epics_prefix = wx.TextCtrl(panel, -1, value='', size=(160, -1)) self.epics_use = wx.CheckBox(panel, -1, 'Use Epics Db') self.epics_use.SetValue(1==int(self.db.get_info('epics_use', default=0))) self.epics_prefix.SetValue(self.db.get_info('epics_prefix', default='')) sizer.Add(title, (0, 3), (1, 2), labstyle|wx.GROW|wx.ALL, 5) sizer.Add(label, (1, 3), (1, 1), labstyle|wx.ALL, 5) sizer.Add(self.epics_prefix, (1, 4), (1, 1), labstyle|wx.GROW|wx.ALL, 5) sizer.Add(self.epics_use, (2, 3), (1, 2), labstyle|wx.GROW|wx.ALL, 5) irow = 4 sizer.Add(wx.StaticLine(panel, size=(150, -1), style=wx.LI_HORIZONTAL), (irow, 0), (1, 5), wx.ALIGN_CENTER|wx.GROW|wx.ALL, 3) title = SimpleText(panel, 'Show Instruments:', font=titlefont, minsize=(130, -1), colour=self.colors.title, style=tstyle) irow += 1 sizer.Add(title, (irow, 0), (1, 2), labstyle|wx.ALL, 3) self.hideframes = {} strlen = 24 for inst in self.db.get_all_instruments(): strlen = max(strlen, len(inst.name)) for inst in self.db.get_all_instruments(): irow += 1 isshown = inst.name in self.get_page_map() iname = (inst.name + ' '*strlen)[:strlen] cb = wx.CheckBox(panel, -1, iname)#, style=wx.ALIGN_RIGHT) cb.SetValue(isshown) self.hideframes[inst.name] = cb sizer.Add(cb, (irow, 0), (1, 1), labstyle, 5) irow += 1 sizer.Add(wx.StaticLine(panel, size=(150, -1), style=wx.LI_HORIZONTAL), (irow, 0), (1, 5), wx.ALIGN_CENTER|wx.GROW|wx.ALL, 5) btn_ok = add_button(panel, 'OK', size=(70, -1), action=self.OnOK) btn_cancel = add_button(panel, 'Cancel', size=(70, -1), action=self.OnCancel) irow += 1 sizer.Add(btn_ok, (irow, 0), (1, 1), labstyle|wx.ALL, 5) sizer.Add(btn_cancel, (irow, 1), (1, 1), labstyle|wx.ALL, 5) set_font_with_children(self, font) pack(panel, sizer) mainsizer = wx.BoxSizer(wx.VERTICAL) mainsizer.Add(panel, 1, wx.GROW|wx.ALL, 1) pack(self, mainsizer) self.Show() self.Raise()
def txt(label, size=-1): return SimpleText(panel, label, size=(size, -1))
def build_dialog(self, parent, thispos): panel = wx.Panel(self) colors = GUIColors() self.SetFont(parent.GetFont()) titlefont = self.GetFont() titlefont.PointSize += 2 titlefont.SetWeight(wx.BOLD) panel.SetBackgroundColour(colors.bg) sizer = wx.GridBagSizer(10, 4) labstyle = wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL rlabstyle = wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL | wx.ALL tstyle = wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL # title row i = 0 for titleword in (' PV ', 'Current Value', 'Saved Value', 'Move?'): txt = SimpleText(panel, titleword, font=titlefont, minsize=(100, -1), colour=colors.title, style=tstyle) sizer.Add(txt, (0, i), (1, 1), labstyle, 1) i = i + 1 sizer.Add(wx.StaticLine(panel, size=(150, -1), style=wx.LI_HORIZONTAL), (1, 0), (1, 4), wx.ALIGN_CENTER | wx.GROW | wx.ALL, 0) self.checkboxes = {} for irow, pvpos in enumerate(thispos.pvs): pvname = pvpos.pv.name desc = get_pvdesc(pvname) if desc != pvname: desc = "%s (%s)" % (desc, pvname) curr_val = self.pvs[pvname].get(as_string=True) if curr_val is None: curr_val = 'Unknown' save_val = pvpos.value label = SimpleText(panel, desc, style=tstyle, colour=colors.pvname) curr = SimpleText(panel, curr_val, style=tstyle) saved = SimpleText(panel, save_val, style=tstyle) cbox = wx.CheckBox(panel, -1, "Move") cbox.SetValue(True) self.checkboxes[pvname] = (cbox, save_val) sizer.Add(label, (irow + 2, 0), (1, 1), labstyle, 2) sizer.Add(curr, (irow + 2, 1), (1, 1), rlabstyle, 2) sizer.Add(saved, (irow + 2, 2), (1, 1), rlabstyle, 2) sizer.Add(cbox, (irow + 2, 3), (1, 1), rlabstyle, 2) sizer.Add(wx.StaticLine(panel, size=(150, -1), style=wx.LI_HORIZONTAL), (irow + 3, 0), (1, 4), wx.ALIGN_CENTER | wx.GROW | wx.ALL, 0) btnsizer = wx.StdDialogButtonSizer() btn = wx.Button(panel, wx.ID_OK) btn.SetDefault() btnsizer.AddButton(btn) btnsizer.AddButton(wx.Button(panel, wx.ID_CANCEL)) btnsizer.Realize() sizer.Add(btnsizer, (irow + 4, 2), (1, 2), wx.ALIGN_CENTER_VERTICAL | wx.ALL, 1) pack(panel, sizer) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(panel, 0, 0, 0) pack(self, sizer)
class StripChart(wx.Frame): default_colors = ((0, 0, 0), (0, 0, 255), (255, 0, 0), (0, 0, 0), (255, 0, 255), (0, 125, 0)) help_msg = """Quick help: Left-Click: to display X,Y coordinates Left-Drag: to zoom in on plot region Right-Click: display popup menu with choices: Zoom out 1 level Zoom all the way out -------------------- Configure Save Image Also, these key bindings can be used (For Mac OSX, replace 'Ctrl' with 'Apple'): Ctrl-S: save plot image to file Ctrl-C: copy plot image to clipboard Ctrl-K: Configure Plot Ctrl-Q: quit """ about_msg = """Epics PV Strip Chart version 0.1 Matt Newville <*****@*****.**> """ def __init__(self, parent=None): self.pvdata = {} self.pvlist = [' -- '] self.pvwids = [None] self.pvchoices = [None] self.colorsels = [] self.plots_drawn = [False] * 10 self.needs_refresh = False self.needs_refresh = False self.paused = False self.tmin = -60.0 self.timelabel = 'seconds' self.create_frame(parent) self.timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.onUpdatePlot, self.timer) self.timer.Start(POLLTIME) def create_frame(self, parent, size=(750, 450), **kwds): self.parent = parent kwds['style'] = wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL kwds['size'] = size wx.Frame.__init__(self, parent, -1, 'Epics PV Strip Chart', **kwds) self.build_statusbar() self.plotpanel = PlotPanel(self, trace_color_callback=self.onTraceColor) self.plotpanel.BuildPanel() self.plotpanel.messenger = self.write_message self.build_pvpanel() self.build_btnpanel() self.build_menus() self.SetBackgroundColour(wx.Colour(*BGCOL)) mainsizer = wx.BoxSizer(wx.VERTICAL) p1 = wx.Panel(self) p1.SetBackgroundColour(wx.Colour(*BGCOL)) s1 = wx.BoxSizer(wx.HORIZONTAL) n = LabelEntry(p1, '', labeltext=' Add PV: ', size=300, action=self.onPVname) self.pvmsg = SimpleText(p1, ' ', minsize=(75, -1), style=LSTY | wx.EXPAND) s1.Add(n.label, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER, 10) s1.Add(n, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER, 10) s1.Add(self.pvmsg, 1, wx.ALIGN_LEFT | wx.ALIGN_CENTER, 10) p1.SetAutoLayout(True) p1.SetSizer(s1) s1.Fit(p1) mainsizer.Add(p1, 0, wx.GROW | wx.EXPAND, 5) mainsizer.Add( wx.StaticLine(self, size=(250, -1), style=wx.LI_HORIZONTAL), 0, wx.EXPAND | wx.GROW, 8) mainsizer.Add(self.pvpanel, 0, wx.EXPAND, 5) mainsizer.Add( wx.StaticLine(self, size=(250, -1), style=wx.LI_HORIZONTAL), 0, wx.EXPAND | wx.GROW, 8) mainsizer.Add(self.btnpanel, 0, wx.EXPAND, 5) mainsizer.Add(self.plotpanel, 1, wx.EXPAND, 5) self.SetAutoLayout(True) self.SetSizer(mainsizer) self.Fit() try: self.SetIcon(wx.Icon(ICON_FILE, wx.BITMAP_TYPE_ICO)) except: pass self.Refresh() def build_statusbar(self): sbar = self.CreateStatusBar(2, wx.CAPTION | wx.THICK_FRAME) sfont = sbar.GetFont() sfont.SetWeight(wx.BOLD) sfont.SetPointSize(10) sbar.SetFont(sfont) self.SetStatusWidths([-5, -2]) self.SetStatusText('', 0) def build_pvpanel(self): panel = self.pvpanel = wx.Panel(self) panel.SetBackgroundColour(wx.Colour(*BGCOL)) sizer = self.pvsizer = wx.GridBagSizer(4, 5) name = SimpleText(panel, ' PV: ', minsize=(75, -1), style=LSTY) colr = SimpleText(panel, ' Color ', minsize=(50, -1), style=LSTY) logs = SimpleText(panel, ' Log Scale?', minsize=(85, -1), style=LSTY) ymin = SimpleText(panel, ' Y Minimum ', minsize=(85, -1), style=LSTY) ymax = SimpleText(panel, ' Y Maximum ', minsize=(85, -1), style=LSTY) sizer.Add(name, (0, 0), (1, 1), LSTY | wx.EXPAND, 2) sizer.Add(colr, (0, 1), (1, 1), LSTY, 1) sizer.Add(logs, (0, 2), (1, 1), LSTY, 1) sizer.Add(ymin, (0, 3), (1, 1), LSTY, 1) sizer.Add(ymax, (0, 4), (1, 1), LSTY, 1) self.npv_rows = 0 for i in range(4): self.AddPV_row() panel.SetAutoLayout(True) panel.SetSizer(sizer) sizer.Fit(panel) def build_btnpanel(self): panel = self.btnpanel = wx.Panel(self, ) panel.SetBackgroundColour(wx.Colour(*BGCOL)) btnsizer = wx.BoxSizer(wx.HORIZONTAL) self.pause_btn = wx.Button(panel, label='Pause', size=(100, 30)) self.resume_btn = wx.Button(panel, label='Resume', size=(100, 30)) self.resume_btn.Disable() self.pause_btn.Bind(wx.EVT_BUTTON, self.onPause) self.resume_btn.Bind(wx.EVT_BUTTON, self.onPause) time_label = SimpleText(panel, ' Time Range: ', minsize=(85, -1), style=LSTY) self.time_choice = MyChoice(panel, size=(120, -1), choices=('seconds', 'minutes', 'hours')) self.time_choice.SetStringSelection(self.timelabel) self.time_choice.Bind(wx.EVT_CHOICE, self.onTimeChoice) self.time_ctrl = FloatCtrl(panel, value=-self.tmin, precision=2, size=(90, -1), action=self.onTimeVal) btnsizer.Add(self.pause_btn, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER, 2) btnsizer.Add(self.resume_btn, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER, 2) btnsizer.Add(time_label, 1, wx.ALIGN_CENTER_HORIZONTAL, 2) btnsizer.Add(self.time_ctrl, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER, 2) btnsizer.Add(self.time_choice, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER, 2) panel.SetAutoLayout(True) panel.SetSizer(btnsizer) btnsizer.Fit(panel) def build_menus(self): mbar = wx.MenuBar() mfile = wx.Menu() mfile.Append(MENU_SAVE_DAT, "&Save Data\tCtrl+S", "Save PNG Image of Plot") mfile.Append(MENU_SAVE_IMG, "Save Plot Image\t", "Save PNG Image of Plot") mfile.Append(MENU_CLIPB, "&Copy Image to Clipboard\tCtrl+C", "Copy Plot Image to Clipboard") mfile.AppendSeparator() mfile.Append(MENU_PSETUP, 'Page Setup...', 'Printer Setup') mfile.Append(MENU_PREVIEW, 'Print Preview...', 'Print Preview') mfile.Append(MENU_PRINT, "&Print\tCtrl+P", "Print Plot") mfile.AppendSeparator() mfile.Append(MENU_EXIT, "E&xit\tCtrl+Q", "Exit the 2D Plot Window") mopt = wx.Menu() mopt.Append(MENU_CONFIG, "Configure Plot\tCtrl+K", "Configure Plot styles, colors, labels, etc") mopt.AppendSeparator() mopt.Append(MENU_UNZOOM, "Zoom Out\tCtrl+Z", "Zoom out to full data range") mhelp = wx.Menu() mhelp.Append(MENU_HELP, "Quick Reference", "Quick Reference for MPlot") mhelp.Append(MENU_ABOUT, "About", "About MPlot") mbar.Append(mfile, "File") mbar.Append(mopt, "Options") mbar.Append(mhelp, "&Help") self.SetMenuBar(mbar) self.Bind(wx.EVT_MENU, self.onSaveData, id=MENU_SAVE_DAT) self.Bind(wx.EVT_MENU, self.onHelp, id=MENU_HELP) self.Bind(wx.EVT_MENU, self.onAbout, id=MENU_ABOUT) self.Bind(wx.EVT_MENU, self.onExit, id=MENU_EXIT) self.Bind(wx.EVT_CLOSE, self.onExit) pp = self.plotpanel self.Bind(wx.EVT_MENU, pp.configure, id=MENU_CONFIG) self.Bind(wx.EVT_MENU, pp.unzoom_all, id=MENU_UNZOOM) self.Bind(wx.EVT_MENU, pp.save_figure, id=MENU_SAVE_IMG) self.Bind(wx.EVT_MENU, pp.Print, id=MENU_PRINT) self.Bind(wx.EVT_MENU, pp.PrintSetup, id=MENU_PSETUP) self.Bind(wx.EVT_MENU, pp.PrintPreview, id=MENU_PREVIEW) self.Bind(wx.EVT_MENU, pp.canvas.Copy_to_Clipboard, id=MENU_CLIPB) def AddPV_row(self): i = self.npv_rows = self.npv_rows + 1 panel = self.pvpanel sizer = self.pvsizer pvchoice = MyChoice(panel, choices=self.pvlist, size=(200, -1)) pvchoice.SetSelection(0) logs = MyChoice(panel) logs.SetSelection(0) ymin = wx.TextCtrl(panel, -1, '', size=(75, -1)) ymax = wx.TextCtrl(panel, -1, '', size=(75, -1)) if i > 2: logs.Disable() ymin.Disable() ymax.Disable() colval = (0, 0, 0) if i < len(self.default_colors): colval = self.default_colors[i] colr = csel.ColourSelect(panel, -1, '', colval) self.colorsels.append(colr) sizer.Add(pvchoice, (i, 0), (1, 1), LSTY, 3) sizer.Add(colr, (i, 1), (1, 1), CSTY, 3) sizer.Add(logs, (i, 2), (1, 1), CSTY, 3) sizer.Add(ymin, (i, 3), (1, 1), CSTY, 3) sizer.Add(ymax, (i, 4), (1, 1), CSTY, 3) pvchoice.Bind(wx.EVT_CHOICE, Closure(self.onPVchoice, row=i)) colr.Bind(csel.EVT_COLOURSELECT, Closure(self.onPVcolor, row=i)) logs.Bind(wx.EVT_CHOICE, self.onPVwid) ymin.Bind(wx.EVT_TEXT_ENTER, self.onPVwid) ymax.Bind(wx.EVT_TEXT_ENTER, self.onPVwid) self.pvchoices.append(pvchoice) self.pvwids.append((logs, colr, ymin, ymax)) def onTraceColor(self, trace, color, **kws): irow = self.get_current_traces()[trace][0] - 1 self.colorsels[irow].SetColour(color) def onPVshow(self, event=None, row=0): if not event.IsChecked(): trace = self.plotpanel.conf.get_mpl_line(row) trace.set_data([], []) self.plotpanel.canvas.draw() self.needs_refresh = True def onPVname(self, event=None): try: name = event.GetString() except AttributeError: return self.addPV(name) @EpicsFunction def addPV(self, name): if name is not None and name not in self.pvlist: pv = PV(str(name), callback=self.onPVChange) pv.get() conn = False if pv is not None: if not pv.connected: pv.wait_for_connection() conn = pv.connected msg = 'PV not found: %s' % name if conn: msg = 'PV found: %s' % name self.pvmsg.SetLabel(msg) if not conn: return self.pvlist.append(name) self.pvdata[name] = [(time.time(), pv.get())] i_new = len(self.pvdata) new_shown = False for choice in self.pvchoices: if choice is None: continue cur = choice.GetSelection() choice.Clear() choice.SetItems(self.pvlist) choice.SetSelection(cur) if cur == 0 and not new_shown: choice.SetSelection(i_new) new_shown = True self.needs_refresh = True @DelayedEpicsCallback def onPVChange(self, pvname=None, value=None, timestamp=None, **kw): if timestamp is None: timestamp = time.time() self.pvdata[pvname].append((timestamp, value)) self.needs_refresh = True def onPVchoice(self, event=None, row=None, **kws): self.needs_refresh = True for i in range(len(self.pvlist) + 1): try: trace = self.plotpanel.conf.get_mpl_line(row - 1) trace.set_data([], []) except: pass if row == 1: self.plotpanel.set_y2label('') self.plotpanel.canvas.draw() def onPVcolor(self, event=None, row=None, **kws): self.plotpanel.conf.set_trace_color(hexcolor(event.GetValue()), trace=row - 1) self.needs_refresh = True def onPVwid(self, event=None, row=None, **kws): self.needs_refresh = True def onTimeVal(self, event=None, value=None, **kws): new = -abs(value) if abs(new) < 0.1: new = -0.1 if abs(new - self.tmin) > 1.e-3 * max(new, self.tmin): self.tmin = new self.needs_refresh = True def onTimeChoice(self, event=None, **kws): newval = event.GetString() denom, num = 1.0, 1.0 if self.timelabel != newval: if self.timelabel == 'hours': denom = 3600. elif self.timelabel == 'minutes': denom = 60.0 if newval == 'hours': num = 3600. elif newval == 'minutes': num = 60.0 self.timelabel = newval timeval = self.time_ctrl.GetValue() self.time_ctrl.SetValue(timeval * denom / num) self.plotpanel.set_xlabel('Elapsed Time (%s)' % self.timelabel) self.needs_refresh = True def onPause(self, event=None): if self.paused: self.pause_btn.Enable() self.resume_btn.Disable() else: self.pause_btn.Disable() self.resume_btn.Enable() self.paused = not self.paused def write_message(self, s, panel=0): """write a message to the Status Bar""" self.SetStatusText(s, panel) def onSaveData(self, event=None): dlg = wx.FileDialog(self, message='Save Data to File...', defaultDir=os.getcwd(), defaultFile='PVStripChart.dat', style=wx.SAVE | wx.CHANGE_DIR) if dlg.ShowModal() == wx.ID_OK: path = dlg.GetPath() self.SaveDataFiles(path) self.write_message('Saved data to %s' % path) dlg.Destroy() def SaveDataFiles(self, path): basename, ext = os.path.splitext(path) if len(ext) < 2: ext = '.dat' if ext.startswith('.'): ext = ext[1:] for pvname, data in self.pvdata.items(): tnow = time.time() tmin = data[0][0] fname = [] for s in pvname: if s not in FILECHARS: s = '_' fname.append(s) fname = os.path.join("%s_%s.%s" % (basename, ''.join(fname), ext)) buff = ["# Epics PV Strip Chart Data for PV: %s " % pvname] buff.append("# Current Time = %s " % time.ctime(tnow)) buff.append("# Earliest Time = %s " % time.ctime(tmin)) buff.append("#------------------------------") buff.append("# Timestamp Value Time-Current_Time(s)") for tx, yval in data: buff.append(" %.3f %16g %.3f" % (tx, yval, tx - tnow)) fout = open(fname, 'w') fout.write("\n".join(buff)) fout.close() #dat = tnow, func(tnow) def onAbout(self, event=None): dlg = wx.MessageDialog(self, self.about_msg, "About Epics PV Strip Chart", wx.OK | wx.ICON_INFORMATION) dlg.ShowModal() dlg.Destroy() def onHelp(self, event=None): dlg = wx.MessageDialog(self, self.help_msg, "Epics PV Strip Chart Help", wx.OK | wx.ICON_INFORMATION) dlg.ShowModal() dlg.Destroy() def onExit(self, event=None): try: self.plotpanel.win_config.Close(True) self.plotpanel.win_config.Destroy() except: pass self.Destroy() def get_current_traces(self): "return list of current traces" traces = [] # to be shown for irow, s in enumerate(self.pvchoices): if s is not None: ix = s.GetSelection() if ix > 0: name = self.pvlist[ix] logs = 1 == self.pvwids[irow][0].GetSelection() color = self.pvwids[irow][1].GetColour() ymin = get_bound(self.pvwids[irow][2].GetValue()) ymax = get_bound(self.pvwids[irow][3].GetValue()) traces.append((irow, name, logs, color, ymin, ymax)) return traces def onUpdatePlot(self, event=None): if self.paused or not self.needs_refresh: return tnow = time.time() # set timescale sec/min/hour timescale = 1.0 if self.time_choice.GetSelection() == 1: timescale = 1. / 60 elif self.time_choice.GetSelection() == 2: timescale = 1. / 3600 ylabelset, y2labelset = False, False xlabel = 'Elapsed Time (%s)' % self.timelabel itrace = -1 update_failed = False hasplot = False span1 = (1, 0) did_update = False left_axes = self.plotpanel.axes right_axes = self.plotpanel.get_right_axes() for irow, pname, uselog, color, ymin, ymax in self.get_current_traces( ): if pname not in self.pvdata: continue itrace += 1 if len(self.plots_drawn) < itrace: self.plots_drawn.extend([False] * 3) side = 'left' if itrace == 1: side = 'right' data = self.pvdata[pname][:] if len(data) < 2: update_failed = True continue tdat = timescale * (array([i[0] for i in data]) - tnow) mask = where(tdat > self.tmin) if (len(mask[0]) < 2 or ((abs(min(tdat)) / abs(1 - self.tmin)) > 0.1)): data.append((time.time(), data[0][-1])) tdat = timescale * (array([i[0] for i in data]) - tnow) mask = where(tdat > self.tmin) i0 = mask[0][0] if i0 > 0: i0 = i0 - 1 i1 = mask[0][-1] + 1 tdat = timescale * (array([i[0] for i in data[i0:i1]]) - tnow) ydat = array([i[1] for i in data[i0:i1]]) if len(ydat) < 2: update_failed = True continue if ymin is None: ymin = min(ydat) if ymax is None: ymax = max(ydat) # for more that 2 plots, scale to left hand axis if itrace == 0: span1 = (ymax - ymin, ymin) if span1[0] * ymax < 1.e-6: update_failed = True continue elif itrace > 1: yr = abs(ymax - ymin) if yr > 1.e-9: ydat = span1[1] + 0.99 * (ydat - ymin) * span1[0] / yr ymin, ymax = min(ydat), max(ydat) if self.needs_refresh: if itrace == 0: self.plotpanel.set_ylabel(pname) elif itrace == 1: self.plotpanel.set_y2label(pname) if not self.plots_drawn[itrace]: plot = self.plotpanel.oplot if itrace == 0: plot = self.plotpanel.plot try: plot(tdat, ydat, drawstyle='steps-post', side=side, ylog_scale=uselog, color=color, xmin=self.tmin, xmax=0, xlabel=xlabel, label=pname, autoscale=False) self.plots_drawn[itrace] = True except: update_failed = True else: try: self.plotpanel.update_line(itrace, tdat, ydat, draw=False) self.plotpanel.set_xylims((self.tmin, 0, ymin, ymax), side=side, autoscale=False) did_update = True except: update_failed = True axes = left_axes if itrace == 1: axes = right_axes if uselog and min(ydat) > 0: axes.set_yscale('log', basey=10) else: axes.set_yscale('linear') self.plotpanel.set_title( time.strftime("%Y-%b-%d %H:%M:%S", time.localtime())) if did_update: self.plotpanel.canvas.draw() self.needs_refresh = update_failed return
def __init__(self, parent=None, *args, **kwds): wx.Frame.__init__(self, None, wx.ID_ANY, '', wx.DefaultPosition, wx.Size(-1, -1), **kwds) STY = wx.GROW | wx.ALL | wx.ALIGN_CENTER_VERTICAL LSTY = wx.ALIGN_LEFT | wx.ALL | wx.ALIGN_CENTER_VERTICAL CEN = wx.ALIGN_CENTER | wx.GROW | wx.ALL self.parent = parent cam_type = 'ad' if parent.cam_type.lower().startswith('web'): cam_type = 'web' sizer = wx.GridBagSizer(10, 2) panel = wx.Panel(self, style=wx.GROW) irow = 0 sizer.Add(wx.StaticLine(panel, size=(150, -1), style=wx.LI_HORIZONTAL), (irow, 0), (1, 2), CEN, 2) self.cam_type = wx.Choice(panel, -1, size=(150, -1), choices=CAM_CHOICES) self.cam_adform = wx.Choice(panel, -1, size=(150, -1), choices=AD_TYPES) self.cam_adform.SetSelection(0) self.cam_type.SetSelection({'web': 0, 'ad': 1}[cam_type]) self.cam_weburl = wx.TextCtrl(panel, value=parent.cam_weburl, size=(260, -1)) self.cam_adpref = wx.TextCtrl(panel, value=parent.cam_adpref, size=(260, -1)) self.image_dir = wx.TextCtrl(panel, value=parent.imgdir, size=(260, -1)) irow += 1 sizer.Add(SimpleText(panel, 'Image Sub Folder: '), (irow, 0), (1, 1), LSTY, 2) sizer.Add(self.image_dir, (irow, 1), (1, 1), LSTY, 2) irow += 1 sizer.Add(SimpleText(panel, 'Camera Type:'), (irow, 0), (1, 1), LSTY, 2) sizer.Add(self.cam_type, (irow, 1), (1, 1), LSTY, 2) irow += 1 sizer.Add(wx.StaticLine(panel, size=(150, -1), style=wx.LI_HORIZONTAL), (irow, 0), (1, 2), CEN, 2) irow += 1 sizer.Add(SimpleText(panel, 'Web Camera URL: '), (irow, 0), (1, 1), LSTY, 2) sizer.Add(self.cam_weburl, (irow, 1), (1, 1), LSTY, 2) irow += 1 sizer.Add(wx.StaticLine(panel, size=(150, -1), style=wx.LI_HORIZONTAL), (irow, 0), (1, 2), CEN, 2) irow += 1 sizer.Add(SimpleText(panel, 'Area Detector Format: '), (irow, 0), (1, 1), LSTY, 2) sizer.Add(self.cam_adform, (irow, 1), (1, 1), LSTY, 2) irow += 1 sizer.Add(SimpleText(panel, 'Area Detector Prefix: '), (irow, 0), (1, 1), LSTY, 2) sizer.Add(self.cam_adpref, (irow, 1), (1, 1), LSTY, 2) irow += 1 sizer.Add(wx.StaticLine(panel, size=(150, -1), style=wx.LI_HORIZONTAL), (irow, 0), (1, 2), CEN, 2) btn_ok = add_button(panel, 'Done', size=(70, -1), action=self.onOK) btn_cancel = add_button(panel, 'Cancel', size=(70, -1), action=self.onCancel) irow += 1 sizer.Add(btn_ok, (irow, 0), (1, 1), LSTY, 2) sizer.Add(btn_cancel, (irow, 1), (1, 1), LSTY, 2) pack(panel, sizer) mainsizer = wx.BoxSizer(wx.VERTICAL) mainsizer.Add(panel, 1, LSTY | STY) pack(self, mainsizer) self.Layout() self.Show() self.Raise() self.cam_type.Bind(wx.EVT_CHOICE, self.onCameraType) self.onCameraType()