def main(): from ui import Image i = Image.named('test:Lenna') with open('test.png', 'wb') as f: f.write(i.to_png()) contextc = EAGL.EAGLContext(EAGL.RenderingAPI.OpenGLES2) GLKit.setRenderEngine(Renderer()) glviewv.setDelegate(GLKit.GLKViewDelegate()) glviewv.setContext(contextc) glviewv.present("sheet")
def contentFromC(aCContent): if aCContent is None: return None elif aCContent.isKindOfClass(UIColor): return RGBA(aCContent.red(), aCContent.green(), aCContent.blue(), aCContent.alpha()) elif aCContent.isKindOfClass(ObjCClass('UIImage')): c.UIImagePNGRepresentation.argtypes = [c_void_p] c.UIImagePNGRepresentation.restype = c_void_p data = ObjCInstance(c.UIImagePNGRepresentation(aCContent.ptr)) return Image.from_data(nsdata_to_bytes(data), 2.0) elif aCContent.isKindOfClass(NSArray): if aCContent.objectAtIndex(0).isKindOfClass(ObjCClass('UIImage')): imageArray = [] c.UIImagePNGRepresentation.argtypes = [c_void_p] c.UIImagePNGRepresentation.restype = c_void_p for i in range(aCContent.count()): aCImg = aCContent.objectAtIndex(i) if aCImg.isKindOfClass(ObjCClass('UIImage')): data = ObjCInstance(c.UIImagePNGRepresentation(aCImg.ptr)) imageArray.append( Image.from_data(nsdata_to_bytes(data), 2.0)) return imageArray elif aCContent.isKindOfClass(NSURL): return str(aCContent.absoluteString()) else: pass return aCContent
def main(): from ui import Image USER_APPS = 0 SYSTEM_APPS = 1 UIImage = ObjCClass('UIImage') allApps = defaultWorkspace.applicationsOfType_(USER_APPS) for i, app in enumerate(allApps): #print('hidden' in str(app.appTags())) console.write_link( '{} : {}, version {}. By {}'.format(app.bundleIdentifier(), app.localizedName(), app.shortVersionString(), app.vendorName()), 'pythonista://{}?action=run&argv={}'.format( __file__.rsplit('/Pythonista3/Documents/')[-1], app.bundleIdentifier())) Image.from_data( uiimage_to_png( UIImage._applicationIconImageForBundleIdentifier_format_scale_( app.bundleIdentifier(), 1, 100))).show() print('\n')
def createRecordButton(self): """ """ # TODO : Use centered button. container = Panel(orientation='horizontal', padding=30) button = Image('resources/icons/record.png') button.onClick = lambda: self.capture() container.add(button) self.sidebar.add(container)
def createImage(self, imageUrl): image = Image(imageUrl) image.setStyleName("ks-images-Image") p = VerticalPanel() p.setHorizontalAlignment(HasAlignment.ALIGN_CENTER) p.setVerticalAlignment(HasAlignment.ALIGN_MIDDLE) p.add(image) return p
def makeicon(c1, c2, name): gradient = makegradient(c1, c2, appsize) # hack to support partial transparency uii = UIImage.named(name) data = io.BytesIO(uii.to_png()) top = PILImage.open(data) icon = composite(top, gradient, offset) data.close() with io.BytesIO() as bIO: icon.save(bIO, 'PNG') img = UIImage.from_data(bIO.getvalue()) return img
def __init__(self): inner = Grid(10, 5) outer = FlexTable() outer.setWidget( 0, 0, Image(self.baseURL() + "rembrandt/LaMarcheNocturne.jpg")) outer.getFlexCellFormatter().setColSpan(0, 0, 2) outer.getFlexCellFormatter().setHorizontalAlignment( 0, 0, HasHorizontalAlignment.ALIGN_CENTER) outer.setHTML( 1, 0, "Look to the right...<br>That's a nested table component ->") outer.setWidget(1, 1, inner) outer.getCellFormatter().setColSpan(1, 1, 2) for i in range(10): for j in range(5): inner.setText(i, j, "" + i + "," + j) inner.setWidth("100%") outer.setWidth("100%") inner.setBorderWidth(1) outer.setBorderWidth(1) self.setWidget(outer)
def __init__(self): DialogBox.__init__(self) # Use this opportunity to set the dialog's caption. self.setText("About the Mail Sample") # Create a DockPanel to contain the 'about' label and the 'OK' button. outer = DockPanel() outer.setSpacing(4) outer.add(Image(AboutDialog.LOGO_IMAGE), DockPanel.WEST) # Create the 'OK' button, along with a listener that hides the dialog # when the button is clicked. Adding it to the 'south' position within # the dock causes it to be placed at the bottom. buttonPanel = HorizontalPanel() buttonPanel.setHorizontalAlignment(HasAlignment.ALIGN_RIGHT) buttonPanel.add(Button("Close", self)) outer.add(buttonPanel, DockPanel.SOUTH) # Create the 'about' label. Placing it in the 'rest' position within the # dock causes it to take up any remaining space after the 'OK' button # has been laid out. textplain = "This sample application demonstrates the construction " textplain += "of a complex user interface using pyjamas' built-in widgets. Have a look " textplain += "at the code to see how easy it is to build your own apps!" text = HTML(textplain) text.setStyleName("mail-AboutText") outer.add(text, DockPanel.CENTER) # Add a bit of spacing and margin to the dock to keep the components from # being placed too closely together. outer.setSpacing(8) self.add(outer)
def plot(self): fig = BytesIO() if self.plt3D: figure = plt.figure() ax = figure.add_subplot(111, projection='3d') xs, ys, zs = self.ys for n in range(len(xs)): ax.plot_wireframe(xs[n], ys[n], zs[n]) plt.savefig(fig) return Image.from_data(fig.getvalue()) else: for n in range(len(self.ys)): plt.step(self.ranges[self.vars[0]][n], self.ys[n]) plt.savefig(fig) return Image.from_data(fig.getvalue())
def __init__(self, style, name, line, column, level, breadcrumb): super().__init__('{}{}'.format(level * ' ', name), '{} (line {})'.format(breadcrumb, line)) self.style = style self.name = name self.line = line self.column = column self.level = level self.breadcrumb = breadcrumb self.image = Image(style)
def __init__(self): img = Image("images/num1.png") img.addMouseListener(TooltipListener("An image: " + img.getUrl())) img2 = Image("images/num2.png") img2.addMouseListener(TooltipListener("An image: " + img2.getUrl())) html = HTML("Some <i>HTML</i> text.") html.addMouseListener(TooltipListener("An HTML component.")) panel_h = HorizontalPanel() panel_h.add(img) panel_h.add(img2) panel_h.setSpacing(8) panel = VerticalPanel() panel.add(panel_h) panel.add(html) panel.setSpacing(8) self.setWidget(panel)
def createModeController(self): """ Creates and configures widget for booth mode controller. """ photo = Image('resources/icons/photo.png') video = Image('resources/icons/video.png') self.mode.add(photo) self.mode.add(self.modeLabel) self.mode.add(video) photo.onClick = lambda: self.setMode(PHOTO_MODE) video.onClick = lambda: self.setMode(VIDEO_MODE)
def createSettings(self): """ Creates and configures widget for photo configuration. """ self.effects = self.camera.effects() self.currentEffect = 0 effectPanel = Panel(orientation='horizontal', padding=0) effectPanel.add(Image('resources/icons/filter.png')) container = Panel(orientation='horizontal', padding=10) prevEffect = Label('<', size='large') nextEffect = Label('>', size='large') self.effectLabel = Label(self.effects[self.currentEffect], size='large') container.add(prevEffect) container.add(self.effectLabel) container.add(nextEffect) effectPanel.add(container) self.sidebar.add(effectPanel)
def __init__(self, contact): # The popup's constructor's argument is a boolean specifying that it # auto-close itself when the user clicks outside of it. PopupPanel.__init__(self, True) inner = VerticalPanel() nameLabel = Label(contact.name) emailLabel = Label(contact.email) inner.add(nameLabel) inner.add(emailLabel) panel = HorizontalPanel() panel.setSpacing(4) panel.add(Image(contact.photo)) panel.add(inner) self.add(panel) self.setStyleName("mail-ContactPopup") nameLabel.setStyleName("mail-ContactPopupName") emailLabel.setStyleName("mail-ContactPopupEmail")
def analyse_data(fname, load_time, rest_time, interactive=False): t, f = np.loadtxt(fname).T tmeans, durations, _, fmeans, e_fmeans = measure_mean_loads(t, f) print(tmeans, fmeans) factor = load_time / (load_time + rest_time) load_asymptote = np.nanmean(fmeans[-5:-1]) e_load_asymptote = np.nanstd(fmeans[-5:-1]) / np.sum( np.isfinite(fmeans[-5:-1])) critical_load = load_asymptote * factor e_critical_load = critical_load * (e_load_asymptote / load_asymptote) used_in_each_interval = ( fmeans - critical_load) * load_time - critical_load * rest_time used_alternative = (fmeans - critical_load) * durations - critical_load * ( load_time + rest_time - durations) wprime = np.sum(used_in_each_interval) wprime_alt = np.sum(used_alternative) remaining = wprime_alt - np.cumsum(used_alternative) # force constant alpha = np.median((fmeans - load_asymptote) / remaining) msg = 'peak load = {:.2f} +/- {:.2f} kg\n'.format(fmeans[0], e_fmeans[0]) msg += 'critical load = {:.2f} +/- {:.2f} kg\n'.format( critical_load, e_critical_load) msg += 'asymptotic load = {:.2f} +/- {:.2f} kg\n'.format( load_asymptote, e_load_asymptote) msg += "W'' = {:.0f} J\n".format(9.8 * np.sum(used_in_each_interval)) msg += "W'' (alt) = {:.0f} J\n".format(9.8 * wprime_alt) msg += 'Anaerobic function score = {:.1f}'.format(wprime_alt / critical_load) fmax = f.max() predicted_force = load_asymptote + remaining * ( fmax - load_asymptote) / wprime_alt #predicted_force = load_asymptote + alpha * remaining plt.rcParams.update({'font.size': 12}) fig, axis = plt.subplots() axis.plot(t, f, alpha=0.5) axis.errorbar(tmeans, fmeans, yerr=e_fmeans, fmt='o') axis.axhline(critical_load, label='critical load') axis.axhline(load_asymptote, label='asymptotic load') axis.plot(tmeans, predicted_force, label='predicted max force') axis.fill_between(tmeans, load_asymptote, predicted_force, color='g', alpha=0.3, label="W''") axis.set_xlabel('Time since start (s)') axis.set_ylabel('Load (kg)') plt.legend() axis.set_ylim(bottom=10) if interactive: print(msg) plt.show() return b = BytesIO() plt.savefig(b) plt.close('all') img = Image.from_data(b.getvalue()) return msg, img
class Reader: ITEM_H = 70 WIDTH_LINE = 337 LOADING = Image.named('iob:load_d_32') LOADING_HEIGHT = WIDTH_LINE / LOADING.size.x * LOADING.size.y def __init__(self, scrollview, tableview): self.var_ebook_loader = EImgLoader(dict_conf) self.has_sent_req = False self.scrollview = scrollview self.tableview = tableview self.queue = Queue() self.items = deque(self.scrollview.subviews) assert (len(self.items) - 1) * self.ITEM_H > scrollview.height self.init_subviews(url) def load_img(self, init=False): imgs, title, url = self.var_ebook_loader.get_one_img() self.queue.put((imgs, title, url, init)) def check_title(self): off_set = self.cur_offset for item in self.items: if item.y + item.height >= off_set: i = item.i if i is None: continue for l, r, name, url in self.titles: if l <= i < r: nav_view.name = name return def add2contents(self): if not self.queue.empty(): imgs, title, url, init = self.queue.get() if imgs is None: console.hud_alert('已经阅读完毕') return False l = len(self.contents) # 保证进度条不会完全到底 sum_height = -10 if init else 0 for img in imgs: resized_height = self.WIDTH_LINE / img.size.x * img.size.y sum_height += resized_height self.contents.append((img, resized_height)) r = len(self.contents) if self.titles: # merge 当一个页面多个图片 last_title = self.titles[-1] if last_title[3] == url: self.titles[-1] = (last_title[0], r, title, url) else: self.titles.append((l, r, title, url)) else: self.titles.append((l, r, title, url)) self.scrollview.content_size += (0, sum_height) self.has_sent_req = False return True return False def load_img_bg(self): if not self.has_sent_req: self.has_sent_req = True self.t = threading.Thread(target=self.load_img) self.t.start() def init_subviews(self, url, i=0, j=0): if self.has_sent_req: self.t.join() self.has_sent_req = False self.queue = Queue() scrollview = self.scrollview scrollview.content_size = (scrollview.width, 0) self.cur_offset = 0 # [(image, resized_height),] self.contents = [] # (l, r, name) self.titles = [] self.var_ebook_loader.init_url(url) self.load_img(True) self.add2contents() # 条件应该是把一页填充满而且书签模式下尽量加载 while scrollview.content_size.y <= scrollview.height or len( self.contents) <= i: self.load_img() self.add2contents() # print(scrollview.content_size) rows = i len_content = len(self.contents) len_items = len(self.items) y = 0 start = max(0, len_items - len_content) remain = islice(self.items, start, len_items) for i, (item, content) in enumerate(zip(remain, self.contents)): img, resize_height = content item.height = resize_height item.image = img item.i = i item.y = y y += resize_height # 未使用的item往上放 y = 0 if len_content < len_items: end = len_items - len_content - 1 for i in range(end, -1, -1): item = self.items[i] item.i = None item.image = None y -= item.height item.y = y # 书签偏移量 h = 0 for content in self.contents[:rows]: img, resize_height = content h += resize_height # 这个破玩意儿改了之后会自动调用监听函数 scrollview.content_offset = (0, h + j) self.check_title() def reset_scrollbar(self): scrollview = self.scrollview offset_x, offset_y = scrollview.content_offset max_offset = scrollview.content_size.y - scrollview.height cur_offset = offset_y min_offset = min(cur_offset, max_offset) scrollview.content_offset = (offset_x, min_offset) def scrollview_did_scroll(self, scrollview): offset = scrollview.content_offset.y is_scroll_down = True if offset > self.cur_offset else False self.cur_offset = offset reader_h = scrollview.height # print('t') content_size = scrollview.content_size[1] # 预加载 if content_size and content_size - self.cur_offset <= 4 * reader_h: self.load_img_bg() # 滚动条下移 if is_scroll_down: while True: item_end = self.items[-1] item_start = self.items[0] if (item_end.y + item_end.height - reader_h <= offset and item_end.i is not None): # console.hud_alert('应该load') i = item_end.i + 1 if i >= len(self.contents): img = self.LOADING resized_height = self.LOADING_HEIGHT self.load_img_bg() i = None else: img, resized_height = self.contents[i] item_start.image = img item_start.y = item_end.y + item_end.height item_start.height = resized_height item_start.i = i self.items.rotate(-1) elif item_end.i is None and item_end.y <= offset + reader_h: # console.hud_alert(f'应该refresh') if not self.add2contents(): break item = self.items[-2] i = item.i + 1 if i < len(self.contents): img, resized_height = self.contents[i] item_end.image = img item_end.y = item.y + item.height item_end.height = resized_height item_end.i = i # 这个防止空白页吧……会有吗? else: break else: break else: while True: item_end = self.items[-1] item_start = self.items[0] if item_start.y >= offset: # None的时候仅仅是初始化设计导致的 if item_start.i is None or item_start.i <= 0: break i = item_start.i - 1 img, resized_height = self.contents[i] item_end.image = img item_end.height = resized_height item_end.y = item_start.y - resized_height item_end.i = i self.items.rotate(1) else: break self.check_title()
def image(self): # TODO - Find a way how get the right icon, because there's # lot of prefixes like iob:, different sizes, ... image = Image.named('iob:play_32') return image
import base64 from ui import Image import console import sys import io sys.stderr = io.StringIO() console.show_activity('Creating images…') imagefilenames = [os.path.splitext(i)[0] for i in open(os.path.expanduser('~/Pythonista.app/Typicons-M.txt')).readlines()] imagenames = [i.replace('Typicons96_', '') for i in imagefilenames] images = {n: Image.named(imagefilenames[i]) for (i, n) in enumerate(imagenames)} imageurls = {k:'data:image/png;base64,'+base64.b64encode(images[k].to_png()) for k in images} choosecolorpath = os.path.dirname(sys.argv[0].split('/Documents/',1)[1]) + '/choosecolor.py' tagtemplate = '<a href="pythonista://' +choosecolorpath+ '?action=run&argv=%s"><img src="%s"></a>' imagetags = [tagtemplate%(k,imageurls[k]) for k in imagenames] imagesstring = ''.join(imagetags) html = ''' <!DOCTYPE html> <html> <head>
bm_view = ui.load_view('bookmark') nav_view = ui.NavigationView(reader_view) tb = bm_view['tableview'] tb.data_source.items = dict_bm['bookmarks'] tb.data_source.edit_action = conf_loader.refresh_file for i in range(18): sc.add_subview(reader_view[f'label{i}']) var = Reader(sc, tb) var_bm_table_viewer = BMTableViewer(var) sc.delegate = var tb.delegate = var_bm_table_viewer reader_view['button_save_bm'].action = var_bm_table_viewer.save_bm nav_view.navigation_bar_hidden = True nav_view.present('fullscreen') return_button_item = ui.ButtonItem( image=Image.named('iob:arrow_return_left_24')) bm_button_items = [return_button_item] nav_view.right_button_items = bm_button_items return_button_item.action = nav_view.pop_view reader_view['button_show_bm'].action = lambda _: nav_view.push_view(bm_view) menu_button_item = ui.ButtonItem(image=Image.named('iob:navicon_round_24')) main_button_items = [menu_button_item] menu_button_item.action = nav_view.pop_view
t = GLKEffectPropertyTexture() print t print t.enabled print t.envMode print t.name print t.target ti = GLKTextureInfo() print ti print ti.name print ti.target print ti.height print ti.containsMipmaps from ui import Image as image i = image.named('test:Lenna') d = i.to_png() with open('test.png', 'wb') as f: f.write(d) t = (ctypes.c_char_p * len(d)) pt = t() pt[:] = d[:] tid = loadTexture('test:Lenna') print tid from OpenGLES.Util.Shader import ShaderProgram from OpenGLES.Util.Shader import ShaderSource with open("../shader.vs", "rb") as f: v = ShaderSource(f.read(), ES3.GL_VERTEX_SHADER) with open("../shader.fs", "rb") as f: f = ShaderSource(f.read(), ES3.GL_FRAGMENT_SHADER)
class EImgBodyViewer: ITEM_H = 70 WIDTH_LINE = 337 LOADING = Image.named('iob:load_d_32') LOADING_HEIGHT = WIDTH_LINE / LOADING.size.x * LOADING.size.y def __init__(self, parent): reader_view = ui.load_view('ebody_viewer/eimg_body') scrollview = reader_view['scrollview'] for i in range(9): # print(reader_view[f'imageview{i}']) scrollview.add_subview(reader_view[f'imageview{i}']) scrollview.delegate = self self.has_sent_req = False self.scrollview = scrollview self.reader_view = reader_view self.items = deque(self.scrollview.subviews) assert (len(self.items) - 1) * self.ITEM_H > scrollview.height self.parent = parent def req_data_bg(self): self.parent.req_data_bg(self) def req_data(self, init=False): self.parent.req_data(self, init) def set_navi_view_name(self, name): self.parent.set_navi_view_name(name) def refresh_title(self): off_set = self.cur_offset for item in self.items: if item.y + item.height >= off_set: i = item.i if i is None: continue for l, r, name, url in self.titles: if l <= i < r: self.set_navi_view_name(name) return def load_data(self): element = self.parent.load_data(self) if element is None: return False if element[0] is None: # 到底之后不再复位self.has_sent_req console.hud_alert('已经阅读完毕') return False l = len(self.contents) imgs, title, url, init = element # 保证进度条不会完全到底 sum_height = -10 if init else 0 for img in imgs: resized_height = self.WIDTH_LINE / img.size.x * img.size.y sum_height += resized_height self.contents.append((img, resized_height)) r = len(self.contents) if self.titles: # merge 当一个页面多个图片 last_title = self.titles[-1] if last_title[3] == url: self.titles[-1] = (last_title[0], r, title, url) else: self.titles.append((l, r, title, url)) else: self.titles.append((l, r, title, url)) self.scrollview.content_size += (0, sum_height) self.has_sent_req = False return True def reset_view(self, i=0, j=0): scrollview = self.scrollview # [(image, resized_height),] self.contents = [] # (l, r, name) self.titles = [] scrollview.content_size = (scrollview.width, 0) self.cur_offset = 0 self.req_data(True) self.load_data() # 条件应该是把一页填充满而且书签模式下尽量加载 while scrollview.content_size.y <= scrollview.height or len( self.contents) <= i: self.req_data() self.load_data() # print(scrollview.content_size) rows = i len_content = len(self.contents) len_items = len(self.items) y = 0 start = max(0, len_items - len_content) remain = islice(self.items, start, len_items) for i, (item, content) in enumerate(zip(remain, self.contents)): img, resize_height = content item.height = resize_height item.image = img item.i = i item.y = y y += resize_height # 未使用的item往上放 y = 0 if len_content < len_items: end = len_items - len_content - 1 for i in range(end, -1, -1): item = self.items[i] item.i = None item.image = None y -= item.height item.y = y # 书签偏移量 h = 0 for content in self.contents[:rows]: img, resize_height = content h += resize_height # 这个破玩意儿改了之后会自动调用监听函数 scrollview.content_offset = (0, h + j) self.refresh_title() def get_offset(self): scrollview = self.scrollview off_set = scrollview.content_offset.y i = None for item in self.items: if item.y + item.height >= off_set: i = item.i j = off_set - item.y break if i is None: return for l, r, name, url in self.titles: if l <= i < r: # 本页的i 相对段落数目 new_bookmark = { 'i': i - l, 'j': int(j), 'url': url, 'title': name } return new_bookmark def reset_scrollbar(self): scrollview = self.scrollview offset_x, offset_y = scrollview.content_offset max_offset = scrollview.content_size.y - scrollview.height cur_offset = offset_y min_offset = min(cur_offset, max_offset) scrollview.content_offset = (offset_x, min_offset) def scrollview_did_scroll(self, scrollview): offset = scrollview.content_offset.y is_scroll_down = True if offset > self.cur_offset else False self.cur_offset = offset reader_h = scrollview.height # print('t') content_size = scrollview.content_size[1] if not content_size: return # 预加载 if content_size - self.cur_offset <= 4 * reader_h: self.req_data_bg() # 滚动条下移 if is_scroll_down: while True: item_end = self.items[-1] item_start = self.items[0] if (item_end.y + item_end.height - reader_h <= offset and item_end.i is not None): # console.hud_alert('应该load') i = item_end.i + 1 if i >= len(self.contents): img = self.LOADING resized_height = self.LOADING_HEIGHT self.req_data_bg() i = None else: img, resized_height = self.contents[i] item_start.image = img item_start.y = item_end.y + item_end.height item_start.height = resized_height item_start.i = i self.items.rotate(-1) elif item_end.i is None and item_end.y <= offset + reader_h: # console.hud_alert(f'应该refresh') if not self.load_data(): break item = self.items[-2] i = item.i + 1 if i < len(self.contents): img, resized_height = self.contents[i] item_end.image = img item_end.y = item.y + item.height item_end.height = resized_height item_end.i = i # 这个防止空白页吧……会有吗? else: break else: break else: while True: item_end = self.items[-1] item_start = self.items[0] if item_start.y >= offset: # None的时候仅仅是初始化设计导致的 if item_start.i is None or item_start.i <= 0: break i = item_start.i - 1 img, resized_height = self.contents[i] item_end.image = img item_end.height = resized_height item_end.y = item_start.y - resized_height item_end.i = i self.items.rotate(1) else: break self.refresh_title()
def __init__(self, url="", load_listener=None): Image.__init__(self, url) if load_listener: self.addLoadListener(load_listener) self.onAttach()
def __init__(self): self.curImage=0 self.image=Image() self.loadingImage = Image(self.baseURL() + "images/blanksearching.gif") self.nextButton = Image(self.baseURL() + "rembrandt/forward.gif") self.prevButton = Image(self.baseURL() + "rembrandt/back.gif") self.sImages=["rembrandt/JohannesElison.jpg", "rembrandt/LaMarcheNocturne.jpg", "rembrandt/SelfPortrait1628.jpg", "rembrandt/SelfPortrait1640.jpg", "rembrandt/TheArtistInHisStudio.jpg", "rembrandt/TheReturnOfTheProdigalSon.jpg"] for i in range(len(self.sImages)): self.sImages[i]=self.baseURL() + self.sImages[i] self.image.addLoadListener(self) self.prevButton.addClickListener(self) self.nextButton.addClickListener(self) topPanel = DockPanel() topPanel.setVerticalAlignment(HasAlignment.ALIGN_MIDDLE) topPanel.add(self.prevButton, DockPanel.WEST) topPanel.add(self.nextButton, DockPanel.EAST) topPanel.add(self.loadingImage, DockPanel.CENTER) panel = VerticalPanel() panel.setHorizontalAlignment(HasAlignment.ALIGN_CENTER) panel.add(HTML("<h2>A Bit of Rembrandt</h2>", True)) panel.add(topPanel) panel.add(self.image) panel.setWidth("100%") self.setWidget(panel) self.image.setStyleName("ks-images-Image") self.nextButton.setStyleName("ks-images-Button") self.prevButton.setStyleName("ks-images-Button") self.loadImage(0)