【问题标题】:WXPython Event Handling - ButtonWXPython 事件处理 - 按钮
【发布时间】:2021-11-15 11:40:50
【问题描述】:

当我运行以下代码时,我收到错误消息(附图)那?另一个问题是,当我点击 左侧面板 上的 Big Script 时,我想调用该特定按钮,但是我不知道如何执行此操作,我尝试将按钮放在OnSelChanged 方法,但我无法使其工作。

整个代码都在下面,所以更容易复制粘贴。

import wx
from wx.core import Font, Position, Size
import wx.lib.newevent
from wx.lib.agw.customtreectrl import CustomTreeCtrl

def onButton(event):
    print("Button Pressed")

#---------------------------------------------------------------------------

class MyTree(wx.TreeCtrl):
    """
    Our customized TreeCtrl class.
    """
    def __init__(self, parent, id, position, size, style):
        """
        Initialize our tree.
        """
        wx.TreeCtrl.__init__(self, parent, id, position, size, style)
       
        root = self.AddRoot('Programmer')
        
        os = self.AppendItem(root, '???? Big Script')
        pl = self.AppendItem(root, '???? Big Script2')
        tk = self.AppendItem(root, 'Big Script3')
           
        cl = self.AppendItem(pl, 'Random Scripts')
        sl = self.AppendItem(pl, 'Miscelanious')

        self.AppendItem(os, 'Script1')
        self.AppendItem(os, 'Script2')
        self.AppendItem(os, 'Script3')
        self.AppendItem(os, 'Script4')
        self.AppendItem(cl, 'Script1')
        self.AppendItem(cl, 'Script2')
        self.AppendItem(cl, 'Script3')
        self.AppendItem(sl, '1')
        self.AppendItem(sl, '2')
        self.AppendItem(sl, '3')
        self.AppendItem(sl, '4')
        self.AppendItem(tk, 'Script1')
        self.AppendItem(tk, 'Script2')
        self.AppendItem(tk, 'Script3')
        self.AppendItem(tk, 'Script4+')
        self.AppendItem(tk, 'Script5')

#---------------------------------------------------------------------------
        
class MyFrame(wx.Frame):
    """
    Our customized window class.
    """
    def __init__(self, parent, id, title):
        """
        Initialize our window.
        """
        wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition, wx.Size(800, 600))

        #self.SetIcon(wx.Icon('./icons/wxwin.ico', wx.BITMAP_TYPE_ICO))

        #------------
        
        # Create a splitter window.
        self.splitter = wx.SplitterWindow(self, -1, style=wx.SP_LIVE_UPDATE)
        
        # Create the left panel.
        leftPanel = wx.Panel(self.splitter, -1)
        
        # Create our tree and put it into the left panel.
        self.tree = MyTree(leftPanel, 1,
                           wx.DefaultPosition,
                           wx.DefaultSize,
                           wx.TR_HIDE_ROOT |
                           wx.TR_HAS_BUTTONS)
        self.tree.SetBackgroundColour('#3DB2FF')

        # Bind the OnSelChanged method to the tree.
        self.tree.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelChanged, id=1)
        

        # Create the right panel.
        rightPanel = wx.Panel(self.splitter, -1, style=wx.SUNKEN_BORDER)
        rightPanel.SetBackgroundColour('#79B4B7')
        
        # Create a widget to display static text 
        # and store it in the right panel.
        self.display = wx.StaticText(rightPanel, -1, '', style=wx.ALIGN_CENTER)
        #item =  self.display.SetLabel(self.tree.GetItemText())
        #print(item)
        
        # Put the left and right panes into the split window.
        self.splitter.SplitVertically(leftPanel, rightPanel, 200)

        # Minimum size of subwindow.
        self.splitter.SetMinimumPaneSize(1)         

        #------------

        # Create a box sizer that will contain the left panel contents.
        leftBox = wx.BoxSizer(wx.VERTICAL)
        
        # Add the tree to the box sizer.
        leftBox.Add(self.tree, 1, wx.EXPAND)
        
        # Set the size of the right panel to that required by the tree.
        leftPanel.SetSizer(leftBox)
        
        # Create the right box sizer that will contain the panel's contents.
        rightBox = wx.BoxSizer(wx.VERTICAL)
        
        # Add the display widget to the right panel.
        rightBox.Add(self.display, 0, wx.ALL, 1)


        self.button = wx.Button(rightPanel, wx.ID_ANY, 'Test', pos=(225, 2000))
        rightBox.Add(self.button)
        self.button.Bind(wx.EVT_BUTTON, onButton)
        print(self.button.GetScreenPosition())

        # Set the size of the right panel to that 
        # required by the display widget.
        rightPanel.SetSizer(rightBox)
        #------------
        
        # Create the window in the centre of the screen.
        self.Centre()

    #-----------------------------------------------------------------------
        
    def OnSelChanged(self, event):
        """
        Method called when selected item is changed.
        """
        
        # Get the selected item object.
        item =  event.GetItem()

        overview = """
        This demo simply catches all key events and prints info about them.
        It is meant to be used as a compatibility test for cross platform work.
        """
        
        # Display the selected item text in the text widget.
        if self.tree.GetItemText(item) == '???? Big Script':
            self.display.SetLabel(f"{self.tree.GetItemText(item)}\n {overview}")
        else: 
            self.display.SetLabel(self.tree.GetItemText(item))
        
        return item

        #print(self.tree.GetItemText(item))

#---------------------------------------------------------------------------
        
class MyApp(wx.App):
    """
    Our application class.
    """
    def OnInit(self):
        """
        Initialize by creating the split window with the tree.
        """
        
        frame = MyFrame(None, -1, 'Test1')
        frame.Show(True)
        self.SetTopWindow(frame)
        
        return True

#---------------------------------------------------------------------------
    
if __name__ == '__main__':
    app = MyApp(0)
    app.MainLoop()

最后一个问题是,除了文档之外,您是否知道任何其他资源可以更深入地了解这个库? (Youtube 视频、Udemy 等)

【问题讨论】:

  • 未来的一点。问多个问题被认为是不好的形式。当您盯着代码枪的枪管时,一口气解决所有问题的冲动很强烈,但问题是上下文。许多人使用 SO 来搜索问题的特定解决方案,并且希望将其封装在问题标题中。在一个问题中提出多个问题,意味着解决方案被埋没并且变得难以找到。虽然这很痛苦,但为了清楚起见,最好提出多个重点问题。

标签: python python-3.x user-interface event-handling wxpython


【解决方案1】:

首先是www.wxpython.org。然后是讨论.wxpython.org。但真正的学习方法是找到适合您平台的演示,其中包含易于浏览的示例以及您可以窃取的代码。转到www.wxpython.org 并向下滚动到“额外文件”部分以查找演示。 至于您的按钮位置问题,在 wxpython 中控制事物位置的最佳方法是使用 sizers。有关示例,请参见演示。

【讨论】:

    【解决方案2】:

    有几点要提:
    在使用 sizer 时使用 position 语句是没有意义的,它将被忽略。

    sizer 类型决定了位置。您选择了垂直 boxsizer,因此所有内容都将垂直排列。您可以在添加小部件时使用对齐样式或选择不同的尺寸器类型,更符合您的要求。

    我已经在类中移动了按钮的回调函数。

    按钮回调函数可以单独调用,如果你不依赖事件值,你发送一个虚拟事件参数,通常是None

    import wx
    from wx.core import Font, Position, Size
    import wx.lib.newevent
    from wx.lib.agw.customtreectrl import CustomTreeCtrl
    
    #---------------------------------------------------------------------------
    
    class MyTree(wx.TreeCtrl):
        """
        Our customized TreeCtrl class.
        """
        def __init__(self, parent, id, position, size, style):
            """
            Initialize our tree.
            """
            wx.TreeCtrl.__init__(self, parent, id, position, size, style)
           
            root = self.AddRoot('Programmer')
            
            os = self.AppendItem(root, '? Big Script')
            pl = self.AppendItem(root, '? Big Script2')
            tk = self.AppendItem(root, 'Big Script3')
               
            cl = self.AppendItem(pl, 'Random Scripts')
            sl = self.AppendItem(pl, 'Miscelanious')
    
            self.AppendItem(os, 'Script1')
            self.AppendItem(os, 'Script2')
            self.AppendItem(os, 'Script3')
            self.AppendItem(os, 'Script4')
            self.AppendItem(cl, 'Script1')
            self.AppendItem(cl, 'Script2')
            self.AppendItem(cl, 'Script3')
            self.AppendItem(sl, '1')
            self.AppendItem(sl, '2')
            self.AppendItem(sl, '3')
            self.AppendItem(sl, '4')
            self.AppendItem(tk, 'Script1')
            self.AppendItem(tk, 'Script2')
            self.AppendItem(tk, 'Script3')
            self.AppendItem(tk, 'Script4+')
            self.AppendItem(tk, 'Script5')
    
    #---------------------------------------------------------------------------
            
    class MyFrame(wx.Frame):
        """
        Our customized window class.
        """
        def __init__(self, parent, id, title):
            """
            Initialize our window.
            """
            wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition, wx.Size(800, 600))
    
            #self.SetIcon(wx.Icon('./icons/wxwin.ico', wx.BITMAP_TYPE_ICO))
    
            #------------
            
            # Create a splitter window.
            self.splitter = wx.SplitterWindow(self, -1, style=wx.SP_LIVE_UPDATE)
            
            # Create the left panel.
            leftPanel = wx.Panel(self.splitter, -1)
            
            # Create our tree and put it into the left panel.
            self.tree = MyTree(leftPanel, 1,
                               wx.DefaultPosition,
                               wx.DefaultSize,
                               wx.TR_HIDE_ROOT |
                               wx.TR_HAS_BUTTONS)
            self.tree.SetBackgroundColour('#3DB2FF')
    
            # Bind the OnSelChanged method to the tree.
            self.tree.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelChanged, id=1)
            
    
            # Create the right panel.
            rightPanel = wx.Panel(self.splitter, -1, style=wx.SUNKEN_BORDER)
            rightPanel.SetBackgroundColour('#79B4B7')
            
            # Create a widget to display static text 
            # and store it in the right panel.
            self.display = wx.StaticText(rightPanel, -1, '', style=wx.ALIGN_CENTER)
            #item =  self.display.SetLabel(self.tree.GetItemText())
            #print(item)
            
            # Put the left and right panes into the split window.
            self.splitter.SplitVertically(leftPanel, rightPanel, 200)
    
            # Minimum size of subwindow.
            self.splitter.SetMinimumPaneSize(1)         
    
            #------------
    
            # Create a box sizer that will contain the left panel contents.
            leftBox = wx.BoxSizer(wx.VERTICAL)
            
            # Add the tree to the box sizer.
            leftBox.Add(self.tree, 1, wx.EXPAND)
            
            # Set the size of the right panel to that required by the tree.
            leftPanel.SetSizer(leftBox)
            
            # Create the right box sizer that will contain the panel's contents.
            rightBox = wx.BoxSizer(wx.VERTICAL)
            
            # Add the display widget to the right panel.
            rightBox.Add(self.display, 0, wx.ALL, 1)
    
    
            #self.button = wx.Button(rightPanel, wx.ID_ANY, 'Test', pos=(225, 2000))
            # You're using a Sizer to arrange the contents of rightPanel so "position" is meaningless
            self.button = wx.Button(rightPanel, wx.ID_ANY, 'Test')
            # Use an alignment parameter or choose a sizer other than a boxsizer
            rightBox.Add(self.button,0,wx.ALIGN_RIGHT|wx.ALL, 20)
            self.button.Bind(wx.EVT_BUTTON, self.onButton)
    
            # Set the size of the right panel to that 
            # required by the display widget.
            rightPanel.SetSizer(rightBox)
            #------------
            
            # Create the window in the centre of the screen.
            self.Centre()
    
        #-----------------------------------------------------------------------
        def onButton(self, event):
            print("Button Pressed")
            
        def OnSelChanged(self, event):
            """
            Method called when selected item is changed.
            """
            
            # Get the selected item object.
            item =  event.GetItem()
    
            overview = """
            This demo simply catches all key events and prints info about them.
            It is meant to be used as a compatibility test for cross platform work.
            """
            
            # Display the selected item text in the text widget.
            if self.tree.GetItemText(item) == '? Big Script':
                self.display.SetLabel(f"{self.tree.GetItemText(item)}\n {overview}")
                # We can call the event function, as long as we set a value of something for the event parameter
                self.onButton(None)
            else: 
                self.display.SetLabel(self.tree.GetItemText(item))
            
    #---------------------------------------------------------------------------
            
    class MyApp(wx.App):
        """
        Our application class.
        """
        def OnInit(self):
            """
            Initialize by creating the split window with the tree.
            """
            
            frame = MyFrame(None, -1, 'Test1')
            frame.Show(True)
            self.SetTopWindow(frame)
            
            return True
    
    #---------------------------------------------------------------------------
        
    if __name__ == '__main__':
        app = MyApp()
        app.MainLoop()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-04
      • 2012-11-08
      • 1970-01-01
      相关资源
      最近更新 更多