Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在两个(或多个)WXLISTCRL(wxGTK)之间拖放?_C++_Wxwidgets - Fatal编程技术网

C++ 如何在两个(或多个)WXLISTCRL(wxGTK)之间拖放?

C++ 如何在两个(或多个)WXLISTCRL(wxGTK)之间拖放?,c++,wxwidgets,C++,Wxwidgets,我正在尝试组织一个wxListCtrl派生控件(xList),该控件支持项之间的DnD(LC\u REPORT视图)。所以,我抓住了开始拖动事件 Connect(wxEVT_COMMAND_LIST_BEGIN_DRAG, (wxObjectEventFunction)&xList::OnBeginDrag ); 而OnBeginDrag功能的设计方式是捕捉xList(list)的每个实例的鼠标运动和鼠标左键向上事件: (和onendrag将它们全部断开)

我正在尝试组织一个wxListCtrl派生控件(
xList
),该控件支持项之间的DnD(
LC\u REPORT
视图)。所以,我抓住了开始拖动事件

Connect(wxEVT_COMMAND_LIST_BEGIN_DRAG,
        (wxObjectEventFunction)&xList::OnBeginDrag
       );
OnBeginDrag
功能的设计方式是捕捉
xList
list
)的每个实例的鼠标运动和鼠标左键向上事件:

(和
onendrag
将它们全部断开)。当我有一个
xList
实例(一个面板)时,它工作得很好,但当我有两个实例时,它看起来像是运动,左起事件只在我开始拖动的面板上被捕捉到:我可以在单个面板内进行DnD,但当我将鼠标从一个面板拖动到另一个面板时,它仍然像第一个面板一样工作。我错过了什么

是否分别为每个小部件处理
wxEVT\u运动
?如果是,为什么程序会这样做。如果不是,为什么我开始拖动的小部件总是处理它,而不是最后一个连接的小部件

下面是一个示例代码(尽可能简单)来说明发生了什么:

#include <wx/wx.h>
#include <vector>

class xList;

// class to store group of xList to DnD between
class DnDxList
   {public:
       void BeginDrag ();
       void EndDrag ();
       void AddList (xList* l) {list.push_back (l); }; // register new xList object
    private:
       std::vector<xList*> list;
   };


class xList: public wxListCtrl
   {public:
       xList (DnDxList& dnd,
              wxWindow *parent,
              wxWindowID winid = wxID_ANY,
              const wxPoint& pos = wxDefaultPosition,
              const wxSize& size = wxDefaultSize,
              long style = wxLC_ICON,
              const wxValidator &validator = wxDefaultValidator,
              const wxString &name = wxListCtrlNameStr
             );
       virtual ~xList () {};
       void OnBeginDrag(wxListEvent& event);
       void OnEndDrag(wxMouseEvent& event);
       void OnMoveDrag(wxMouseEvent& event);

       DnDxList& dndsource; // keep reference to common DnDxList object
   };


void DnDxList::BeginDrag () // connect motion and left-up events for all lists in group
   {for (std::vector<xList*>::const_iterator i = list.begin(); i != list.end(); i++)
        {(*i)->Connect(wxEVT_MOTION,
                           wxMouseEventHandler(xList::OnMoveDrag)
                      );
         (*i)->Connect(wxEVT_LEFT_UP,
                       wxMouseEventHandler(xList::OnEndDrag)
                      );
        }
   };

void DnDxList::EndDrag () // disconnect all
   {for (std::vector<xList*>::const_iterator i = list.begin(); i != list.end(); i++)
        {(*i)->Disconnect(wxEVT_MOTION,
                          wxMouseEventHandler(xList::OnMoveDrag)
                         );
         (*i)->Disconnect(wxEVT_LEFT_UP,
                          wxMouseEventHandler(xList::OnEndDrag)
                         );
        }
   }




xList::xList (DnDxList& dnd,
              wxWindow *parent,
              wxWindowID winid,
              const wxPoint& pos,
              const wxSize& size,
              long style,
              const wxValidator &validator,
              const wxString &name
             ): wxListCtrl (parent, winid, pos, size, style, validator, name),
                dndsource (dnd)
   {Connect(wxEVT_COMMAND_LIST_BEGIN_DRAG,
            (wxObjectEventFunction)&xList::OnBeginDrag
           );
    dndsource.AddList (this);
   };


void xList::OnBeginDrag(wxListEvent& event) // begin drag
   {SetCursor(wxCursor(wxCURSOR_HAND));
    dndsource.BeginDrag();
   }

void xList::OnMoveDrag(wxMouseEvent& event) 
   {std::cout << "Movie: " << this << std::endl;  // to show the object for which the move event is called for
   }

void xList::OnEndDrag(wxMouseEvent& event) 
   {std::cout << "End: " << this << std::endl;
    dndsource.EndDrag();
    SetCursor(wxCursor(*wxSTANDARD_CURSOR));
   }


class xFrame: public wxFrame
   {
    public:
        xFrame (const wxString& title,
                const wxPoint& pos,
                const wxSize& size
               );
        ~xFrame () { }
    private:

        void OnExit(wxCommandEvent& event);
        DECLARE_EVENT_TABLE();

        DnDxList* dndxlist;
        xList* lp;
        xList* rp;
        wxPanel* panel;
   };

BEGIN_EVENT_TABLE(xFrame, wxFrame)
    EVT_MENU(wxID_EXIT, xFrame::OnExit)
END_EVENT_TABLE()


xFrame::xFrame(const wxString& title,
               const wxPoint& pos,
               const wxSize& size
              ): wxFrame(NULL, wxID_ANY, title, pos, size)
  {
   panel = new wxPanel(this);
   wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);

   // create common DnDxList
   dndxlist = new DnDxList(); 
   // create two panels
   lp = new xList (*dndxlist,
                   panel,
                   wxID_ANY,
                   wxDefaultPosition,
                   wxDefaultSize,
                   wxLC_REPORT | wxLC_SINGLE_SEL
                  );
   rp = new xList (*dndxlist,
                   panel,
                   wxID_ANY,
                   wxDefaultPosition,
                   wxDefaultSize,
                   wxLC_REPORT | wxLC_SINGLE_SEL
                  );

   // some contents
   lp->InsertColumn(0, _("A"));
   lp->InsertColumn(1, _("B"));
   lp->InsertColumn(2, _("C"));
   lp->InsertColumn(3, _("D"));

   lp->SetColumnWidth(0, 100);
   lp->SetColumnWidth(1, 100);
   lp->SetColumnWidth(2, 100);
   lp->SetColumnWidth(3, 100);


   for (long i = 0; i < 100; i++)
      {lp->InsertItem(i, 1);
       for (int j = 0; j < 4; j++)
          {wxString s;
           s << _("lp [") << i << _(", ") << j << _("]");
           lp->SetItem (i, j, s);
          }
      }

   rp->InsertColumn(0, _("A"));
   rp->InsertColumn(1, _("B"));
   rp->InsertColumn(2, _("C"));
   rp->InsertColumn(3, _("D"));

   rp->SetColumnWidth(0, 100);
   rp->SetColumnWidth(1, 100);
   rp->SetColumnWidth(2, 100);
   rp->SetColumnWidth(3, 100);


   for (long i = 0; i < 100; i++)
      {rp->InsertItem(i, 1);
       for (int j = 0; j < 4; j++)
          {wxString s;
           s << _("rp [") << i << _(", ") << j << _("]");
           rp->SetItem (i, j, s);
          }
      }

   sizer->Add(lp,1, wxEXPAND | wxALL, 10);
   sizer->Add(rp,1, wxEXPAND | wxALL, 10);
   panel->SetSizer(sizer);


  }

void xFrame::OnExit(wxCommandEvent& event)
  {
   Close( true );
  }


class xApp: public wxApp
   {
    public:
       virtual bool OnInit();
   };

IMPLEMENT_APP(xApp);


bool xApp::OnInit()
   {
    xFrame *frame = new xFrame(_("Frame"), wxPoint(50, 50), wxSize(450, 340) );
    frame->Show(true);
    return true;
   }
#包括
#包括
类别列表;
//类来存储从xList到DnD的组
类DnDxList
{公众:
空生子();
void EndDrag();
void AddList(xList*l){list.push_back(l);};//注册新的xList对象
私人:
std::向量表;
};
类xList:public wxListCtrl
{公众:
xList(DnDxList和dnd),
wxWindow*父级,
wxWindowID winid=wxID_ANY,
常量wxPoint&pos=wxDefaultPosition,
const wxSize&size=wxDefaultSize,
长样式=wxLC_图标,
const wxValidator&validator=wxDefaultValidator,
const wxString&name=wxListCtrlNameStr
);
虚拟~xList(){};
一开始无效(wxListEvent&event);
void onendrag(wxMouseEvent和event);
移动时无效(wxMouseEvent和event);
DnDxList&dndsource;//保留对公共DnDxList对象的引用
};
void DnDxList::BeginDrag()//连接组中所有列表的运动和左起事件
{for(std::vector::const_迭代器i=list.begin();i!=list.end();i++)
{(*i)->连接(wxEVT_运动,
wxMouseEventHandler(xList::OnMoveDrag)
);
(*i)->连接(wxEVT_左上),
wxMouseEventHandler(xList::onendrag)
);
}
};
void DnDxList::EndDrag()//断开所有连接
{for(std::vector::const_迭代器i=list.begin();i!=list.end();i++)
{(*i)->断开(wxEVT_运动,
wxMouseEventHandler(xList::OnMoveDrag)
);
(*i)->断开(wxEVT左上),
wxMouseEventHandler(xList::onendrag)
);
}
}
xList::xList(DnDxList和dnd,
wxWindow*父级,
wxWindowID winid,
常量wxPoint和pos,
const wxSize&size,
长款,
常量wxValidator和validator,
常量wxString&name
):wxListCtrl(父项、winid、pos、大小、样式、验证程序、名称),
数据源(dnd)
{Connect(wxEVT_命令_列表_开始_拖动,
(wxObjectEventFunction)&xList::OnBeginDrag
);
dndsource.AddList(本文件);
};
void xList::OnBeginDrag(wxListEvent&event)//开始拖动
{SetCursor(wxCursor(wxCursor_HAND));
dndsource.BeginDrag();
}
void xList::OnMoveDrag(wxmousevent和event)
{std::cout SetColumnWidth(1100);
lp->SetColumnWidth(2100);
lp->SetColumnWidth(3100);
用于(长i=0;i<100;i++)
{lp->插入项(i,1);
对于(int j=0;j<4;j++)
{wxString s;
s插入柱(3,ud);
rp->SetColumnWidth(01100);
rp->SetColumnWidth(1100);
rp->SetColumnWidth(2100);
rp->SetColumnWidth(3100);
用于(长i=0;i<100;i++)
{rp->插入项(i,1);
对于(int j=0;j<4;j++)
{wxString s;
s秀(真实);
返回true;
}

查看控制台输出,可以发现鼠标移动事件和鼠标左上事件总是调用同一对象的方法,拖动从该对象开始,而不是鼠标实际打开的对象。

wxListCtrl
-特定的拖动事件实际上只用于拖动同一控件内的项。拖放在不同的控件之间,甚至在不同的应用程序之间,您需要使用常规的
wxDragSource
wxDropTarget
类。

好的,谢谢,但是我想知道
wxDragSource
wxDropTarget
是否允许我在移动过程中执行一些操作,因为我想突出显示e用户将要删除,即插入拖动内容的表格行之间的空间。因为如果我只捕获
EVT\u motoin
结果将是相同的。您可以使用此选项。
#include <wx/wx.h>
#include <vector>

class xList;

// class to store group of xList to DnD between
class DnDxList
   {public:
       void BeginDrag ();
       void EndDrag ();
       void AddList (xList* l) {list.push_back (l); }; // register new xList object
    private:
       std::vector<xList*> list;
   };


class xList: public wxListCtrl
   {public:
       xList (DnDxList& dnd,
              wxWindow *parent,
              wxWindowID winid = wxID_ANY,
              const wxPoint& pos = wxDefaultPosition,
              const wxSize& size = wxDefaultSize,
              long style = wxLC_ICON,
              const wxValidator &validator = wxDefaultValidator,
              const wxString &name = wxListCtrlNameStr
             );
       virtual ~xList () {};
       void OnBeginDrag(wxListEvent& event);
       void OnEndDrag(wxMouseEvent& event);
       void OnMoveDrag(wxMouseEvent& event);

       DnDxList& dndsource; // keep reference to common DnDxList object
   };


void DnDxList::BeginDrag () // connect motion and left-up events for all lists in group
   {for (std::vector<xList*>::const_iterator i = list.begin(); i != list.end(); i++)
        {(*i)->Connect(wxEVT_MOTION,
                           wxMouseEventHandler(xList::OnMoveDrag)
                      );
         (*i)->Connect(wxEVT_LEFT_UP,
                       wxMouseEventHandler(xList::OnEndDrag)
                      );
        }
   };

void DnDxList::EndDrag () // disconnect all
   {for (std::vector<xList*>::const_iterator i = list.begin(); i != list.end(); i++)
        {(*i)->Disconnect(wxEVT_MOTION,
                          wxMouseEventHandler(xList::OnMoveDrag)
                         );
         (*i)->Disconnect(wxEVT_LEFT_UP,
                          wxMouseEventHandler(xList::OnEndDrag)
                         );
        }
   }




xList::xList (DnDxList& dnd,
              wxWindow *parent,
              wxWindowID winid,
              const wxPoint& pos,
              const wxSize& size,
              long style,
              const wxValidator &validator,
              const wxString &name
             ): wxListCtrl (parent, winid, pos, size, style, validator, name),
                dndsource (dnd)
   {Connect(wxEVT_COMMAND_LIST_BEGIN_DRAG,
            (wxObjectEventFunction)&xList::OnBeginDrag
           );
    dndsource.AddList (this);
   };


void xList::OnBeginDrag(wxListEvent& event) // begin drag
   {SetCursor(wxCursor(wxCURSOR_HAND));
    dndsource.BeginDrag();
   }

void xList::OnMoveDrag(wxMouseEvent& event) 
   {std::cout << "Movie: " << this << std::endl;  // to show the object for which the move event is called for
   }

void xList::OnEndDrag(wxMouseEvent& event) 
   {std::cout << "End: " << this << std::endl;
    dndsource.EndDrag();
    SetCursor(wxCursor(*wxSTANDARD_CURSOR));
   }


class xFrame: public wxFrame
   {
    public:
        xFrame (const wxString& title,
                const wxPoint& pos,
                const wxSize& size
               );
        ~xFrame () { }
    private:

        void OnExit(wxCommandEvent& event);
        DECLARE_EVENT_TABLE();

        DnDxList* dndxlist;
        xList* lp;
        xList* rp;
        wxPanel* panel;
   };

BEGIN_EVENT_TABLE(xFrame, wxFrame)
    EVT_MENU(wxID_EXIT, xFrame::OnExit)
END_EVENT_TABLE()


xFrame::xFrame(const wxString& title,
               const wxPoint& pos,
               const wxSize& size
              ): wxFrame(NULL, wxID_ANY, title, pos, size)
  {
   panel = new wxPanel(this);
   wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);

   // create common DnDxList
   dndxlist = new DnDxList(); 
   // create two panels
   lp = new xList (*dndxlist,
                   panel,
                   wxID_ANY,
                   wxDefaultPosition,
                   wxDefaultSize,
                   wxLC_REPORT | wxLC_SINGLE_SEL
                  );
   rp = new xList (*dndxlist,
                   panel,
                   wxID_ANY,
                   wxDefaultPosition,
                   wxDefaultSize,
                   wxLC_REPORT | wxLC_SINGLE_SEL
                  );

   // some contents
   lp->InsertColumn(0, _("A"));
   lp->InsertColumn(1, _("B"));
   lp->InsertColumn(2, _("C"));
   lp->InsertColumn(3, _("D"));

   lp->SetColumnWidth(0, 100);
   lp->SetColumnWidth(1, 100);
   lp->SetColumnWidth(2, 100);
   lp->SetColumnWidth(3, 100);


   for (long i = 0; i < 100; i++)
      {lp->InsertItem(i, 1);
       for (int j = 0; j < 4; j++)
          {wxString s;
           s << _("lp [") << i << _(", ") << j << _("]");
           lp->SetItem (i, j, s);
          }
      }

   rp->InsertColumn(0, _("A"));
   rp->InsertColumn(1, _("B"));
   rp->InsertColumn(2, _("C"));
   rp->InsertColumn(3, _("D"));

   rp->SetColumnWidth(0, 100);
   rp->SetColumnWidth(1, 100);
   rp->SetColumnWidth(2, 100);
   rp->SetColumnWidth(3, 100);


   for (long i = 0; i < 100; i++)
      {rp->InsertItem(i, 1);
       for (int j = 0; j < 4; j++)
          {wxString s;
           s << _("rp [") << i << _(", ") << j << _("]");
           rp->SetItem (i, j, s);
          }
      }

   sizer->Add(lp,1, wxEXPAND | wxALL, 10);
   sizer->Add(rp,1, wxEXPAND | wxALL, 10);
   panel->SetSizer(sizer);


  }

void xFrame::OnExit(wxCommandEvent& event)
  {
   Close( true );
  }


class xApp: public wxApp
   {
    public:
       virtual bool OnInit();
   };

IMPLEMENT_APP(xApp);


bool xApp::OnInit()
   {
    xFrame *frame = new xFrame(_("Frame"), wxPoint(50, 50), wxSize(450, 340) );
    frame->Show(true);
    return true;
   }