2009-07-18 40 views
5

Trong ứng dụng wxPython của tôi, tôi đã tạo một wx.ScrolledPanel, trong đó có một số lớn wx.StaticBitmap cần được cuộn.Cuộn qua một `wx.ScrolledPanel` bằng các phím chuột và phím mũi tên

Thanh cuộn xuất hiện và tôi có thể cuộn với chúng, nhưng tôi cũng muốn có thể cuộn bằng bánh xe chuột và các phím mũi tên trên bàn phím. Nó sẽ là tốt đẹp nếu "Home", "Page Up", và những phím khác cũng sẽ hoạt động như mong đợi.

Làm cách nào để thực hiện việc này?

UPDATE:

Tôi thấy vấn đề. ScrolledPanel có thể cuộn, nhưng chỉ khi nó đang được tập trung. Vấn đề là, làm thế nào để tôi được tập trung? Ngay cả khi nhấp vào nó cũng không làm được. Chỉ khi tôi đặt một điều khiển văn bản bên trong nó, tôi có thể tập trung vào nó và do đó di chuyển với bánh xe. Nhưng tôi không muốn có một điều khiển văn bản trong đó. Vậy làm cách nào để tôi tập trung?

UPDATE 2:

Đây là một mẫu mã cho thấy hiện tượng này. Bỏ ghi chú để xem cách điều khiển văn bản làm cho bánh xe chuột hoạt động.

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

Trả lời

0

Đây là ví dụ nên làm những gì bạn muốn, tôi hy vọng. (Chỉnh sửa: Nhìn lại, điều này không hoạt động tốt, ví dụ, khi có hai bảng cuộn ... Tôi sẽ để nó ở đây mặc dù vậy có thể giảm bớt nó hoặc bất cứ thứ gì.) Về cơ bản, tôi đặt mọi thứ vào bảng bên trong khung (thường là một ý tưởng hay), và sau đó đặt trọng tâm vào bảng điều khiển chính này.

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

Để kiểm soát bàn phím, giống như thiết lập hành động từ chìa khóa nhà, tôi nghĩ rằng bạn sẽ cần phải liên kết với những sự kiện, và đáp ứng một cách thích hợp, chẳng hạn như sử dụng mypanel.Scroll(0,0) cho phím home (và nhớ để gọi evt.Skip() cho các sự kiện bàn phím mà bạn không thực hiện). (Chỉnh sửa: Tôi không nghĩ có bất kỳ ràng buộc khóa mặc định nào để cuộn. Tôi không chắc chắn tôi muốn bất kỳ điều gì, ví dụ: điều gì sẽ xảy ra nếu có một bảng điều khiển cuộn trong một bảng cuộn?)

+0

Nhưng phải đặt ở đâu? Tôi có thể muốn thay đổi tập trung vào một số tiện ích khác, sau đó quay lại ScrolledPanel. –

+0

1. Xem câu hỏi trong bình luận đầu tiên của tôi. 2. Có, tôi đã gọi là SetupScrolling. 3. Tôi có thực sự cần phải tái tạo lại bánh xe bằng chìa khóa nhà không? Không wxPython thực hiện điều này? –

+0

Điều gì đó lạ. Ví dụ trong bản demo wxPython, khi chuột nếu trên mỗi bảng điều khiển, bảng điều khiển đó sẽ cuộn bằng bánh xe. Vì vậy, một vài câu hỏi. Nếu bạn gọi 'SetFocus' có hoạt động không? Nếu bạn cố gắng cuộn theo cách thông thường, bằng cách nhấp vào thanh cuộn và di chuyển, nó có di chuyển không? Và nếu bạn ngay lập tức sử dụng bánh xe di chuyển, nó có hoạt động không? – tom10

3

Sự cố trên cửa sổ Khung lấy tiêu điểm và bảng con không nhận được tiêu điểm (trên linux ubuntu nó hoạt động tốt). Giải pháp thay thế có thể đơn giản như chuyển hướng sự kiện lấy nét khung để đặt tiêu điểm thành bảng điều khiển, ví dụ:

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

hoặc di chuyển trên bảng điều khiển, đặt trọng tâm vào đó và tất cả các phím + mousewheeel sẽ bắt đầu hoạt động, ví dụ:

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

Về mẫu mã đầu tiên của bạn, nó sẽ không hoạt động với nhiều ScrolledPanel, phải không? Về mẫu mã thứ hai của bạn, tôi nghĩ đây là con đường để đi. (Ngoại trừ một chút ít nhạy cảm, tôi không muốn tập trung thay đổi mỗi khi bạn vô tình di chuột qua bảng điều khiển.) Tôi nghĩ rằng tôi sẽ phân lớp ScrolledPanel và đăng nó ở đây. –

+1

để cuộn bảng điều khiển cần được lấy nét, nhưng nếu bạn không thích tập trung vào di chuyển chuột, bạn có thể làm điều tương tự khi nhấp –

Các vấn đề liên quan