滚动面板鼠标

2024-09-29 23:20:42 发布

您现在位置:Python中文网/ 问答频道 /正文

我希望你能帮我:)我的头撞到墙上了,当我使用鼠标滚轮时,我无法让滚动面板上下滚动。但当我点击或拖动它时,它会起作用。在

我要做的是用一堆textctrl填充一个面板,然后使用滚动面板来滚动它们。我试着在鼠标悬停时设置面板的焦点,甚至在单击时也尝试过,但是当我在面板上下滚动时,没有发生任何事情。在

我已经看过wxPython的滚动面板示例,但是我不明白为什么他们的工作正常,而我的不工作。在

任何帮助都将是惊人的!在

编辑: 我发现,当textcrl被选中时,它会激活滚动,但在使用多行时却不会。Expando文本ctrl使用多行样式,因此我只能在单击单行文本ctrl时激活滚动条。在

当单击多行文本控件时,如何控制滚动条以使用鼠标滚轮?在

import wx
import random
import wx.lib.platebtn as pbtn
import wx.lib.agw.gradientbutton as gbtn
import wx.lib.scrolledpanel as spanel
import requests
import json
import sys
import wx.lib.mixins.listctrl  as  listmix
import wx.lib.expando as etc


ticketInfo = """
*************************\n
TEST TICKET\n
*************************\n
BLAH BLAH BLAH BLAH\n
BLAH BLAH BLAH BLAH\n
BLAH BLAH BLAH BLAH\n
BLAH BLAH BLAH BLAH\n
BLAH BLAH BLAH BLAH\n
"""


class MyApp(wx.App):
    def OnInit(self):
        self.frame = MyFrame(None, title="Learning List Controls")
        self.SetTopWindow(self.frame)
        self.frame.Show()

        return True
class TicketViewer(wx.lib.scrolledpanel.ScrolledPanel):
    def __init__(self, parent):
        super(TicketViewer, self).__init__(parent, name="panel", style=wx.TE_AUTO_SCROLL)

        #Attributes
        vSizer = wx.BoxSizer(wx.VERTICAL)
        self.SetSizer(vSizer)
        self.PopulateTicketMessages(ticketInfo)
        self.PopulateTicketMessages(ticketInfo)
        self.PopulateTicketMessages(ticketInfo)
        self.PopulateTicketMessages(ticketInfo)
        self.PopulateTicketMessages(ticketInfo)
        self.PopulateTicketMessages(ticketInfo)
        self.PopulateTicketMessages(ticketInfo)
        self.PopulateTicketMessages(ticketInfo)
        self.PopulateTicketMessages(ticketInfo)
        self.PopulateTicketMessages(ticketInfo)
        self.SetSizer(vSizer)
        self.Layout()
        self.SetupScrolling()
        panelID = self.GetId()
    def PopulateTicketMessages(self, ticketInfo):
        msgBox = etc.ExpandoTextCtrl(self,
                         id=-1,
                         value=ticketInfo,
                         style=wx.TE_READONLY|wx.TE_WORDWRAP)
        sizer = self.GetSizer()
        sizer.Add(msgBox)
        msgBox.Bind(wx.EVT_LEFT_DOWN, self.OnMouseOver)
    def OnMouseOver(self, event):
        panel = wx.FindWindowByName("panel")
        panel.SetFocus()
        print(panel)
class MyFrame(wx.Frame):
    def __init__(self, *args, **kwargs):
        super(MyFrame, self).__init__(*args, **kwargs)

        #Attribues
        self.tktViewer = TicketViewer(self)


        frameSizer = wx.BoxSizer(wx.HORIZONTAL)
        frameSizer.Add(self.tktViewer, 1, wx.EXPAND)
        self.SetSizer(frameSizer)

        #self.SetSizerAndFit(frameSizer)
        self.CreateStatusBar()
        self.SetInitialSize()

    def OnMouseOver(self, event):
        panel = wx.FindWindowById(tktViewerID)
        panel.SetFocus()
        print(self)

if __name__ == "__main__":
    app = MyApp(False)
    app.MainLoop()

Tags: 文本importself面板initlibdefas
1条回答
网友
1楼 · 发布于 2024-09-29 23:20:42

这是因为ScrolledPanel派生自wx.面板,wich有代码,每次它收到焦点时,都会尝试将焦点重置为第一个子级。此外,在Windows中,轮子事件只被发送到具有焦点的小部件。(Useful thread with Robin Dunn remarks

出现这种情况时的解决方案:

(1)去哪里看比赛?在应用程序级别。 正如wxpython文档中关于事件表搜索顺序的描述:How Events are Processed

Finally, i.e., if the event is still not processed, the App object itself (which derives from EvtHandler) gets a last chance to process it.

所以wx.GetApp软件().绑定(wx.EVT_鼠标滚轮,您的处理程序)

(2)如何手动处理事件? 从this post开始构思(根据pygcodeviewer/pygcodeviewer.py内的评论由道格·安德森撰写)

需要在我们感兴趣的wxWindow(滚动面板)上调用GetHandler().ProcessEvent(event)

考虑到我们是在应用程序级别捕捉到的:我们必须确保事件来自wxWindow[滚动面板]的子级,如果不是,跳过它并让它过去。在

因此,以下是作为mixin类的解决方案:

class TeMultilineScrollAwareMixin(object):
    """ Mixin class for wx.lib.scrolledpanel.ScrolledPanel so it's
    aware of scroll events from childs with the TE_MULTILINE style
    """

    def __init__(self, *args, **kwargs):
        self._pLastEvtObj = None        
        wx.GetApp().Bind(wx.EVT_MOUSEWHEEL, self.OnUnhandledMouseWheel)

    def OnUnhandledMouseWheel(self, event):
        # stops the same event object being processed repeatedly
        if self._pLastEvtObj == event.GetEventObject():
            return False

        self._pLastEvtObj = event.GetEventObject()

        def is_child_evt():
            parent = event.GetEventObject().GetParent()
            while parent:
                if parent == self: 
                    return True
                parent = parent.GetParent() 
            return False

        # as we are listening at app level, must ensure that event is from a widget of us
        if is_child_evt():
            print 'event from %s' % event.GetEventObject().__class__.__name__
            # if the event was not handled this window will handle it,
            # which is why we need the protection code at the beginning
            # of this method
            self.GetEventHandler().ProcessEvent(event)            
        else:
            # it's not of our interest, let it go
            event.Skip()

        self._pLastEvtObj = None
        return

记住在添加mixin之后初始化mixin,这样就完成了:

^{pr2}$

相关问题 更多 >

    热门问题