×
Namespaces

Variants
Actions

Archived:How to Create Custom Multi-Selection Listbox for PySymbian

From Nokia Developer Wiki
Jump to: navigation, search

Archived.pngAquivado: Este artigo foi arquivado, pois o conteúdo não é mais considerado relevante para se criar soluções comerciais atuais. Se você achar que este artigo ainda é importante, inclua o template {{ForArchiveReview|escreva a sua justificativa}}.

All PySymbian articles have been archived. PySymbian is no longer maintained by Nokia and is not guaranteed to work on more recent Symbian devices. It is not possible to submit apps to Nokia Store.


Article Metadata
Tested with
Devices(s): Nokia N96
Compatibility
Platform(s): S60 3rd Edition
Article
Keywords: appuifw, listbox
Created: JOM (31 Mar 2009)
Last edited: hamishwillee (31 May 2013)

Contents

Introduction

This small PySymbian sample application demonstrates how to use

PySymbian offers great multi-selection listbox, with search, except it has one weakness: you cannot initialize the selections in advance. You start with no selections.

Here is a sample application to compare two built-in listboxes with one custom listbox. In every possible way the custom listbox is worse than built-in - except that you are able to initialize which items are selected at start.

The article contains code example demonstrating:

  • How to use built-in "Checkbox" multi-selection listbox
  • How to use built-in "Checkmark" multi-selection listbox
  • How to create your own multi-selection listbox, where you can initialize selections at start
  • How to use built-in checkbox icon graphics from two possible sources (webkit.mbm or avkon2.mbm)
  • How to report listbox selections
  • How to un-bind non-binded keys without crash


Code Snippet

'''
Multi-Selection List Test
 
1.10 2009-04-15 Simpler code to update custom listbox selection
1.00 2009-03-31 First release
'''

 
VERSION = u'1.10'
 
import e32
import appuifw
import key_codes
 
### keypress handler trick
import time
g_time = 0
my_timer = e32.Ao_timer()
 
# Application main body, appuifw.Text()
g_t = None
 
# List items for all listboxes
my_list = [u"One", u"Two", u"Three", u"Four", u"Five", u"Six"]
 
# Custom listbox related items, global or within class
lb3 = None # Listbox
e3 = [] # Entries: list items with icons
my_items = () # Save selections for next time
icon_on = None # Icon for selected checkbox
icon_off = None # Icon for non-selected checkbox
 
# Listbox icons, use built-in graphics
# See inside C:\Symbian\9.2\S60_3rd_FP1\Epoc32\include\avkonicons.hrh
# AVKON_ICON_FILE = u"z:\\resource\\apps\\avkon2.mbm"
 
# Listbox 1
# - Perfect, except cannot initialize selections
# - Search field works great
 
def menu_list1():
''' Built-in multi-selection listbox '''
items = appuifw.multi_selection_list(my_list, style='checkbox', search_field=1)
# Show what happened
appuifw.note(u"Selected: %s" % items)
 
# Listbox 2
# - Nice, use shift + scrolling to select several items
 
def menu_list2():
''' Built-in multi-selection listbox '''
items = appuifw.multi_selection_list(my_list, style='checkmark')
# Show what happened
appuifw.note(u"Selected: %s" % items)
 
# Listbox custom, lots of work
# - Checkbox icon for listbox (get_checkbox)
# - Handle selection on listbox (cb_select)
# - Handle closing listbox (cb_return)
# - Initialize and draw listbox (menu_list3)
# - Missing search field
 
def get_checkbox(a_value):
''' Checkbox icon: selected or not '''
global icon_on, icon_off
# Create only once, reuse after that
if not icon_on:
# See avkon2.mbm content (old version)
# http://alindh.iki.fi/symbian/avkon2.mbm/
 
try:
# webkit checkbox looks better, but might not exist
icon_off = appuifw.Icon(u"z:\\resource\\apps\\webkit.mbm", 12, 31)
icon_on = appuifw.Icon(u"z:\\resource\\apps\\webkit.mbm", 13, 32)
except:
# Counting on avkon2 to be there, hopefully with checkbox
icon_off = appuifw.Icon(u"z:\\resource\\apps\\avkon2.mbm", 103, 104)
icon_on = appuifw.Icon(u"z:\\resource\\apps\\avkon2.mbm", 109, 110)
 
if a_value:
return icon_on
else:
return icon_off
 
def cb_select():
''' Callback for listbox item selection event '''
 
### keypress handler trick, to allow Enter/Select work
global g_time
my_timer.cancel()
# Ignore first and non-timer trickered events
if (not g_time) or (time.clock() - g_time < 0.1):
g_time = time.clock()
# Should be more than start keyrepeat rate
my_timer.after(0.15, cb_select)
return
g_time = 0
### keypress handler trick, done
 
# Current listbox selection
index = lb3.current()
 
# Change selected item icon: on <-> off
if e3[index][1] == icon_on:
new_icon = icon_off
else:
new_icon = icon_on
 
e3[index] = (e3[index][0], new_icon)
 
# Show new list, same item selected
lb3.set_list(e3, index)
appuifw.app.body = lb3
 
# Make it visible
e32.ao_yield()
 
def cb_return():
''' Closing listbox, clean up and bring back main view '''
# Restore Main view
global appuifw
appuifw.app.body = g_t
appuifw.app.menu = self_options[0]
appuifw.app.exit_key_handler = cb_quit
 
# Save selections from listbox
global my_items
my_items = tuple(i for i,x in enumerate(e3) if x[1] == icon_on)
 
# Show what happened
appuifw.note(u"Selected: %s" % my_items)
 
def menu_list3():
''' Custom multi-selection listbox '''
global e3, lb3
e3 = []
 
# Mark initial selections
for item in range(len(my_list)):
if item in my_items:
icon = get_checkbox(item in my_items)
else:
icon = get_checkbox(False)
e3.append((my_list[item], icon))
 
global appuifw
lb3 = appuifw.Listbox(e3, cb_select)
appuifw.app.body = lb3
appuifw.app.menu = self_options[1]
appuifw.app.exit_key_handler = cb_return
 
# Several ways to select item
# BUG: One press of Enter/Select gives two events: KeyDown and KeyUp
# BUG: ...or even 3+ with key repeat
# Fix: write own key handler, react only on KeyUp event
# Fix: use timer to separate "one" key press
lb3.bind(key_codes.EKeyRightArrow, cb_select)
lb3.bind(key_codes.EKeyEnter, cb_select)
lb3.bind(key_codes.EKeySelect, cb_select)
 
def menu_about():
''' Callback for menu item About '''
appuifw.note(u'Multi-selection List Test v' + VERSION + u'\n' +\
u'jouni.miettunen.googlepages.com\n\u00a92009 Jouni Miettunen')
 
def cb_quit():
''' Cleanup before exit '''
# ALWAYS cancel your timers before exit.
my_timer.cancel()
 
# User might NOT have initialized lb3 in custom listbox
# Crash when unbinding non-binded keys
global e3, lb3, icon_on, icon_off
try:
lb3.bind(key_codes.EKeyRightArrow, None)
lb3.bind(key_codes.EKeyEnter, None)
lb3.bind(key_codes.EKeySelect, None)
except:
pass
 
# Help system clean-up, delete stuff by yourself
e3 = []
del lb3
del icon_on
del icon_off
 
# Done, continue exit
app_lock.signal()
 
# Initialize application UI
self_options = [
[
(u"Checkbox", menu_list1),
(u"Checkmark", menu_list2),
(u"Custom", menu_list3),
(u"About", menu_about),
(u"Exit", cb_quit)
],
[
(u"Change", cb_select),
(u"Back", cb_return)
]
]
 
# Hox: no need to fix as portrait screen
# Supports automatic screen rotation as-is (N82)
appuifw.app.title = u'Multi-selection List Test'
appuifw.app.exit_key_handler = cb_quit
appuifw.app.menu = self_options[0]
 
# Create UI control and initilize instructions
g_t = appuifw.Text()
g_t.style = appuifw.STYLE_BOLD
g_t.add(u"Select listbox from Options menu:\n\n")
g_t.add(u"Checkbox: ")
g_t.style = 0
g_t.add(u"built-in listbox, looks nice, cannot initialize selections\n")
g_t.style = appuifw.STYLE_BOLD
g_t.add(u"Checkmark:")
g_t.style = 0
g_t.add(u"built-in listbox, cannot initialize selections\n")
g_t.style = appuifw.STYLE_BOLD
g_t.add(u"Custom: ")
g_t.style = 0
g_t.add(u"Looks plain, can initialize selections!\n")
 
# Show to user
appuifw.app.body = g_t
 
# Wait for user to do anything
app_lock = e32.Ao_lock()
app_lock.wait()

Screenshot

T mslist 100 1.jpg T mslist 100 2.jpg T mslist 100 3.jpg T mslist 100 4.jpg T mslist 100 5.jpg T mslist 100 6.jpg

Related Link

Archived:How to use Listbox in PySymbian

Archived:A 100% PySymbian Listbox base class

This page was last modified on 31 May 2013, at 04:03.
113 page views in the last 30 days.