先公布答案再讲故事(panel的style注意默认是TAB_TRAVERSAL,这个会影响键盘)
最近在网易云课堂中看到一篇课程,是用wxPython写一个2048的小游戏,游戏界面如下图所示:
这个游戏2-3年前非常流行,于是我就跟着教程做了一下(tkinter的界面太丑了,听说wxpython比tkinter好看很多)。过程一切顺利,尤其是做到计算器的时候,能明显感觉到wxpython比tkinter漂亮多了(当然,也不排除我水平太差)
继续到了2048,也是一切顺利,定义frame类,绘图,写算法,运行,都没有错,全部写好了之后,准备玩的时候突然发现,这个游戏是用上下左右键控制的,上下左右居然不好使!!
第一个想到的就是我的代码是不是不对啊?我到github上下载了源码(https://github.com/shiyanlou/shiyanlou_cs427),源码复制粘贴了以后,居然还是一样,上下左右键都不好使!(插一句,源码也有问题,设置font的方法里面的参数不是face了,而是faceName,但这不是重点)
重点是我写了个用上下左右玩的游戏,键盘的上下左右事件我获取不到!
先去查了函数:
这是panel绑定事件的代码:
panel.Bind(wx.EVT_KEY_DOWN, self.onKeyDown)#前面是事件类型,后面是事件函数
这是事件函数:
def onKeyDown(self,event):
keyCode = event.GetKeyCode()
#print(keyCode)————————————————用print检测键盘输入
if keyCode==wx.WXK_UP:
self.doMove(*self.slideUpDown(True))
elif keyCode==wx.WXK_DOWN:
self.doMove(*self.slideUpDown(False))
elif keyCode==wx.WXK_LEFT:
self.doMove(*self.slideLeftRight(True))
elif keyCode==wx.WXK_RIGHT:
self.doMove(*self.slideLeftRight(False))
检测的结果是,键盘所有的输入都能监听到,唯独上下左右没有!!!哭啊,我写的上下左右游戏,上下左右用不了,我把上下左右改成了WASD,可以用,可是这不是我想要的效果啊
想办法,问题一定是出在哪里了。
查wxpython官网,查Event类,查on key down,查getkeycode方法。中间一度怀疑是wxpython的问题,因为我看到别人用pygame写的 一个例子里面用到了上下左右,会不是是wxpython就不支持上下左右,可是不支持的话,里面明明写了上下左右的虚拟键值了(wx.WXK_UP,wx.WXK_DOWN,wx.WXK_LEFT,wx.WXK_RIGHT)
在看getkeycode方法的时候,发现getkeycode会返回一个int值,而上下左右的int值就print不出来。唉,这是天要亡我啊。
在getkeycode和keyevent兜兜转转两天以后,忽然想到,是不是panel的问题啊?
在wxpython介绍panel类里面有这么一句话:
Note
if not all characters are being intercepted by your OnKeyDown or OnChar handler, it may be because you are using the TAB_TRAVERSAL style, which grabs some keypresses for use by child controls.
注意,如果你键盘输入没有被捕获到,那么你是用了TAB_TARVERSAL的缘故,再看看panel的构造函数:
__init__ (self, parent, id=ID_ANY, pos=DefaultPosition, size=DefaultSize, style=TAB_TRAVERSAL, name=PanelNameStr)
默认的style就是TAB_TARVERSAL!
看来如果换个style或许有解决问题的希望??
马上查询wxpython的style列表,虽然大部分看不懂,为了安全换成了wx.BORDER_NONE.保存,运行,我的上下左右又可以用了!为了能用这4个键,我都一度怀疑是笔记本键盘还是标准键盘的问题了。。。
花了2天半终于解决了这个问题,不过也好,中间花了大量的事件查询frame,panel,keyevent,bind方法什么的,倒是对wx的事件运行机制有了不少了解。。。好了终于写了一篇除了自己能看懂,大部分人都看不懂的文章了,Yeah!