Прокрутка `wx.ScrolledPanel` с помощью колесика мыши и клавиш со стрелками - PullRequest
5 голосов
/ 18 июля 2009

В моем приложении wxPython я создал wx.ScrolledPanel, в котором есть большой wx.StaticBitmap, который нужно прокрутить.

Полосы прокрутки появляются, и я могу прокручивать их, но я также хотел бы иметь возможность прокручивать колесико мыши и клавиши со стрелками на клавиатуре. Было бы неплохо, если бы «Домой», «Страница вверх» и другие клавиши также работали должным образом.

Как мне это сделать?

UPDATE:

Я вижу проблему. 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 ]

3 голосов
/ 21 июля 2009

Проблема в окне. Рамка получает фокус, а дочерняя панель не получает Фокус (в 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()

или наведите курсор мыши на панель, установите на нее фокус, и все клавиши + колесико мыши заработают, например,

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()
0 голосов
/ 18 июля 2009

Вот пример, который должен делать то, что вы хотите, я надеюсь. ( Редактировать : В ретроспективе это не совсем работает, например, когда есть две прокручиваемые панели ... Я оставлю это здесь, хотя, так что peole может понизить его или что-то в этом роде.) По сути, я положил все в панели внутри рамки (как правило, хорошая идея), а затем установите фокус на этой главной панели.

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()

Для управления с клавиатуры, например, для установки действия с помощью клавиши home, я думаю, вам нужно будет привязать эти события и ответить соответствующим образом, например, используя mypanel.Scroll(0,0) для клавиши home (и не забывайте звонить evt.Skip() для событий клавиатуры, на которые вы не действуете). ( Edit: Я не думаю, что есть какие-либо привязки клавиш по умолчанию для прокрутки. Я не уверен, что я хотел бы также любой, например, что должно произойти, если есть прокручиваемая панель в прокручиваемой панели ?)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...