wxpython拖放焦点问题

时间:2009-09-22 15:16:50

标签: python drag-and-drop wxpython focus

我想在wxPython中实现拖放操作,其工作方式类似于写字板/ Eclipse等。我的意思如下:

当某些内容被放到写字板上时,写字板窗口位于顶部,焦点和文字被添加。在Eclipse编辑器中,文本被粘贴,Eclipse窗口获得了焦点并位于顶部。

当我使用wxPython实现拖放时,目标窗口没有被带到前面。我以类似于(拖动)的方式实现了拖放:

import wx

class DragFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None)
        self.tree = wx.TreeCtrl(self, wx.ID_ANY)
        root = self.tree.AddRoot("root item")
        self.tree.AppendItem(root, "child 1")
        self.tree.Bind(wx.EVT_TREE_BEGIN_DRAG, self.__onBeginDrag)        
    def __onBeginDrag(self, event):
        tdo = wx.PyTextDataObject(self.tree.GetItemText(event.GetItem()))
        dropSource = wx.DropSource(self.tree)
        dropSource.SetData(tdo)
        dropSource.DoDragDrop(True)

app = wx.PySimpleApp()
frame = DragFrame()
app.SetTopWindow(frame)
frame.Show()
app.MainLoop()

第二个程序(drop):

import wx
class TextDropTarget(wx.TextDropTarget):
    def __init__(self, obj):
        wx.TextDropTarget.__init__(self)
        self.obj = obj
    def OnDropText(self, x, y, data):
        self.obj.WriteText(data + '\n\n')
        wx.MessageBox("Error", "Error", style = wx.ICON_ERROR)

class DropFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None)
        text = wx.TextCtrl(self, wx.ID_ANY)
        text.SetDropTarget(TextDropTarget(text))

app = wx.PySimpleApp()
frame = DropFrame()
app.SetTopWindow(frame)
frame.Show()
app.MainLoop()

当你运行这两个程序时,将窗口放在屏幕的中心(可以看到拖放窗口的一部分),然后将一个节点从拖动窗口拖到拖放窗口 - 目标窗口显示消息框,这是不可见的,目标窗口隐藏在源窗口后面。

如何实现专注于第二个(目标)窗口的拖放操作?我尝试添加window.Show(),window.SetFocus(),甚至使用WinAPI的一些功能(通过win32gui)。我认为应该有一些标准的方法来做到这一点。我错过了什么?

2 个答案:

答案 0 :(得分:1)

这不会起作用吗?

class DropFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None)
        text = wx.TextCtrl(self, wx.ID_ANY)
        self.SetFocus() # Set's the focus to this window, allowing it to receive keyboard input.
        text.SetDropTarget(TextDropTarget(text))

wx.Frame继承自wx.WindowSetFocus(self)


我刚刚测试过它并且有效。只是在SetFocus之前移动SetDropTarget,因为它是一种更清洁的行为。

答案 1 :(得分:1)

您需要在DropTarget的DragOver方法中执行任何您想要的操作,例如:在那里你可以提高并设置你的窗口焦点

目标

的工作代码示例
import wx
class TextDropTarget(wx.TextDropTarget):
    def __init__(self, obj, callback):
        wx.TextDropTarget.__init__(self)
        self.obj = obj
        self._callback = callback

    def OnDropText(self, x, y, data):
        self.obj.WriteText(data + '\n\n')
        wx.MessageBox("Error", "Error", style = wx.ICON_ERROR)

    def OnDragOver(self, *args):
        wx.CallAfter(self._callback)
        return wx.TextDropTarget.OnDragOver(self, *args)

class DropFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None)
        text = wx.TextCtrl(self, wx.ID_ANY)
        text.SetDropTarget(TextDropTarget(text, self._callback))

    def _callback(self):
        self.Raise()
        self.SetFocus()

app = wx.PySimpleApp()
frame = DropFrame()
app.SetTopWindow(frame)
frame.Show()
app.MainLoop()