wxPython Cookbook (Chatper1)part 3

来源:互联网 发布:程序员用什么输入法 编辑:程序博客网 时间:2024/06/11 08:44
应用剪贴板
剪贴板(Clipboard)是系统广泛应用的在应用之间获取数据的方式。这个部分将展示如何从剪贴版获得文本,同样如何把文本放到剪贴板上以供其他应用来使用。
How to do it?
译注:下面两个函数用来从剪贴板获取(GetClipboardText)和放入文本(SetClipboardText),点击"Copy"按钮便把第一个输入框(copyCtr)中文本放入剪贴板,点击“Paste”按钮便使第二个输入框(pastCtr)获取剪贴板的文本。在Windows系统中其余应用中复制到剪贴板的文本也可以粘贴到第二个输入框,第一个输入框的内容也可以粘贴到其他程序中。
import wxclass ClipboardFrame(wx.Frame):    def __init__(self, parent, id = wx.ID_ANY, title = "",                 pos = wx.DefaultPosition, size = wx.DefaultSize,                 style = wx.DEFAULT_FRAME_STYLE, name = "ClipboardFrame"):                     super(ClipboardFrame, self).__init__(parent, id, title,                                                            pos, size, style, name)                     panel = wx.Panel(self)                     copyBt = wx.Button(panel, label = "Copy")                     pastBt = wx.Button(panel, label = "Paste")                     self.copyCtr = wx.TextCtrl(panel)                     self.pastCtr = wx.TextCtrl(panel)                                          copyBt.Bind(wx.EVT_BUTTON, self.OnCopy)                     pastBt.Bind(wx.EVT_BUTTON, self.OnPast)                                          box1 = wx.BoxSizer(wx.HORIZONTAL)                     box1.Add(copyBt, 1, wx.EXPAND)                     box1.Add(pastBt, 1, wx.EXPAND)                     box2 = wx.BoxSizer(wx.HORIZONTAL)                     box2.AddMany([self.copyCtr, self.pastCtr])                     pbox = wx.BoxSizer(wx.VERTICAL)                     pbox.Add(box1, 1, wx.EXPAND)                     pbox.Add(box2, 1, wx.EXPAND)                     panel.SetSizer(pbox)                     pbox.Fit(self)                     fbox = wx.BoxSizer(wx.VERTICAL)                     fbox.Add(panel)                     self.SetSizer(fbox)        def OnCopy(self, event):        print "OnCopy Trigger!\n"        self.SetClipboardText(self.copyCtr.GetValue())        def OnPast(self, event):        print "OnPast Trigger!\n"        self.pastCtr.SetValue(self.GetClipboardText())        def SetClipboardText(self,text):        """Put text in the clipboard        @param text: string        """        data_o = wx.TextDataObject()        data_o.SetText(text)        if wx.TheClipboard.IsOpened() or wx.TheClipboard.Open():            wx.TheClipboard.SetData(data_o)            wx.TheClipboard.Close()         def GetClipboardText(self):        """Get text from the clipboard        @return: string        """        text_obj = wx.TextDataObject()        rtext = ""        if wx.TheClipboard.IsOpened() or wx.TheClipboard.Open():            if wx.TheClipboard.GetData(text_obj):                rtext = text_obj.GetText()                wx.TheClipboard.Close()        return rtext                                                if __name__ == "__main__":    app = wx.PySimpleApp(False)    ClipboardFrame(None).Show()    app.MainLoop()

How it works?
wxPython提供一个单例(singleton)剪贴板对象来与系统的剪贴板交互。这个类针对代表系统底层数据类型的数据对象(data object)来工作。使用剪贴板包括下面三个步骤:
  1. 打开一个剪贴板
  2. 设置(Set)或获取(Get)数据对象
  3. 关闭剪贴板
There's more
剪贴板除了文本外还支持很多其他类型的数据类型。wxPython为你自己定义的数据类型也提供了内置(built-in)支持。下面各种不同数据类型的应用模式跟文本数据(TextDataObject)类似。
  • wx.BitmapDataObject:Bitmap类型
  • wx.CustomDataObject:任意Python序列化对象
  • wx.DataObjectComposite:Can contain any arbitrary number of simple data types  and make them all available at once
  • wx.FileDataObject:文件名称
  • wx.URLDataObject:URL地址

支持拖放(Drag and Drop)
为了提升可用性,在应用中最好能支持拖放操作,这样便于用户通过简单的拖放文件或其它对象来操作你的应用。这个部分将向你展示如何支持一个CompositeDataOjbect,其支持文件和文本。
How to do it?
import wxclass FileAndTextDropTarget(wx.PyDropTarget):    """Drop target capable of accepting dropped     files and text"""    def __init__(self, file_callback, text_callback):        print "FileAndTextDropTarget Initializing!\n"        assert callable(file_callback)        assert callable(text_callback)        super(FileAndTextDropTarget, self).__init__()# Attributes        self.fcallback = file_callback # Drop File Callback        self.tcallback = text_callback # Drop Text Callback        self._data = None        self.txtdo = None        self.filedo = None# Setup        self.InitObjects()            def InitObjects(self):        """Initializes the text and file data objects"""        print "InitObjects Trigger!\n"        self._data = wx.DataObjectComposite()        self.txtdo = wx.TextDataObject()        self.filedo = wx.FileDataObject()        self._data.Add(self.txtdo, False)        self._data.Add(self.filedo, True)        self.SetDataObject(self._data)            def OnData(self, x_cord, y_cord, drag_result):        """Called by the framework when data is dropped         on the target        """        print "OnData Trigger!\n"        if self.GetData():            data_format = self._data.GetReceivedFormat()            if data_format.GetType() == wx.DF_FILENAME:                self.fcallback(self.filedo.GetFilenames())            else:                self.tcallback(self.txtdo.GetText())        return drag_result        class DropTargetFrame(wx.Frame):    def __init__(self, parent, id = wx.ID_ANY, title = "",                 pos = wx.DefaultPosition, size = wx.DefaultSize,                 style = wx.DEFAULT_FRAME_STYLE, name = "DropTargetFrame"):                     super(DropTargetFrame, self).__init__(parent, id, title,                                                    pos, size, style, name)                                         choices = ["Drag and Drop Text or Files here", ]                     self.list = wx.ListBox(self,                                            choices = choices)                     self.dt = FileAndTextDropTarget(self.OnFileDrop,                                                     self.OnTextDrop)                     self.list.SetDropTarget(self.dt)                     self.CreateStatusBar()                     self.Fit()        def OnFileDrop(self, files):        print "OnFileDrop Trigger!\n"        self.PushStatusText("Files Dropped")        for f in files:            self.list.Append(f)        def OnTextDrop(self, text):        print "OnTextDrop Trigger!\n"        self.PushStatusText("Text Dropped")        self.list.Append(text)     if __name__ == "__main__":    app = wx.PySimpleApp(False)    DropTargetFrame(None).Show()    app.MainLoop()

How it works?
当窗口收到拖放的数据,框架(framework)将调用我们DropTarget中的OnData方法。在OnData方法中,我们简单从DataObject中获取数据并将它传递给合适的回调函数,由窗口来决定如何处理这些数据。所有的窗口对象都有SetDropTarget方法来用于设置一个DropTarget,所以这个类(FileAndTextDropTarget)可以在其他任何控件中复用。在上面的例子中,我们用列表框(ListBox)来展示拖放的数据。
     译注:可以把“拖放”类理解为一个事件(event),这里需要我们继承 wx.PyDropTarget类,并设置支持的数据类型,本例子中就是文本(text)和文件(file)。在窗口(window)对象中的SetDropTarget相当于一个事件绑定,当有拖放事件时,便调用OnData回调方法进行处理。在例子中,OnData方法再根据拖放进入的不同数据类型,来调用窗口(window)中不同方法来处理。以拖放“hello world.txt”为例,其内容是“HELLO WORLD!”,发现windows下的记事本无法拖放文本,故需要在记事本下打开并选择文本拖放,下面两个图就是拖放的效果。

           
There's more
PyDropTarget类可以在拖拽的过程中提供许多其他的方法。这些方法可以被重现,这样便于实现变换鼠标图标,展示拖放图像,或拒绝拖放对象等操作。
  • OnEnter(x, y, drag_result) 当拖放对象进入窗口时调用。返回一个拖放的结果值。
  • OnDragOver(x, y, drag_result)当鼠标拖放一个对象在目标之上时调用。
  • OnLeave() 当鼠标离开拖放对象时调用
  • OnDrop(x, y)当用户释放对象时调用。返回True表示接受对象或者False表示拒绝
  • OnData(x, y, drag_result) 当对象被接受后,在OnDrop后调用。



0 0
原创粉丝点击