2009-07-18 17 views
5

Nella mia applicazione wxPython ho creato uno wx.ScrolledPanel, in cui c'è un grande wx.StaticBitmap che deve essere fatto scorrere.Scorrere attraverso un `wx.ScrolledPanel` con la rotellina del mouse e i tasti freccia

Le barre di scorrimento appaiono e io posso scorrere con loro, ma mi piacerebbe anche essere in grado di scorrere con la rotella del mouse e i tasti freccia sulla tastiera. Sarebbe bello se anche "Home", "Pagina su" e quegli altri tasti funzionassero come previsto.

Come posso fare?

UPDATE:

vedo il problema. ScrolledPanel è in grado di scorrere, ma solo quando è messo a fuoco. Il problema è, come posso essere messo a fuoco? Anche facendo clic su di esso non lo fa. Solo se metto un controllo testuale al suo interno posso concentrarmi su di esso e quindi scorrere con la rotella. Ma non voglio avere un controllo del testo. Quindi, come faccio a focalizzarlo?

UPDATE 2:

Ecco un esempio di codice che illustra questo fenomeno. Non notare per vedere come un controllo del testo fa funzionare la rotellina del mouse.

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

risposta

0

Ecco un esempio che dovrebbe fare quello che vuoi, spero. (Modifica: In retrospettiva, questo non funziona molto, ad esempio, quando ci sono due pannelli a scorrimento ... Lascerò tutto qui, anche se in questo modo peole può eseguire il downvoting o qualsiasi altra cosa.) Fondamentalmente ho messo tutto in un pannello all'interno del frame (generalmente una buona idea), quindi imposta lo stato attivo su questo pannello principale.

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

Per il controllo della tastiera, come impostare l'azione dalla chiave di casa, penso che avrete bisogno di legarsi a quegli eventi, e rispondere in modo adeguato, come l'utilizzo di mypanel.Scroll(0,0) per la chiave home (e ricordarsi di chiamare per evt.Skip() gli eventi della tastiera su cui non si agisce). (Modifica: Non penso ci siano associazioni di tasti predefinite per lo scorrimento. Non sono sicuro che ne vorrei uno, ad esempio, che cosa dovrebbe accadere se c'è un pannello a scorrimento all'interno di un pannello a scorrimento?)

+0

Ma dove metterlo? Potrei voler spostare lo stato attivo su qualche altro widget e poi tornare di nuovo su ScrolledPanel. –

+0

1. Vedere la domanda nel mio primo commento. 2. Sì, ho chiamato SetupScrolling. 3. Devo davvero reinventare la ruota con la chiave di casa? WxPython non lo implementa? –

+0

Qualcosa è strano. Ad esempio nella demo wxPython, quando il mouse si trova su ciascun pannello, quel pannello scorrerà con la rotellina. Quindi alcune domande. Se chiami 'SetFocus' funziona? Se si prova a scorrere nel modo normale, facendo clic sulla barra di scorrimento e spostandosi, si sposta? E se usi immediatamente la rotellina, funziona allora? – tom10

3

Problema presente nella finestra Il frame ottiene lo stato attivo e il pannello secondario non riceve il Focus (su ubuntu linux funziona correttamente). La soluzione alternativa può essere semplice come reindirizzare l'evento Focus frame per impostare lo stato attivo sul pannello, ad es.

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

o Onmouse spostarsi su pannello, impostare come attivo, e tutte le chiavi + mousewheeel inizierà a lavorare ad esempio

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

Per quanto riguarda il primo esempio di codice, non funzionerà per più di uno ScrolledPanel, vero? Per quanto riguarda il secondo campione di codice, penso che questa sia la strada da percorrere. (Tranne un po 'meno sensibile, non voglio che la messa a fuoco cambi ogni volta che si sposta il mouse sul pannello.) Penso che sottoclassi ScrolledPanel e pubblichi qui. –

+1

per scorrere un pannello che dovrebbe essere a fuoco, ma se non ti piace la messa a fuoco del mouse, puoi fare lo stesso con il clic –

Problemi correlati