禁止滚动滚动条,同时使其在wxPython中可见

时间:2014-02-17 10:56:27

标签: python python-2.7 user-interface user-controls wxpython

我目前正在使用Windows 7操作系统上的wxPython v3.0,python v2.7。我对滚动条有疑问。在我的应用程序中,我有一个GUI,它有许多滚动面板。这些滚动面板的滚动条也正常工作。

问题:我的问题是,是否可以禁用滚动条的滚动,同时让它在特定的滚动面板上可见? 单击滚动按钮或拖动滚动条时,滚动条不应滚动。

我知道我们可以使用SetupScrolling(scroll_y=False)SetupScrolling(scroll_x=False)禁用水平或垂直滚动​​。但这也会使滚动条不可见。我还尝试使用rate_y&将滚动率设置为0 rate_x,这也使滚动条不可见。总之,我想显示滚动条,但不做任何事情。

有没有办法捕捉滚动事件并让它们什么都不做?我尝试通过绑定myPanelwx.EVT_SCROLLWIN来执行命中和试用方法,以执行不执行任何操作的函数。不幸的是它没有用(滚动条仍在滚动)。

myPanel = wx.lib.scrolledpanel.ScrolledPanel(self, -1, style=wx.SIMPLE_BORDER)
myPanel.Bind(wx.EVT_SCROLLWIN, self.onScroll)

def onScroll(self, event):
    pass

这是一个快速的&脏代码样本可以播放,可以是downloaded too!避免身份错误。:

#!/usr/bin/env python

import wx
import wx.lib.scrolledpanel


class GUI(wx.Frame):

     def __init__(self, parent, id, title):
         screenSize = (400, 400)
         wx.Frame.__init__(self, None, id, title, size=screenSize)
         myFont = wx.Font(15, wx.MODERN, wx.NORMAL, wx.BOLD)
         panelsSizer = wx.BoxSizer(wx.VERTICAL)
         sizer1 = wx.BoxSizer(wx.VERTICAL)
         myPanel = wx.lib.scrolledpanel.ScrolledPanel(self, -1,style=wx.SIMPLE_BORDER)
         myPanel.Bind(wx.EVT_SCROLLWIN, self.onScroll)
         myPanel.SetupScrolling()
         panel1 = wx.lib.scrolledpanel.ScrolledPanel(myPanel, -1, style=wx.SIMPLE_BORDER)
         panel1.SetBackgroundColour('#FFFFFF')
         panel2 = wx.lib.scrolledpanel.ScrolledPanel(myPanel, -1, style=wx.SIMPLE_BORDER)
         panel2.SetBackgroundColour('#55F4FF')


         k = 0
         for i in range(1,7):
             sPanel ='Panel' +str(k)
             sPanel = wx.Panel(panel1)
             label = str(k)+'This is panel-1'
             text = wx.StaticText(sPanel, -1, label)
             text.SetForegroundColour('#0101DF')
             text.SetFont(myFont)
             sizer1.Add(sPanel, 0, wx.ALL, 5)
             sizer1.Add(wx.StaticLine(panel1), 0, wx.ALL|wx.EXPAND, 0)
             k += 1

         panel1.SetSizer(sizer1)
         panelsSizer.Add(panel1, 1, wx.EXPAND)
         panelsSizer.Add(panel2, 1, wx.EXPAND)
         myPanel.SetSizer(panelsSizer)

     def onScroll(self, event):
            pass


if __name__=='__main__':
    app = wx.App()
    frame = GUI(parent=None, id=-1, title="Test")
    frame.Show()
    app.MainLoop()

有什么建议吗?谢谢你的时间。

3 个答案:

答案 0 :(得分:1)

呜呜,我读到你解决了它。

与此同时,这是我能想到的最好的黑客攻击:

#!/usr/bin/env python

import wx
import wx.lib.scrolledpanel


class GUI(wx.Frame):

     def __init__(self, parent, id, title):
         screenSize = (400, 400)
         wx.Frame.__init__(self, None, id, title, size=screenSize)
         myFont = wx.Font(15, wx.MODERN, wx.NORMAL, wx.BOLD)
         panelsSizer = wx.BoxSizer(wx.VERTICAL)
         sizer1 = wx.BoxSizer(wx.VERTICAL)
         myPanel = wx.lib.scrolledpanel.ScrolledPanel(self, -1,style=wx.SIMPLE_BORDER)
         myPanel.Bind(wx.EVT_SCROLLWIN, self.onScroll)
         myPanel.SetupScrolling()
         panel1 = wx.lib.scrolledpanel.ScrolledPanel(myPanel, -1, style=wx.SIMPLE_BORDER)
         panel1.SetBackgroundColour('#FFFFFF')
         panel2 = wx.lib.scrolledpanel.ScrolledPanel(myPanel, -1, style=wx.SIMPLE_BORDER)
         panel2.SetBackgroundColour('#55F4FF')


         k = 0
         for i in range(1,7):
             sPanel ='Panel' +str(k)
             sPanel = wx.Panel(panel1)
             label = str(k)+'This is panel-1'
             text = wx.StaticText(sPanel, -1, label)
             text.SetForegroundColour('#0101DF')
             text.SetFont(myFont)
             sizer1.Add(sPanel, 0, wx.ALL, 5)
             sizer1.Add(wx.StaticLine(panel1), 0, wx.ALL|wx.EXPAND, 0)
             k += 1

         panel1.SetSizer(sizer1)
         panelsSizer.Add(panel1, 1, wx.EXPAND)
         panelsSizer.Add(panel2, 1, wx.EXPAND)
         myPanel.SetSizer(panelsSizer)
         self.scrolled_panel=myPanel 

     def onScroll(self, event):
        print "scroll event"
        for child in self.scrolled_panel.GetChildren():
           try:  
              child.SetThumbPosition(0)
              print "set child"
           except:
              print "oops,probably not a scrollbar :) "


if __name__=='__main__':
    app = wx.App()
    frame = GUI(parent=None, id=-1, title="Test")
    frame.Show()
    app.MainLoop()

它不会阻止它们拖动滚动条,但它会在放开后弹出它。

更新:上述代码仅适用于OSX,而​​不适用于Windows。

在OSX下,ScrolledPanel的子项报告为:

wxWindowList: [<wx._controls.ScrollBar; proxy of <Swig Object of type 'wxScrollBar *' at 0x10068f830> >, <wx._controls.ScrollBar; proxy of <Swig Object of type 'wxScrollBar *' at 0x100691230> >, <wx._core.Window; proxy of <Swig Object of type 'wxWindow *' at 0x100691d20> >, <wx.lib.scrolledpanel.ScrolledPanel; proxy of <Swig Object of type 'wxPyScrolledWindow *' at 0x1004ac990> >, <wx.lib.scrolledpanel.ScrolledPanel; proxy of <Swig Object of type 'wxPyScrolledWindow *' at 0x1004af8e0> >]

这是我的黑客攻击的两个ScrollBar。

在Windows下,同一个调用返回:

wxWindowList: [<wx.lib.scrolledpanel.ScrolledPanel; proxy of <Swig Object of type 'wxPyScrolledWindo
w *' at 0x26837b8> >, <wx.lib.scrolledpanel.ScrolledPanel; proxy of <Swig Object of type 'wxPyScroll
edWindow *' at 0x26839b0> >]

这很难理解。滚动条隐藏在哪里?我想这就是你破解到应该为你封装的组件所得到的:)

答案 1 :(得分:1)

我终于想出了解决问题的方法。但我不太明白为什么它有效。 :P

我正在阅读http://wiki.wxpython.org/AnotherTutorial#Events上的教程并发现一些有趣的内容。维基说:

  当我们点击内置的时,会生成wx.ScrollWinEvent事件   滚动条。使用SetScrollbar()激活内置滚动条   方法调用。对于独立的Scrollbars,还有另一种事件类型,   即wx.ScrollEvent。

所以我决定设置一个内置滚动条,然后我将绑定我的onScroll(),以便在移动滚动条时不执行任何操作。现在,我创建了一个简单的Panel,而不是创建一个scrolledPanel。

myPanel = wx.Panel(self, -1,style=wx.SIMPLE_BORDER)

然后我使用setScrollbar()创建一个内置滚动条。

myPanel.SetScrollbar(wx.VERTICAL, 0, 0, 2, 0)

然后我将onScroll()绑定到正在发生的任何scrolling events

myPanel.Bind(wx.EVT_SCROLLWIN, self.OnScroll)

所以,现在您会注意到myPanel上的滚动条在点击或拖动时无效。

我不理解

您真的不需要拦截任何滚动事件。您不需要绑定onScroll()。即使你没有绑定onScroll(),滚动条仍然没有响应任何点击或拖动!也许我错过了一些基本的东西。

以下是可用于download的更新代码,以避免缩进问题:

class GUI(wx.Frame):

    def __init__(self, parent, id, title):
        screenSize = (400, 400)
        wx.Frame.__init__(self, None, id, title, size=screenSize)
        myFont = wx.Font(15, wx.MODERN, wx.NORMAL, wx.BOLD)
        panelsSizer = wx.BoxSizer(wx.VERTICAL)
        sizer1 = wx.BoxSizer(wx.VERTICAL)
        myPanel = wx.Panel(self, -1,style=wx.SIMPLE_BORDER)
        #Uncommenting the following line has no effect on scroll bar behavior!
        #myPanel.Bind(wx.EVT_SCROLLWIN, self.OnScroll)
        myPanel.SetScrollbar(wx.VERTICAL, 0, 0, 2, 0)
        panel1 = wx.lib.scrolledpanel.ScrolledPanel(myPanel, -1, style=wx.SIMPLE_BORDER)
        panel1.SetBackgroundColour('#FFFFFF')
        panel2 = wx.lib.scrolledpanel.ScrolledPanel(myPanel, -1, style=wx.SIMPLE_BORDER)
        panel2.SetBackgroundColour('#55F4FF')


        k = 0
        for i in range(1,10):
            sPanel ='Panel' +str(k)
            sPanel = wx.Panel(panel1)
            label = str(k)+'This is panel-1'
            text = wx.StaticText(sPanel, -1, label)
            text.SetForegroundColour('#0101DF')
            text.SetFont(myFont)
            sizer1.Add(sPanel, 0, wx.ALL, 5)
            sizer1.Add(wx.StaticLine(panel1), 0, wx.ALL|wx.EXPAND, 0)
            k += 1

        panel1.SetSizer(sizer1)
        panelsSizer.Add(panel1, 1, wx.EXPAND)
        panelsSizer.Add(panel2, 1, wx.EXPAND)
        myPanel.SetSizer(panelsSizer)

    def OnScroll(self, evt):
          print "Got it"
          pass



if __name__=='__main__':
   app = wx.App()
   frame = GUI(parent=None, id=-1, title="Test")
   frame.Show()
   app.MainLoop()

答案 2 :(得分:0)

我目前无法对此进行测试,可能会覆盖您已经尝试过的内容,而无法提供更多我无法分辨的信息。

据我所知,没有设置方法可以在不删除滚动条的情况下禁用滚动,我在你的位置尝试的是,当你触发onScroll事件时,不是使用'pass',而是使用滚动条位置设置为0 set position,这可能只会在移动后重置位置,我认为应该能够控制滚动事件,我不知道为什么不是为你工作。

另一种选择可能是将滚动条范围设置为0或非常小的数字。