import wx _width = 376 _height = 380 # wxPython GUI implementation class GUI: def __init__(self): self.checkboxes = [] self.comboboxes = [] self.textfields = [] def doInstaller(self, model): self.model = model self.app = wx.App() # Create Window self.window = wx.Frame(None, title=model.title, size=(_width, _height), style=wx.DEFAULT_FRAME_STYLE & ~ (wx.MINIMIZE_BOX | wx.RESIZE_BOX | wx.MAXIMIZE_BOX |wx.RESIZE_BORDER)) window_box = wx.BoxSizer(wx.VERTICAL) self.window.SetSizer(window_box) # Add logo logoBitmap = wx.Image(model.logo, wx.BITMAP_TYPE_PNG).ConvertToBitmap() logo = wx.StaticBitmap(self.window, -1, logoBitmap) window_box.Add(logo, 0, wx.CENTER, border=5) # Notebook notebook = wx.Notebook(self.window) window_box.Add(notebook, 10, wx.EXPAND) # Create tabs for tab in model.tabs: t = wx.Panel(notebook) notebook.AddPage(t, tab.label) self._do_tab(t, tab) #Add buttons but_box = wx.BoxSizer(wx.HORIZONTAL) window_box.Add(but_box, 1, wx.EXPAND) for button in model.buttons: but = wx.Button(self.window, label=button.label) but.pmodel = button but.Bind(wx.EVT_BUTTON, self.callback_button) but_box.Add(but, 1, wx.EXPAND) # Show everything self.window.Centre() self.window.Show() self.app.MainLoop() # Configure one tab def _do_tab(self, container, tab): # Create box box = wx.BoxSizer(wx.VERTICAL) container.SetSizer(box) # Add text if hasattr(tab, 'text'): txt = wx.StaticText(container, -1, tab.text) box.Add(txt, 0) # Add groups for group in tab.groups: # the panel for the group panel = wx.Panel(container) box.Add(panel, 0, wx.EXPAND) # the group and the sizer g = wx.StaticBox(panel, -1, group.label) vbox = wx.StaticBoxSizer(g, wx.VERTICAL) # checkboxes orientation if group.orientation == 'horizontal': cb_box = wx.BoxSizer(wx.HORIZONTAL) else: cb_box = wx.BoxSizer(wx.VERTICAL) vbox.Add(cb_box) # add checkboxes for checkbox in group.checkboxes: cb = wx.CheckBox(panel, -1, checkbox.label) cb.SetValue(checkbox.checked) cb_box.Add(cb) cb.pmodel = checkbox self.checkboxes.append(cb) # Add comboboxes for combo in group.comboboxes: l = wx.StaticText(panel, -1, combo.label) c = wx.ComboBox(panel, -1, choices=combo.options, style=wx.CB_READONLY) c.SetValue(combo.selected) cbox = wx.BoxSizer(wx.HORIZONTAL) vbox.Add(cbox) cbox.Add(l, 0, wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, 4) cbox.Add(c, 1) c.pmodel = combo self.comboboxes.append(c) # Add TextFields # TODO make expandable and dynamic textfields textfield_width = 70 for textfield in group.textfields: l = wx.StaticText(panel, -1, textfield.label, size=(textfield_width,25)) t = wx.TextCtrl(panel, -1, textfield.value, size=(_width-textfield_width-20, 25)) cbox = wx.BoxSizer(wx.HORIZONTAL) vbox.Add(cbox) cbox.Add(l, 0, wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, 2) cbox.Add(t, 1, wx.EXPAND) t.pmodel = textfield self.textfields.append(t) # extra config panel.SetAutoLayout(True) panel.SetSizer(vbox) vbox.Fit(panel) vbox.SetSizeHints(panel) #/doGroups # Response functions def callback_button(self, event): self.update_model() button = event.GetEventObject() button.pmodel.callback() # Iterate over components and update model def update_model(self): for c in self.checkboxes: c.pmodel.checked = c.GetValue() for c in self.comboboxes: c.pmodel.selected = c.GetValue() for t in self.textfields: t.pmodel.value = t.GetValue() def quit(self): #TODO this return ## EXECUTOR def doExecutor(self, e): self.window.Hide() # Create Window self.window = wx.Frame(None, title=e.title, size=(_width, 450), style=wx.DEFAULT_FRAME_STYLE & ~ (wx.MINIMIZE_BOX | wx.RESIZE_BOX | wx.MAXIMIZE_BOX |wx.RESIZE_BORDER)) window_box = wx.BoxSizer(wx.VERTICAL) self.window.SetSizer(window_box) # Add logo logoBitmap = wx.Image(e.logo, wx.BITMAP_TYPE_PNG).ConvertToBitmap() logo = wx.StaticBitmap(self.window, -1, logoBitmap) window_box.Add(logo, 0, wx.CENTER, border=5) # Console control variables self.remove_next_line = False self.last_line_position = -1 # Add console self.console = wx.TextCtrl(self.window, -1, size=(self.window.GetSize()[0] -4, 100) , style=wx.TE_MULTILINE|wx.TE_READONLY| wx.HSCROLL | wx.TE_RICH2) window_box.Add(self.console, 12, wx.CENTER, border=5) #Add buttons but_box = wx.BoxSizer(wx.HORIZONTAL) window_box.Add(but_box, 1, wx.EXPAND) self.buttons = [] for button in e.buttons: but = wx.Button(self.window, label=button.label) but.pmodel = button but.Bind(wx.EVT_BUTTON, self.callback_button) self.buttons.append(but) but_box.Add(but, 1, wx.EXPAND) # Show everything self.window.Centre() self.window.Show() def write_command_line(self, line): wx.CallAfter(self.wx_write_command_line, line) def wx_write_command_line(self, line): # Finished installation, change button if line == "END": # TODO how do we change button text? #self.buttons[0].SetString("Close") return # Delete last line if it is \r if self.remove_next_line and line != '\n': self.console.Remove(self.last_line_position, self.console.GetLastPosition()) self.remove_next_line = False # Double spaces if line[0:2] == ' ': line = " " + line elif line[0:1] == ' ': line = " " + line # Detect styles style = self.console.GetDefaultStyle() bold = style.GetFont() bold.SetWeight(wx.FONTWEIGHT_BOLD) if line[0:2] == '# ': style = wx.TextAttr("BLACK", wx.NullColour, bold) line = line[2:] elif line == "[ OK ]\n": style = wx.TextAttr("BLUE", wx.NullColour, bold) elif line[0:3] == '!! ': style = wx.TextAttr("RED", wx.NullColour, bold) line = line[2:] # Save last position, write, apply style self.last_line_position = self.console.GetLastPosition() self.console.AppendText(line) self.console.SetStyle(self.last_line_position, self.console.GetLastPosition(), style) if line[-1] == '\r': self.remove_next_line = True