共计 4134 个字符,预计需要花费 11 分钟才能阅读完成。
wxPython 中的拖放
在计算机图形用户界面中,拖放是指导击一个虚构对象并将其拖到不同的地位或另一个虚构对象上的动作(或反对该动作)。一般来说,它能够用来调用多种操作,或者在两个形象对象之间创立各种类型的关联。
拖放操作能够让你直观地实现简单的事件。
在拖放操作中,咱们将一些数据从数据源拖到数据指标上。所以咱们必须要有
- 一些数据
- 一个数据源
- 一个数据指标
在 wxPython 中,咱们有两个预约义的数据指标。wx.TextDropTarget
和wx.FileDropTarget
。
wx.TextDropTarget
wx.TextDropTarget
是一个预约义的用于解决文本数据的投放指标。
#dragdrop_text.py
from pathlib import Path
import os
import wx
class MyTextDropTarget(wx.TextDropTarget):
def __init__(self, object):
wx.TextDropTarget.__init__(self)
self.object = object
def OnDropText(self, x, y, data):
self.object.InsertItem(0, data)
return True
class Example(wx.Frame):
def __init__(self, *args, **kw):
super(Example, self).__init__(*args, **kw)
self.InitUI()
def InitUI(self):
splitter1 = wx.SplitterWindow(self, style=wx.SP_3D)
splitter2 = wx.SplitterWindow(splitter1, style=wx.SP_3D)
home_dir = str(Path.home())
self.dirWid = wx.GenericDirCtrl(splitter1, dir=home_dir,
style=wx.DIRCTRL_DIR_ONLY)
self.lc1 = wx.ListCtrl(splitter2, style=wx.LC_LIST)
self.lc2 = wx.ListCtrl(splitter2, style=wx.LC_LIST)
dt = MyTextDropTarget(self.lc2)
self.lc2.SetDropTarget(dt)
self.Bind(wx.EVT_LIST_BEGIN_DRAG, self.OnDragInit, id=self.lc1.GetId())
tree = self.dirWid.GetTreeCtrl()
splitter2.SplitHorizontally(self.lc1, self.lc2, 150)
splitter1.SplitVertically(self.dirWid, splitter2, 200)
self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelect, id=tree.GetId())
self.OnSelect(0)
self.SetTitle('Drag and drop text')
self.Centre()
def OnSelect(self, event):
list = os.listdir(self.dirWid.GetPath())
self.lc1.ClearAll()
self.lc2.ClearAll()
for i in range(len(list)):
if list[i][0] != '.':
self.lc1.InsertItem(0, list[i])
def OnDragInit(self, event):
text = self.lc1.GetItemText(event.GetIndex())
tdo = wx.TextDataObject(text)
tds = wx.DropSource(self.lc1)
tds.SetData(tdo)
tds.DoDragDrop(True)
def main():
app = wx.App()
ex = Example(None)
ex.Show()
app.MainLoop()
if __name__ == '__main__':
main()
<img src=”https://mymarkdowm.oss-cn-beijing.aliyuncs.com/markdownimg/image-20201031161853768.png” alt=”image-20201031161853768″ style=”zoom:50%;” />
在本例中,咱们在 wx.GenericDirCtrl
中显示了一个文件系统。所选目录的内容显示在右上角的列表控件中,文件名能够拖放到右下角的列表控件中。
def OnDropText(self, x, y, data):
self.object.InsertItem(0, data)
return True
当咱们将文本数据投放到指标上时,通过 InsertItem()办法将数据插入到列表控件中。
dt = MyTextDropTarget(self.lc2)
self.lc2.SetDropTarget(dt)
一个下拉指标被创立。咱们应用 SetDropTarget()办法将投放指标设置为第二个列表控件。
self.Bind(wx.EVT_LIST_BEGIN_DRAG, self.OnDragInit, id=self.lc1.GetId())
当拖动操作开始时,会调用 OnDragInit()办法。
def OnDragInit(self, event):
text = self.lc1.GetItemText(event.GetIndex())
tdo = wx.TextDataObject(text)
tds = wx.DropSource(self.lc1)
...
在 OnDragInit()
办法中,咱们创立一个wx.TextDataObject
,其中蕴含咱们的文本数据。从第一个列表控件中创立一个投放源。
tds.SetData(tdo)
tds.DoDragDrop(True)
咱们用 SetData()为投放源设置数据,用 DoDragDrop()启动拖放操作。
wx.FileDropTarget
wx.FileDropTarget
是一个能够承受从文件管理器中拖动的文件的投放指标。
#dragdrop_file.py
import wx
class FileDrop(wx.FileDropTarget):
def __init__(self, window):
wx.FileDropTarget.__init__(self)
self.window = window
def OnDropFiles(self, x, y, filenames):
for name in filenames:
try:
file = open(name, 'r')
text = file.read()
self.window.WriteText(text)
except IOError as error:
msg = "Error opening file\n {}".format(str(error))
dlg = wx.MessageDialog(None, msg)
dlg.ShowModal()
return False
except UnicodeDecodeError as error:
msg = "Cannot open non ascii files\n {}".format(str(error))
dlg = wx.MessageDialog(None, msg)
dlg.ShowModal()
return False
finally:
file.close()
return True
class Example(wx.Frame):
def __init__(self, *args, **kw):
super(Example, self).__init__(*args, **kw)
self.InitUI()
def InitUI(self):
self.text = wx.TextCtrl(self, style = wx.TE_MULTILINE)
dt = FileDrop(self.text)
self.text.SetDropTarget(dt)
self.SetTitle('File drag and drop')
self.Centre()
def main():
app = wx.App()
ex = Example(None)
ex.Show()
app.MainLoop()
if __name__ == '__main__':
main()
<img src=”https://mymarkdowm.oss-cn-beijing.aliyuncs.com/markdownimg/image-20201031162055685.png” alt=”image-20201031162055685″ style=”zoom:50%;” />
这个例子创立了一个简略的 wx.TextCtrl。咱们能够从文件管理器中拖动文本文件到控件中。
def OnDropFiles(self, x, y, filenames):
for name in filenames:
...
咱们能够一次拖放多个文件。
try:
file = open(name, 'r')
text = file.read()
self.window.WriteText(text)
咱们以只读模式关上文件,获取其内容并将内容写入文本管制窗口。
except IOError as error:
msg = "Error opening file\n {}".format(str(error))
dlg = wx.MessageDialog(None, msg)
dlg.ShowModal()
return False
如果呈现输出 / 输入谬误,咱们将显示一个音讯对话框并终止操作。
self.text = wx.TextCtrl(self, style = wx.TE_MULTILINE)
dt = FileDrop(self.text)
self.text.SetDropTarget(dt)
wx.TextCtrl 是拖放指标。