def onModuleLoad(self): self.remote_py = MyBlogService() # Create a FormPanel and point it at a service. self.form = FormPanel() # Create a panel to hold all of the form widgets. vp=VerticalPanel(BorderWidth=0,HorizontalAlignment=HasAlignment.ALIGN_CENTER,VerticalAlignment=HasAlignment.ALIGN_MIDDLE,Width="100%",Height="150px") self.form.setWidget(vp) header=HTML("<h2>LOGIN TO YOUR ACCOUNT</h2>") part1=header # Create a TextBox, giving it a name so that it will be submitted. self.userName = TextBox() self.userName.setName("userNameFormElement") self.userName.setPlaceholder("User Name") part2=self.userName self.password = PasswordTextBox() self.password.setName("passwordFormElement") self.password.setPlaceholder("Password") part3=self.password self.errorInfoLabel = Label() self.errorInfoLabel.setStyleName('error-info') part4=self.errorInfoLabel part4.setStyleName("errorlabel") # Add a 'submit' button. hpanel = HorizontalPanel(BorderWidth=0,HorizontalAlignment=HasAlignment.ALIGN_CENTER,VerticalAlignment=HasAlignment.ALIGN_MIDDLE,Width="100%",Height="50px") partb=Button("Login", self) partb.setStyleName('btn') image=Label("Don''t have account? Sign up") anchor = Anchor(Widget=image, Href='/signup.html') parta=anchor hpanel.add(partb) hpanel.add(parta) part5=hpanel part5.setStyleName("hpanel") vp.add(part1) vp.add(part2) vp.add(part3) vp.add(part4) vp.add(part5) vp.setStyleName("signup") # Add an event handler to the form. self.form.addFormHandler(self) RootPanel().add(self.form)
class Projects_Editor(SimplePanel): ''' Create and edit projects ''' def __init__(self): # We need to use old form of inheritance because of pyjamas SimplePanel.__init__(self) self.hpanel = HorizontalPanel(Width='475px') self.hpanel.setVerticalAlignment(HasAlignment.ALIGN_BOTTOM) self.name = TextBox() self.name.setStyleName('form-control') self.status = ListBox() self.status.addItem('Active') self.status.addItem('Inactive') self.status.setVisibleItemCount(0) self.status.setStyleName('form-control input-lg') self.status.setSize('100px', '34px') lbl = Label('', Width='10px') self.add_btn = Button('Add') self.add_btn.setStyleName('btn btn-primary') self.del_btn = Button('Delete') self.del_btn.setStyleName('btn btn-danger') self.hpanel.add(self.name) self.hpanel.add(lbl) self.hpanel.add(self.status) self.hpanel.add(self.add_btn) self.hpanel.add(self.del_btn) def get_name_txt(self): '''Return project name. ''' return self.name.getText() def get_status(self): '''Return project status. ''' return self.status.getItemText(self.status.getSelectedIndex())
class ContentItemToolbar(HorizontalPanel): def __init__(self, contentitem, onPublish, onLike, onDislike): """Create a ContentItemToolbar. Event handlers should be methods that take: sender """ HorizontalPanel.__init__(self) self.contentitem = contentitem self.publishBtn = Button('Publish', listener=onPublish, StyleName=Styles.TOOLBAR_BUTTON) self.add(self.publishBtn) self.likeBtn = Button('FOO', listener=onLike, StyleName=Styles.TOOLBAR_BUTTON) self.add(self.likeBtn) self.dislikeBtn = Button('Dislike', listener=onDislike, StyleName=Styles.TOOLBAR_BUTTON) self.add(self.dislikeBtn) self.updateStatusFromItem() return def updateStatusFromItem(self, updatedItem=None): if updatedItem: self.contentitem = updatedItem likes = self.contentitem['metadata']['likes'] self.likeBtn.setText('Like (%s)' % likes) isPublished = self.contentitem['metadata']['is_published'] self.publishBtn.setStyleName(Styles.TOOLBAR_BUTTON_PUBLISHED if isPublished else Styles.TOOLBAR_BUTTON)
def onModuleLoad(self): loggedInUser = getCookie("LoggedInUser") loggedInUserJsonData = json.loads(loggedInUser) self.username = loggedInUserJsonData["username"] self.remote_py = MyBlogService() dockPanel = DockPanel(BorderWidth=0, Padding=0, HorizontalAlignment=HasAlignment.ALIGN_CENTER, VerticalAlignment=HasAlignment.ALIGN_MIDDLE) dockPanel.setSize('100%', '100%') headerDockPanel = DockPanel( BorderWidth=0, Padding=0, HorizontalAlignment=HasAlignment.ALIGN_LEFT, VerticalAlignment=HasAlignment.ALIGN_CENTER) headerDockPanel.setStyleName('header') headerDockPanel.setWidth('100%') dockPanel.add(headerDockPanel, DockPanel.NORTH) dockPanel.setCellHeight(headerDockPanel, '60px') self.siteImage = Image("/images/Testware_logo.png") self.siteImage.setStyleName('logo-image') headerDockPanel.add(self.siteImage, DockPanel.WEST) headerDockPanel.setCellWidth(self.siteImage, '30%') self.pageTitle = Label('New Blog') self.pageTitle.setStyleName('center-header') headerDockPanel.add(self.pageTitle, DockPanel.CENTER) headerDockPanel.setCellWidth(self.pageTitle, '40%') rightHeaderPanel = VerticalPanel(StyleName='right-header') headerDockPanel.add(rightHeaderPanel, DockPanel.EAST) headerDockPanel.setCellWidth(rightHeaderPanel, '30%') welcomeNoteLabel = Label('Hi %s %s!' % (loggedInUserJsonData["first_name"], loggedInUserJsonData["last_name"])) rightHeaderPanel.add(welcomeNoteLabel) logoutAnchor = Anchor(Widget=HTML('Logout'), Href='/', Title='Logout') logoutAnchor.setStyleName('logout') rightHeaderPanel.add(logoutAnchor) panel = HorizontalPanel(StyleName="header2") dockPanel.add(panel, DockPanel.NORTH) dockPanel.setCellHeight(panel, '50px') self.blogTitle = TextBox() self.blogTitle.setStyleName('blog-title') self.blogTitle.setPlaceholder("Blog Title") panel.add(self.blogTitle) self.blogContent = TextArea() self.blogContent.setStyleName('blog-content') dockPanel.add(self.blogContent, DockPanel.CENTER) createBlogButton = Button("Create Blog", self) createBlogButton.setStyleName('btn') panel.add(createBlogButton) RootPanel().add(dockPanel)
class kMeans(Algorithm): def __init__(self): Algorithm.__init__(self) self.MLAlgorithmService = MLAlgorithmService(self) self.image = Image(self.baseURL() + "services/kMeansPictures/lenna.png", Width="320px", Height="360px") self.resultImage = Image("", Width="320px", Height="360px") self.loadingImage = Image(self.baseURL() + "images/blanksearching.gif") self.calculateButton = Button("RUN", self.onButtonClick) self.log = Button("SHOW LOG", self.openLogFile) self.log.setEnabled(False) self.image.addLoadListener(self) topPanel = DockPanel() topPanel.setVerticalAlignment(HasAlignment.ALIGN_MIDDLE) topPanel.add(self.calculateButton, DockPanel.WEST) topPanel.add(self.loadingImage, DockPanel.CENTER) topPanel.add(self.log, DockPanel.EAST) panel = DockPanel() panel.setHorizontalAlignment(HasAlignment.ALIGN_CENTER) panel.setVerticalAlignment(HasAlignment.ALIGN_MIDDLE) #panel.add(HTML("<h2>Image compression</h2>", True)) panel.add(topPanel, DockPanel.NORTH) panel.add(self.image, DockPanel.WEST) panel.add(self.resultImage, DockPanel.EAST) panel.setWidth("100%") self.initWidget(panel) self.image.setStyleName("ks-images-Image") self.calculateButton.setStyleName("ks-images-Button") self.loadImage("picturem.png") def onButtonClick(self, sender): Window.alert("Starting image compression...") self.MLAlgorithmService.callMethod("lenna.png") def onError(self, sender): pass def onLoad(self, sender=None): self.loadingImage.setUrl(self.baseURL() + "images/blanksearching.gif") def loadImage(self, picture): self.loadingImage.setUrl(self.baseURL() + "images/searching.gif") self.image.setUrl(self.baseURL() + "services/kMeansPictures/lenna.png") self.resultImage.setUrl(self.baseURL() + "services/kMeansPictures/lenna.png") self.resultImage.setUrl(self.baseURL() + "services/kMeansPictures/" + picture) def onImageClicked(self): Window.alert("picture!") def openLogFile(self, sender): ###TODO: make logging output fileLocation = self.baseURL() + "services/contactjson.txt" dlg = FileOpenDlg(fileLocation=fileLocation) dlg.show() def showStatus(self, msg): Window.alert(msg)
class kMeans(Algorithm): def __init__(self): Algorithm.__init__(self) self.MLAlgorithmService = MLAlgorithmService(self) self.image=Image(self.baseURL() + "services/kMeansPictures/lenna.png",Width="320px", Height="360px") self.resultImage=Image("",Width="320px", Height="360px") self.loadingImage = Image(self.baseURL() + "images/blanksearching.gif") self.calculateButton = Button("RUN", self.onButtonClick) self.log = Button("SHOW LOG", self.openLogFile) self.log.setEnabled(False) self.image.addLoadListener(self) topPanel = DockPanel() topPanel.setVerticalAlignment(HasAlignment.ALIGN_MIDDLE) topPanel.add(self.calculateButton, DockPanel.WEST) topPanel.add(self.loadingImage, DockPanel.CENTER) topPanel.add(self.log, DockPanel.EAST) panel = DockPanel() panel.setHorizontalAlignment(HasAlignment.ALIGN_CENTER) panel.setVerticalAlignment(HasAlignment.ALIGN_MIDDLE) #panel.add(HTML("<h2>Image compression</h2>", True)) panel.add(topPanel, DockPanel.NORTH) panel.add(self.image, DockPanel.WEST) panel.add(self.resultImage, DockPanel.EAST) panel.setWidth("100%") self.initWidget(panel) self.image.setStyleName("ks-images-Image") self.calculateButton.setStyleName("ks-images-Button") self.loadImage("picturem.png") def onButtonClick(self, sender): Window.alert("Starting image compression...") self.MLAlgorithmService.callMethod("lenna.png") def onError(self, sender): pass def onLoad(self, sender=None): self.loadingImage.setUrl(self.baseURL() + "images/blanksearching.gif") def loadImage(self, picture): self.loadingImage.setUrl(self.baseURL() + "images/searching.gif") self.image.setUrl(self.baseURL() + "services/kMeansPictures/lenna.png") self.resultImage.setUrl(self.baseURL() + "services/kMeansPictures/lenna.png") self.resultImage.setUrl(self.baseURL() + "services/kMeansPictures/" + picture) def onImageClicked(self): Window.alert("picture!") def openLogFile(self, sender): ###TODO: make logging output fileLocation = self.baseURL() + "services/contactjson.txt" dlg = FileOpenDlg(fileLocation=fileLocation) dlg.show() def showStatus(self, msg): Window.alert(msg)
class Input_Form(Abstract_View): '''Input form that modifies itself depending on the proejct. ''' def __init__(self): Abstract_View.__init__(self) self.dev_fields = Dev_Fields() def register(self, controller): '''Register controller for view and its subviews''' self.controller = controller self.dev_fields.register(controller) def onModuleLoad(self): '''Create initial view of the panel. ''' # Container that keeps everything self.panel = VerticalPanel() self.panel.setSpacing(10) # Create list of projects proj_list = ListBox(Height='34px') proj_list.addItem('') proj_list.setVisibleItemCount(0) proj_list.addChangeListener(getattr(self, 'on_project_changed')) proj_list.setStyleName('form-control input-lg') self.proj_row = Form_Row('Select project', proj_list, help='project, status of which you want to report') # Project-specific container self.project_panel = VerticalPanel() # Submit report button self.submit_btn = Button('Submit report', getattr(self, 'send_data')) self.submit_btn.setStyleName('btn btn-primary btn-lg') self.submit_btn.setEnabled(False) self.msg_lbl = HTMLPanel('', Width='475px') # Add controls here self.panel.add(self.proj_row.panel()) self.panel.add(self.project_panel) self.panel.add(Label(Height='20px')) self.panel.add(self.msg_lbl) btn_holder = HorizontalPanel() btn_holder.add(self.submit_btn) help_btn = HTMLPanel('') help_btn.setHTML(MODAL_PNL) btn_holder.add(Label(Width='10px')) btn_holder.add(help_btn) self.panel.add(btn_holder) self.root = RootPanel('report') self.root.add(self.panel) def _load_project(self, project): '''Load project specific fields in the panel ''' if self.dev_fields is not None: self.project_panel.remove(self.dev_fields) # Remove the old one and add brand new self.dev_fields = Dev_Fields() self.project_panel.add(self.dev_fields) def send_data(self): '''Retrieve data for the active project fields and send to flask. ''' #data = self.dev_fields.prep_data() self.controller.process_msg(SEND_DATA_MSG) def on_project_changed(self, event): '''Change form fields depending on the proejct. ''' proj_list = self.proj_row.widget() project = proj_list.getItemText(proj_list.getSelectedIndex()) if project != '': self.controller.process_msg(PROJ_CHANGED_MSG, project)
class Dev_Fields(VerticalPanel, Abstract_View): '''Fields for a development project: Status Impediment Desc Status: Open | Closed Comment Risks Milestone Name Target End Date Actual End Date ''' def __init__(self): '''Initialize widget''' VerticalPanel.__init__(self) Abstract_View.__init__(self) # Keep list of all milestones, we will add milestones from controller # when we create the form self.milestone_names = [] # Corresponding dates self.milestone_dates = [] # These two variables keep track of added milestone and impediments objects self.milestones = [] self.impediments = [] self.status_area = Text_Area_Row('Status', help='status of the project') # Keeps milestones self.main_mlst_panel = VerticalPanel() hp_mlst = HorizontalPanel() self.add_milestone_btn = Button('Add', getattr(self, 'on_add_milestone_btn_click')) self.add_milestone_btn.setStyleName('btn btn-info') self.remove_milestone_btn = Button('Remove', getattr(self, 'remove_milestone')) self.remove_milestone_btn.setStyleName('btn btn-danger') milestone_panel = VerticalPanel() self.milestone_row = Form_Row('Milestones', milestone_panel, help='add milestone and provide expected completion date') hp_mlst.add(Label(Width='330px')) hp_mlst.add(self.add_milestone_btn) hp_mlst.add(Label(Width='10px')) hp_mlst.add(self.remove_milestone_btn) self.main_mlst_panel.add(self.milestone_row.panel()) self.main_mlst_panel.add(hp_mlst) self.risks_area = Text_Area_Row('Risks', help='short / long term risks') # Keeps impediments self.main_impd_panel = VerticalPanel() hp_impd = HorizontalPanel() self.add_impediment_btn = Button('Add', getattr(self, 'add_impediment')) self.add_impediment_btn.setStyleName('btn btn-info') # Remove button self.remove_impediment_btn = Button('Remove', getattr(self, 'remove_impediment')) self.remove_impediment_btn.setStyleName('btn btn-danger') impediment_panel = VerticalPanel() self.impediment_row = Form_Row('Impediments', impediment_panel, help='add impediments, one per section, please') hp_impd.add(Label(Width='330px')) hp_impd.add(self.add_impediment_btn) hp_impd.add(Label(Width='10px')) hp_impd.add(self.remove_impediment_btn) self.main_impd_panel.add(self.impediment_row.panel()) self.main_impd_panel.add(hp_impd) # Add those to itself self.add(self.status_area.panel()) self.add(self.risks_area.panel()) self.add(self.main_mlst_panel) self.add(self.main_impd_panel) def on_add_milestone_btn_click(self): '''Inform controller we want to add a milestone. ''' self.controller.process_msg(ADD_MLS_MSG) def add_milestone(self): '''Add milestone to the development project. ''' # Pass list of milestones when we create the row milestone = Milestones_Row(self.milestone_names, self.milestone_dates) self.milestone_row.widget().add(Label(Height='5px')) self.milestone_row.widget().add(milestone.hpanel) self.milestones.append(milestone) def remove_milestone(self, sender): '''Remove milestone. ''' try: self.milestones[-1].hpanel.removeFromParent() self.milestones.remove(self.milestones[-1]) except IndexError: pass def add_impediment(self, sender): '''Add impediment to the development project. ''' today_date = datetime.date.today().strftime('%d/%m/%Y') impediment = Impediments(today_date) self.impediment_row.widget().add(impediment.vpanel) self.impediments.append(impediment) def remove_impediment(self, sender): '''Remove impediment. ''' try: if self.impediments[-1].can_delete == True: self.impediments[-1].vpanel.removeFromParent() self.impediments.remove(self.impediments[-1]) else: self.controller.process_msg(CANT_DEL_IMP_MSG) pass except IndexError: pass
class Milestones_Editor(SimplePanel): ''' Create and edit projects ''' def __init__(self): # We need to use old form of inheritance because of pyjamas SimplePanel.__init__(self) self.hpanel = HorizontalPanel(Width='755px') self.hpanel.setVerticalAlignment(HasAlignment.ALIGN_TOP) self.name = TextBox() self.name.setStyleName('form-control') self.start = Report_Date_Field(cal_ID='start') self.start.getTextBox().setStyleName('form-control') self.start.setRegex(DATE_MATCHER) self.start.appendValidListener(self._display_ok) self.start.appendInvalidListener(self._display_error) self.start.validate(None) self.end = Report_Date_Field(cal_ID='end') self.end.getTextBox().setStyleName('form-control') self.end.setRegex(DATE_MATCHER) self.end.appendValidListener(self._display_ok) self.end.appendInvalidListener(self._display_error) self.end.validate(None) self.status = ListBox() self.status.addItem('Active') self.status.addItem('Inactive') self.status.setVisibleItemCount(0) self.status.setStyleName('form-control input-lg') self.status.setSize('100px', '34px') spacer1 = Label(Width='10px') spacer2 = Label(Width='10px') spacer3 = Label(Width='10px') self.add_btn = Button('Add') self.add_btn.setStyleName('btn btn-primary') self.del_btn = Button('Delete') self.del_btn.setStyleName('btn btn-danger') self.hpanel.add(self.name) self.hpanel.add(spacer1) self.hpanel.add(self.status) self.hpanel.add(spacer2) self.hpanel.add(self.start) #self.hpanel.add(spacer3) self.hpanel.add(self.end) self.hpanel.add(self.add_btn) self.hpanel.add(Label(Width='10px')) self.hpanel.add(self.del_btn) def get_name_txt(self): '''Return project name. ''' return self.name.getText() def get_status(self): '''Return project status. ''' return self.status.getItemText(self.status.getSelectedIndex()) def get_milestone_data(self): '''Return all data for a milestone and validation result. ''' valid = False name_txt = self.get_name_txt() status_txt = self.get_status() start_txt = self.start.getTextBox().getText() end_txt = self.end.getTextBox().getText() data = [name_txt, status_txt, start_txt, end_txt] # We are only valid if these conditions are met if len(name_txt.strip()) > 0 and self.start.valid == True and self.end.valid == True: valid = True return (valid, data) def _display_ok(self, obj): obj.setStyleName('form-input') def _display_error(self, obj): if len(obj.getTextBox().getText()) > 0: obj.setStyleName('form-group has-error')
class Milestones_View(Abstract_View): def __init__(self): '''Project editor view. ''' Abstract_View.__init__(self) def onModuleLoad(self): '''Create initial view of the panel. ''' # Container that keeps everything self.panel = VerticalPanel() self.panel.setSpacing(10) spacer1 = Label() spacer1.setHeight('10px') spacer2 = Label() spacer2.setHeight('10px') self.tbl_panel = VerticalPanel(Width='755px') # First is a row count self.grid = Reports_Grid() self.grid.create_grid(1, 4, ['Milestone Name', 'Milestone State', 'Start Date', 'End Date']) self.tbl_panel.add(self.grid) self.editor = Milestones_Editor() self.submit_btn = Button('Submit', getattr(self, 'send_data')) self.submit_btn.setStyleName('btn btn-primary btn-lg') hpanel = HorizontalPanel() hpanel.setHorizontalAlignment(HasAlignment.ALIGN_RIGHT) hpanel.add(self.submit_btn) self.msg_lbl = HTMLPanel('', Width='755px') self.root = RootPanel('projects_') self.root.add(spacer1) self.root.add(self.editor.hpanel) self.root.add(spacer2) self.root.add(self.tbl_panel) spacer3 = Label() spacer3.setHeight('20px') self.root.add(self.msg_lbl) self.root.add(spacer3) self.root.add(hpanel) self.root.add(Label(Height='20px')) # Add listeners and initialize components self._add_listeners() self._iniate_states() def _add_listeners(self): '''Register listeners here. ''' self.editor.add_btn.addClickListener(getattr(self, 'on_add_btn_click')) self.editor.del_btn.addClickListener(getattr(self, 'on_del_btn_click')) self.editor.name.addKeyboardListener(self) def _iniate_states(self): self.editor.add_btn.setEnabled(False) self.editor.del_btn.setEnabled(False) self.editor.name.setFocus(True) def register(self, controller): '''Register controller for a view and related controls. ''' self.controller = controller self.grid.register(controller) self.editor.start.register(controller) self.editor.end.register(controller) def on_add_btn_click(self, event): '''Process click on Add button. ''' (valid, data) = self.editor.get_milestone_data() if self.editor.add_btn.getText() == 'Add': self.controller.process_msg(ADD_ROW_MSG, data) else: self.controller.process_msg(EDT_ROW_MSG, self.grid.selected_row, data) def on_del_btn_click(self, event): '''Process click on Add button. ''' if self.grid.selected_row > 0: self.controller.process_msg(DEL_ROW_MSG, self.grid.selected_row) def send_data(self): '''Notify controller that we need to send data to db and let it do the work''' self.controller.process_msg(COMMIT_MLS_MSG) def onKeyDown(self, sender, keycode, modifiers): pass def onKeyUp(self, sender, keycode, modifiers): # We are managing view control states here, though might send # a message to controller as well, but since we are not passing any data, # we do not bother about controller (valid, data) = self.editor.get_milestone_data() #Window.alert('Valid is {0}, data is {1}'.format(valid, data)) if valid: self.editor.add_btn.setEnabled(True) else: self.editor.add_btn.setEnabled(False) def onKeyPress(self, sender, keycode, modifiers): '''Let users input using keyboard. ''' (valid, data) = self.editor.get_milestone_data() if keycode == KeyboardListener.KEY_ESCAPE: pass # TODO: should we do something useful here? elif keycode == KeyboardListener.KEY_ENTER: if self.editor.add_btn.getText() == 'Add' and self.editor.add_btn.isEnabled(): self.controller.process_msg(ADD_ROW_MSG, data) elif self.editor.add_btn.getText() == 'Change' and self.editor.add_btn.isEnabled(): self.controller.process_msg(EDT_ROW_MSG, self.grid.selected_row, data)
def onModuleLoad(self): self.form = FormPanel() self.remote_py = MyBlogService() self.form.setAction("/index.html") vp = VerticalPanel(BorderWidth=0, HorizontalAlignment=HasAlignment.ALIGN_CENTER, VerticalAlignment=HasAlignment.ALIGN_MIDDLE, Width="100%", Height="150px") self.form.setWidget(vp) header = HTML( "<h2>CREATE MY ACCOUNT</h2><h3>Welcome to signup form</h3>") part1 = header hpn = HorizontalPanel(BorderWidth=0, HorizontalAlignment=HasAlignment.ALIGN_LEFT, VerticalAlignment=HasAlignment.ALIGN_MIDDLE, Width="92%", Height="60px") self.fname = TextBox() self.fname.setName("fname") self.fname.setPlaceholder("First Name") hpn.add(self.fname) self.lname = TextBox() self.lname.setName("lname") self.lname.setPlaceholder("Last Name") hpn.add(self.lname) hpn.setCellWidth(self.fname, "70%") hpn.setCellWidth(self.lname, "30%") part2 = hpn self.uname = TextBox() self.uname.setName("uname") self.uname.setPlaceholder("User Name") part3 = self.uname self.password = PasswordTextBox() self.password.setName("passsignup") self.password.setPlaceholder("Choose a password") part4 = self.password self.rpassword = PasswordTextBox() self.rpassword.setName("rpasssignup") self.rpassword.setPlaceholder("Confirm your password") part5 = self.rpassword self.email = TextBox() self.email.setName("emailsignup") self.email.setPlaceholder("Enter your email address ") part6 = self.email self.errorlabel = Label() self.errorlabel.setStyleName("errorlabel") part7 = self.errorlabel hpanel = HorizontalPanel(BorderWidth=0, HorizontalAlignment=HasAlignment.ALIGN_CENTER, VerticalAlignment=HasAlignment.ALIGN_MIDDLE, Width="100%", Height="50px") partb = Button("Signup", self) partb.setStyleName('btn') image = Label("Already have account! Sign in") anchor = Anchor(Widget=image, Href='/index.html') parta = anchor hpanel.add(partb) hpanel.add(parta) hpanel.setStyleName("hpanel") part8 = hpanel vp.add(part1) vp.add(part2) vp.add(part3) vp.add(part4) vp.add(part5) vp.add(part6) vp.add(part7) vp.add(part8) vp.setCellHeight(part1, "5%") vp.setCellHeight(part2, "10%") vp.setCellHeight(part3, "10%") vp.setCellHeight(part4, "10%") vp.setCellHeight(part5, "10%") vp.setCellHeight(part6, "10%") vp.setCellHeight(part7, "10%") vp.setCellHeight(part8, "10%") vp.setStyleName("signup") self.form.addFormHandler(self) RootPanel().add(self.form)