What steps will reproduce the problem? 1. Create your own KeyboardLayout. 2. Add it with add_custom_layout(Layout()) 3. Start the Keyboard with MTVKeyboard(layout = 'Layout.ID')
What is the expected output?
The Keyboard with my layout.
What do you see instead?
Traceback (most recent call last):
File "start.py", line 91, in <module>
pymt.runTouchApp(baseWidget)
File "/usr/lib/python2.6/site-packages/pymt/base.py", line 352, in runTouchApp
pymt_window.mainloop()
File "/usr/lib/python2.6/site-packages/pymt/ui/window/win_pygame.py", line 124, in mainloop
evloop.idle()
File "/usr/lib/python2.6/site-packages/pymt/base.py", line 201, in idle
pymt_window.dispatch_event('on_draw')
File "/usr/lib/python2.6/site-packages/pymt/event.py", line 344, in dispatch_event
if func(*args):
File "/usr/lib/python2.6/site-packages/pymt/ui/window/init.py", line 355, in on_draw
w.dispatch_event('on_draw')
File "/usr/lib/python2.6/site-packages/pymt/event.py", line 344, in dispatch_event
if func(*args):
File "/usr/lib/python2.6/site-packages/pymt/ui/widgets/widget.py", line 360, in on_draw
w.dispatch_event('on_draw')
File "/usr/lib/python2.6/site-packages/pymt/event.py", line 344, in dispatch_event
if func(*args):
File "/usr/lib/python2.6/site-packages/pymt/ui/widgets/scatter.py", line 141, in on_draw
super(MTScatterWidget, self).on_draw()
File "/usr/lib/python2.6/site-packages/pymt/ui/widgets/widget.py", line 357, in on_draw
self.draw()
File "/usr/lib/python2.6/site-packages/pymt/ui/widgets/composed/vkeyboard.py", line 433, in draw
self._update()
File "/usr/lib/python2.6/site-packages/pymt/ui/widgets/composed/vkeyboard.py", line 335, in _update
layoutmode = '%s:%s' % (self.layout.ID, self.mode)
AttributeError: 'str' object has no attribute 'ID'
What version of the product are you using? On what operating system? I use PyMT 0.4 but I saw the bug in the git too. I use Archlinux
Please provide any additional information below. This error came because of this line in pymt/ui/widgets/composed/vkeyboard.py self.layout = kwargs.get('layout') You shuffle things because you use the same variable for the object and the id for the layout. Replace: # read default layout in configuration if self.layout is None: idlayout = pymt.pymt_config.get('keyboard', 'layout') # search layout for layout in MTVKeyboard.available_layout: if layout.ID == idlayout: self.layout = layout() break # no layout found ? if self.layout is None: pymt.pymt_logger.warning('Vkeyboard: Keyboard layout <%s> not found, fallback on QWERTY' % idlayout) self.layout = KeyboardLayoutQWERTY() With: layout_id = self.layout self.layout = None
# read default layout in configuration
if layout_id == None:
layout_id = pymt.pymt_config.get('keyboard', 'layout')
# search layout
for layout in MTVKeyboard.available_layout:
if layout.ID == layout_id:
self.layout = layout
break
# no layout found ?
if self.layout == None:
pymt.pymt_logger.warning('Vkeyboard: Keyboard layout <%s> not found, fallback on QWERTY' % layout_id)
self.layout = KeyboardLayoutQWERTY()
And you will see that it works.
Comment #1
Posted on Jul 4, 2010 by Quick BirdThanks for reporting the bug!
Can I get the layout to test it?
Comment #2
Posted on Jul 4, 2010 by Grumpy MonkeyI copied one of the standard layouts and changed only the header information. Here is it: class KeyboardLayoutQWERTZ(KeyboardLayout): '''Implementation of QWERTZ Layout''' ID = 'qwertz' TITLE = 'Qwertz' DESCRIPTION = 'A classical German Keyboard' # Need to be comment out because I don't defined kbdlayout_default_font #FONT_FILENAME = kbdlayout_default_font NORMAL_1 = [ ('~', '~', None, 1), ('!', '!', None, 1), ('@', '@', None, 1), ('#', '#', None, 1), ('$', '$', None, 1), ('%', '%', None, 1), ('^', '^', None, 1), ('&', '&', None, 1), ('', '', None, 1), ('(', '(', None, 1), (')', ')', None, 1), ('', '', None, 1), ('+', '+', None, 1), (u'\u232b', None, 'backspace', 2), ] NORMAL_2 = [ (u'\u21B9', chr(0x09), None, 1.5), ('q', 'q', None, 1), ('w', 'w', None, 1), ('e', 'e', None, 1), ('r', 'r', None, 1), ('t', 't', None, 1), ('y', 'y', None, 1), ('u', 'u', None, 1), ('i', 'i', None, 1), ('o', 'o', None, 1), ('p', 'p', None, 1), ('{', '{', None, 1), ('}', '}', None, 1), ('|', '|', None, 1.5) ] NORMAL_3 = [ (u'\u21ea', None, 'capslock', 1.8), ('a', 'a', None, 1), ('s', 's', None, 1), ('d', 'd', None, 1), ('f', 'f', None, 1), ('g', 'g', None, 1), ('h', 'h', None, 1), ('j', 'j', None, 1), ('k', 'k', None, 1), ('l', 'l', None, 1), (':', ':', None, 1), ('"', '"', None, 1), (u'\u23ce', None, 'enter', 2.2), ] NORMAL_4 = [ (u'\u21e7', None, 'shift_L', 2.5), ('z', 'z', None, 1), ('x', 'x', None, 1), ('c', 'c', None, 1), ('v', 'v', None, 1), ('b', 'b', None, 1), ('n', 'n', None, 1), ('m', 'm', None, 1), ('<', '<', None, 1), ('>', '>', None, 1), ('?', '?', None, 1), (u'\u21e7', None, 'shift_R', 2.5), ] NORMAL_5 = [ ('', ' ', None, 12), (u'\u2b12', None, 'layout', 1.5), (u'\u2a2f', None, 'escape', 1.5),
]
SHIFT_1 = [
('`', '`', None, 1), ('1', '1', None, 1), ('2', '2', None, 1),
('3', '3', None, 1), ('4', '4', None, 1), ('5', '5', None, 1),
('6', '6', None, 1), ('7', '7', None, 1), ('8', '8', None, 1),
('9', '9', None, 1), ('0', '0', None, 1), ('+', '+', None, 1),
('=', '=', None, 1), (u'\u232b', None, 'backspace', 2),
]
SHIFT_2 = [
(u'\u21B9', chr(0x09), None, 1.5), ('Q', 'Q', None, 1), ('W', 'W', None, 1),
('E', 'E', None, 1), ('R', 'R', None, 1), ('T', 'T', None, 1),
('Y', 'Y', None, 1), ('U', 'U', None, 1), ('I', 'I', None, 1),
('O', 'O', None, 1), ('P', 'P', None, 1), ('[', '[', None, 1),
(']', ']', None, 1), ('?', '?', None, 1.5)
]
SHIFT_3 = [
(u'\u21ea', None, 'capslock', 1.8), ('A', 'A', None, 1), ('S', 'S', None, 1),
('D', 'D', None, 1), ('F', 'F', None, 1), ('G', 'G', None, 1),
('H', 'H', None, 1), ('J', 'J', None, 1), ('K', 'K', None, 1),
('L', 'L', None, 1), (':', ':', None, 1), ('"', '"', None, 1),
(u'\u23ce', None, 'enter', 2.2),
]
SHIFT_4 = [
(u'\u21e7', None, 'shift_L', 2.5), ('Z', 'Z', None, 1), ('X', 'X', None, 1),
('C', 'C', None, 1), ('V', 'V', None, 1), ('B', 'B', None, 1),
('N', 'N', None, 1), ('M', 'M', None, 1), (',', ',', None, 1),
('.', '.', None, 1), ('/', '/', None, 1), (u'\u21e7', None, 'shift_R', 2.5),
]
SHIFT_5 = [
('', ' ', None, 12), (u'\u2b12', None, 'layout', 1.5), (u'\u2a2f', None, 'escape', 1.5),
]
Comment #3
Posted on Jul 4, 2010 by Quick BirdSorry, I forgot to ask you for the code that you were using to add your own layout. Can you paste it as well please?
Comment #4
Posted on Jul 4, 2010 by Grumpy MonkeyHere is the whole code I used:
!/usr/bin/env python
from pymt import *
class BaseWidget(MTWidget): def init(self): MTWidget.init(self)
class KeyboardLayoutQWERTZ(KeyboardLayout): '''Implementation of QWERTZ Layout''' ID = 'qwertz' TITLE = 'Qwertz' DESCRIPTION = 'A classical German Keyboard' #FONT_FILENAME = kbdlayout_default_font NORMAL_1 = [ ('~', '~', None, 1), ('!', '!', None, 1), ('@', '@', None, 1), ('#', '#', None, 1), ('$', '$', None, 1), ('%', '%', None, 1), ('^', '^', None, 1), ('&', '&', None, 1), ('', '', None, 1), ('(', '(', None, 1), (')', ')', None, 1), ('', '', None, 1), ('+', '+', None, 1), (u'\u232b', None, 'backspace', 2), ] NORMAL_2 = [ (u'\u21B9', chr(0x09), None, 1.5), ('q', 'q', None, 1), ('w', 'w', None, 1), ('e', 'e', None, 1), ('r', 'r', None, 1), ('t', 't', None, 1), ('y', 'y', None, 1), ('u', 'u', None, 1), ('i', 'i', None, 1), ('o', 'o', None, 1), ('p', 'p', None, 1), ('{', '{', None, 1), ('}', '}', None, 1), ('|', '|', None, 1.5) ] NORMAL_3 = [ (u'\u21ea', None, 'capslock', 1.8), ('a', 'a', None, 1), ('s', 's', None, 1), ('d', 'd', None, 1), ('f', 'f', None, 1), ('g', 'g', None, 1), ('h', 'h', None, 1), ('j', 'j', None, 1), ('k', 'k', None, 1), ('l', 'l', None, 1), (':', ':', None, 1), ('"', '"', None, 1), (u'\u23ce', None, 'enter', 2.2), ] NORMAL_4 = [ (u'\u21e7', None, 'shift_L', 2.5), ('z', 'z', None, 1), ('x', 'x', None, 1), ('c', 'c', None, 1), ('v', 'v', None, 1), ('b', 'b', None, 1), ('n', 'n', None, 1), ('m', 'm', None, 1), ('<', '<', None, 1), ('>', '>', None, 1), ('?', '?', None, 1), (u'\u21e7', None, 'shift_R', 2.5), ] NORMAL_5 = [ ('', ' ', None, 12), (u'\u2b12', None, 'layout', 1.5), (u'\u2a2f', None, 'escape', 1.5),
]
SHIFT_1 = [
('`', '`', None, 1), ('1', '1', None, 1), ('2', '2', None, 1),
('3', '3', None, 1), ('4', '4', None, 1), ('5', '5', None, 1),
('6', '6', None, 1), ('7', '7', None, 1), ('8', '8', None, 1),
('9', '9', None, 1), ('0', '0', None, 1), ('+', '+', None, 1),
('=', '=', None, 1), (u'\u232b', None, 'backspace', 2),
]
SHIFT_2 = [
(u'\u21B9', chr(0x09), None, 1.5), ('Q', 'Q', None, 1), ('W', 'W', None, 1),
('E', 'E', None, 1), ('R', 'R', None, 1), ('T', 'T', None, 1),
('Y', 'Y', None, 1), ('U', 'U', None, 1), ('I', 'I', None, 1),
('O', 'O', None, 1), ('P', 'P', None, 1), ('[', '[', None, 1),
(']', ']', None, 1), ('?', '?', None, 1.5)
]
SHIFT_3 = [
(u'\u21ea', None, 'capslock', 1.8), ('A', 'A', None, 1), ('S', 'S', None, 1),
('D', 'D', None, 1), ('F', 'F', None, 1), ('G', 'G', None, 1),
('H', 'H', None, 1), ('J', 'J', None, 1), ('K', 'K', None, 1),
('L', 'L', None, 1), (':', ':', None, 1), ('"', '"', None, 1),
(u'\u23ce', None, 'enter', 2.2),
]
SHIFT_4 = [
(u'\u21e7', None, 'shift_L', 2.5), ('Z', 'Z', None, 1), ('X', 'X', None, 1),
('C', 'C', None, 1), ('V', 'V', None, 1), ('B', 'B', None, 1),
('N', 'N', None, 1), ('M', 'M', None, 1), (',', ',', None, 1),
('.', '.', None, 1), ('/', '/', None, 1), (u'\u21e7', None, 'shift_R', 2.5),
]
SHIFT_5 = [
('', ' ', None, 12), (u'\u2b12', None, 'layout', 1.5), (u'\u2a2f', None, 'escape', 1.5),
]
if name == 'main': main_window = getWindow() main_widget = BaseWidget()
MTVKeyboard.add_custom_layout(KeyboardLayoutQWERTZ())
keyboard = MTVKeyboard(layout = 'qwertz')
main_widget.add_widget(MTScatterWidget())
main_widget.add_widget(keyboard)
runTouchApp(main_widget)
I have detected an other bug when you use add_custom_layout.
Try this code and then fix the bug with the code I gave you.
Now you custom layout works but then try to change the layout to QWERTY.
This works fine too.
But when you want to change back to QWERTZ you get the following message:
Traceback (most recent call last):
File "test.py", line 89, in
runTouchApp(main_widget)
File "/usr/lib/python2.6/site-packages/pymt/base.py", line 352, in runTouchApp
pymt_window.mainloop()
File "/usr/lib/python2.6/site-packages/pymt/ui/window/win_pygame.py", line 124, in mainloop
evloop.idle()
File "/usr/lib/python2.6/site-packages/pymt/base.py", line 196, in idle
self.dispatch_input()
File "/usr/lib/python2.6/site-packages/pymt/base.py", line 181, in dispatch_input
self.post_dispatch_input(type=type, touch=touch)
File "/usr/lib/python2.6/site-packages/pymt/base.py", line 151, in post_dispatch_input
wid.dispatch_event('on_touch_up', touch)
File "/usr/lib/python2.6/site-packages/pymt/event.py", line 349, in dispatch_event
event_type, args, getattr(self, event_type))
File "/usr/lib/python2.6/site-packages/pymt/event.py", line 344, in dispatch_event
if func(*args):
File "/usr/lib/python2.6/site-packages/pymt/ui/widgets/composed/kineticlist.py", line 425, in on_touch_up
child.dispatch_event('on_touch_down', touch)
File "/usr/lib/python2.6/site-packages/pymt/event.py", line 349, in dispatch_event
event_type, args, getattr(self, event_type))
File "/usr/lib/python2.6/site-packages/pymt/event.py", line 344, in dispatch_event
if func(*args):
File "/usr/lib/python2.6/site-packages/pymt/ui/widgets/button.py", line 153, in on_touch_down
self.dispatch_event('on_press', touch)
File "/usr/lib/python2.6/site-packages/pymt/event.py", line 337, in dispatch_event
self._raise_dispatch_exception(event_type, args, handler)
File "/usr/lib/python2.6/site-packages/pymt/event.py", line 334, in dispatch_event
if handler(args):
File "/usr/lib/python2.6/site-packages/pymt/utils.py", line 32, in call_fn
return fn((cargs + fargs), **d)
File "/usr/lib/python2.6/site-packages/pymt/ui/widgets/composed/vkeyboard.py", line 432, in on_layout_change
self.layout = layout()
TypeError: 'KeyboardLayoutQWERTZ' object is not callable
Comment #5
Posted on Jul 4, 2010 by Quick BirdOK, there is no bug. :-) You're using the API incorrectly. a) add_custom_layout expects a class object, not an object of that class. I.e., don't call add_custom_layout(KeyboardLayoutQWERTZ()), but add_custom_layout(KeyboardLayoutQWERTZ). Then you can just create a MTVKeyboard (even without the layout= parameter) and choose the qwertz layout from the list when you click the button on the bottom left.
b) If you want to give the keyboard the right layout from the start, don't pass an ID but the actual keyboardlayout object. I.e.: k = MTVKeyboard(layout=KeyboardLayoutQWERTZ()) instead of: k = MTVKeyboard(layout='qwertz').
That both works for me. (You are missing a SIZE attribute in your layout. I think you can just copy that one line from the QWERTY layout.)
That should help. I'm marking this issue as invalid since I don't think it's a bug. If you disagree, feel free to post again. Thanks for taking the time to report this issue, nevertheless!
Comment #6
Posted on Jul 4, 2010 by Grumpy MonkeyOK, I became a little bit confused because of the config file were it says layout = qwerty. Thank you for these informations and sorry that I waste your time.
(You are missing a SIZE attribute in your layout. I think you can just copy that one line from the QWERTY layout.) There is no SIZE attribute in the QWERTY layout - I think that's because I don't use the git version.
Status: Invalid
Labels:
Type-Defect
Priority-Medium