wxPython手动滚动面板 ScrolledPanel在使用wx.Grid时失败。

问题描述 投票:0回答:1

我创建了一个从wx.lib.scrolledpanel衍生出来的面板。我可以用鼠标滚轮在上面滚动,直到我在面板上放了一个网格。现在,当鼠标光标在网格上方时,滚动停止了,如果我把光标移到网格外,就会重新开始工作。

我想最简单的解决办法就是手动捕捉mousewheel事件,然后手动滚动面板。我在我的wx.App对象中把这个处理程序绑定到wx.EVT_MOUSEWHEEL上。

class Wx_app(wx.App):

    def __init__(self):

        super().__init__(clearSigInt=True)
        self.frame = MyFrame(None, pos=(0,0), size=(1900, 1100))
        self.Bind(wx.EVT_MOUSEWHEEL, self.on_mouse_wheel)

    def on_mouse_wheel(self, e):

        # get the current scroll pos, is tuple with x as first val, y as second val
        pos = self.frame.panel.CalcUnscrolledPosition(0, 0)
        y_pos = pos[1]

        # detemrine if user is scrolling up or down
        if e.GetWheelRotation() > 0:

            # user is scrolling up
            print("UP")
            self.frame.panel.Scroll(0, y_pos + 10)

        else:

            # user is scrolling down
            print("DOWN")
            self.frame.panel.Scroll(0, y_pos - 10)

当我试图向下滚动时,这段代码可以正常工作,但是当我试图用鼠标滚轮向上滚动时,什么都没有发生,即使 "UP "在我的终端中注册。另外,我认为向上应该是y_pos - 10,而不是y_pos + 10,但是滚轮的滚动方向与你期望的相反。我到底做错了什么?也许我首先没有得到正确的现有位置,但 CalcUnscrolledPosition 是我能找到的唯一能做到这一点的东西。我是Python新手,请把我当做一个5岁的孩子来解释。

python wxpython
1个回答
0
投票

你眼前的问题是 Up 将是 Y - 10Down 将是 Y + 10. 你需要再往上走(减少y)或往下走(增加y)。

当你依靠从鼠标事件返回的位置以及它与滚动窗口中的位置的关系时,你也很可能会比较苹果和橙子。

这个问题的关键是,滚动面板和鼠标事件都是 and 网格的滚动条是可滚动的部件。你的问题似乎是你的网格没有足够的大小来显示网格的滚动条,因此造成了混乱。

你可以在网格上强制显示滚动条,并调整它的大小,这样就可以很明显地看到有两组滚动条,希望你的用户可以解决这个问题。

下面是一个滚动面板中的示例网格,可以玩玩(忽略绑定函数,它们在那里是因为最初我误解了你的问题,以为你想在网格中手动滚动)。

import wx
import wx.lib.scrolledpanel
import wx.grid

class MyPanel(wx.Panel):
    def __init__(self, *args, **kwargs):
        wx.Panel.__init__(self, *args, **kwargs) 
        self.sizer = wx.BoxSizer(wx.HORIZONTAL)
        self.fileFormPanel = FileFormPanel(self)
        self.sizer.Add(self.fileFormPanel, 1, wx.EXPAND)
        self.SetSizer(self.sizer)

class FileFormPanel(wx.lib.scrolledpanel.ScrolledPanel):
    def __init__(self, parent):
        wx.lib.scrolledpanel.ScrolledPanel.__init__(self, parent)

        sizer = wx.BoxSizer(wx.VERTICAL)

        # Create a wxGrid object
        self.grid = wx.grid.Grid(self, -1, size=(300,480))
        self.grid.CreateGrid(5, 10)
        self.grid.SetRowLabelSize(1)
        self.grid.SetDefaultColSize(120)
        self.grid.SetColSize(0, 50)
        self.grid.ShowScrollbars(True, True)
        for j in range(5):
            for k in range(10):
                self.grid.SetCellValue(j, k, str(k))

        text = wx.TextCtrl(self, wx.ID_ANY, value="Some text")

        sizer.Add(self.grid)
        sizer.Add(text)
        self.SetSizer(sizer)
        self.SetupScrolling()

        #self.grid.Bind(wx.EVT_MOUSEWHEEL, self.OnGrid)
        #self.Bind(wx.EVT_MOUSEWHEEL, self.OnScroll)
        #self.grid.Bind(wx.grid.EVT_GRID_SELECT_CELL, self.OnSelect)

#    def OnGrid(self, event):
#        obj = event.GetEventObject()
#        if event.WheelRotation > 0:
#            self.grid.MoveCursorUp(False)
#        else:
#            self.grid.MoveCursorDown(False)
#
#    def OnSelect(self, event):
#        obj = event.GetEventObject()
#        r = event.GetRow()
#        c = event.GetCol()
#        self.grid.MakeCellVisible(r,c)
#        event.Skip()
#
#    def OnScroll(self, event):
#        print("window scroll")
#        event.Skip()

class DemoFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, parent = None, size = (400, 400))
        MyPanel(self)

class App(wx.App):
    def OnInit(self):
        self.frame = DemoFrame()
        self.frame.Show()
        self.SetTopWindow(self.frame)

        return True

app = App()
app.MainLoop()

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.