使用鼠标滚轮和箭头键滚动`wx.ScrolledPanel`

时间:2009-07-18 13:51:37

标签: python user-interface wxpython scroll

在我的wxPython应用程序中,我创建了一个wx.ScrolledPanel,其中有一个需要滚动的大wx.StaticBitmap

滚动条确实出现,我可以用它们滚动,但我也希望能够用鼠标滚轮和键盘上的箭头键滚动。如果“Home”,“Page Up”和其他键也可以按预期运行,那将是很好的。

我该怎么做?

更新

我看到了问题。 ScrolledPanel能够滚动,但仅在焦点处于焦点时。问题是,我如何成为焦点?即使点击它也不会这样做。只有当我在其中放置一个文本控件时,我才可以专注于它,然后滚动滚轮。但我不想在其中有文本控件。那么如何让它集中注意力呢?

更新2:

这是一个显示这种现象的代码示例。取消注释以查看文本控件如何使鼠标滚轮工作。

import wx, wx.lib.scrolledpanel

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)

        scrolled_panel = \
            wx.lib.scrolledpanel.ScrolledPanel(parent=self, id=-1)
        scrolled_panel.SetupScrolling()

        text = "Ooga booga\n" * 50
        static_text=wx.StaticText(scrolled_panel, -1, text)
        sizer=wx.BoxSizer(wx.VERTICAL)
        sizer.Add(static_text, wx.EXPAND, 0)

        #    Uncomment the following 2 lines to see how adding
        #    a text control to the scrolled panel makes the
        #    mouse wheel work.
        #
        #text_control=wx.TextCtrl(scrolled_panel, -1)
        #sizer.Add(text_control, wx.EXPAND, 0)

        scrolled_panel.SetSizer(sizer)

        self.Show()

if __name__=="__main__":
    app = wx.PySimpleApp()
    my_frame=MyFrame(None, -1)
    #import cProfile; cProfile.run("app.MainLoop()")
    app.MainLoop()

2 个答案:

答案 0 :(得分:3)

问题在窗口框架获得焦点,子面板没有获得焦点(在ubuntu linux上它工作正常)。解决方法可以简单到重定向帧焦点事件以将焦点设置为面板,例如

import wx, wx.lib.scrolledpanel

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)

        self.panel = scrolled_panel = \
            wx.lib.scrolledpanel.ScrolledPanel(parent=self, id=-1)
        scrolled_panel.SetupScrolling()

        text = "Ooga booga\n" * 50
        static_text=wx.StaticText(scrolled_panel, -1, text)
        sizer=wx.BoxSizer(wx.VERTICAL)
        sizer.Add(static_text, wx.EXPAND, 0)

        scrolled_panel.SetSizer(sizer)

        self.Show()

        self.panel.SetFocus()
        scrolled_panel.Bind(wx.EVT_SET_FOCUS, self.onFocus)

    def onFocus(self, event):
        self.panel.SetFocus()

if __name__=="__main__":
    app = wx.PySimpleApp()
    my_frame=MyFrame(None, -1)
    app.MainLoop()

或onmouse移动到面板上,将焦点设置到它,所有键+ mousewheeel将开始工作,例如

import wx, wx.lib.scrolledpanel

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)

        self.panel = scrolled_panel = \
            wx.lib.scrolledpanel.ScrolledPanel(parent=self, id=-1)
        scrolled_panel.SetupScrolling()

        scrolled_panel.Bind(wx.EVT_MOTION, self.onMouseMove)

        text = "Ooga booga\n" * 50
        static_text=wx.StaticText(scrolled_panel, -1, text)
        sizer=wx.BoxSizer(wx.VERTICAL)
        sizer.Add(static_text, wx.EXPAND, 0)

        scrolled_panel.SetSizer(sizer)

        self.Show()

    def onMouseMove(self, event):
        self.panel.SetFocus()

if __name__=="__main__":
    app = wx.PySimpleApp()
    my_frame=MyFrame(None, -1)
    app.MainLoop()

答案 1 :(得分:0)

我希望这是一个应该做你想做的事的例子。 (编辑:回想起来,这并不是很有效,例如,当有两个滚动的面板时......我会把它留在这里虽然所以人们可以将它或者其他东西投入其中。)基本上我将所有内容放在框架内的面板中(通常是个好主意),然后将焦点设置到此主面板。

import wx
import wx, wx.lib.scrolledpanel

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)
        main_panel = wx.Panel(self, -1)
        main_panel.SetBackgroundColour((150, 100, 100))
        self.main_panel = main_panel

        scrolled_panel = \
            wx.lib.scrolledpanel.ScrolledPanel(parent=main_panel, id=-1)
        scrolled_panel.SetupScrolling()
        self.scrolled_panel = scrolled_panel

        cpanel = wx.Panel(main_panel, -1)
        cpanel.SetBackgroundColour((100, 150, 100))
        b = wx.Button(cpanel, -1, size=(40,40))
        self.Bind(wx.EVT_BUTTON, self.OnClick, b)
        self.b = b

        text = "Ooga booga\n" * 50
        static_text=wx.StaticText(scrolled_panel, -1, text)
        main_sizer=wx.BoxSizer(wx.VERTICAL)
        main_sizer.Add(scrolled_panel, 1, wx.EXPAND)
        main_sizer.Add(cpanel, 1, wx.EXPAND)
        main_panel.SetSizer(main_sizer)

        text_sizer=wx.BoxSizer(wx.VERTICAL)
        text_sizer.Add(static_text, 1, wx.EXPAND)
        scrolled_panel.SetSizer(text_sizer)

        self.main_panel.SetFocus()

        self.Show()

    def OnClick(self, evt):
        print "click"


if __name__=="__main__":
    class MyApp(wx.App):

        def OnInit(self):
            frame = MyFrame(None, -1)
            frame.Show(True)
            self.SetTopWindow(frame)
            return True
    app = MyApp(0)
    app.MainLoop()

对于键盘控制,比如从主页键设置操作,我认为您需要绑定到这些事件,并做出适当的响应,例如使用mypanel.Scroll(0,0) home键(并记住为您未执行操作的键盘事件调用evt.Skip()。 (编辑:我不认为滚动有任何默认的键绑定。我不确定我是否也想要任何一个,例如,如果在滚动内滚动面板会发生什么面板?)