Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.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++ 如何在wxWidgets中转发事件?_C++_Wxwidgets - Fatal编程技术网

C++ 如何在wxWidgets中转发事件?

C++ 如何在wxWidgets中转发事件?,c++,wxwidgets,C++,Wxwidgets,我有一个带有GLCanvas和滚动条的窗口,我想让画布捕捉滚动事件并将它们转发到滚动条,然后滚动条用于定位“摄像头”。因此我完成了以下操作: MainWindow::MainWindow(wxWindow* parent,wxWindowID id) { //... GlCanvas->Connect(ID_GLCANVAS1, wxEVT_MOUSEWHEEL, (wxObjectEventFunction)&MainWindow::onMouseWheel, 0L, th

我有一个带有GLCanvas和滚动条的窗口,我想让画布捕捉滚动事件并将它们转发到滚动条,然后滚动条用于定位“摄像头”。因此我完成了以下操作:

MainWindow::MainWindow(wxWindow* parent,wxWindowID id)
{
//...
   GlCanvas->Connect(ID_GLCANVAS1, wxEVT_MOUSEWHEEL, (wxObjectEventFunction)&MainWindow::onMouseWheel, 0L, this);
}

void MainWindow::onMouseWheel(wxMouseEvent & event)
{
    if(event.GetWheelAxis() == wxMOUSE_WHEEL_VERTICAL)
    {
        std::cerr << "vertical scroll" << std::endl;
        verticalScroll->ProcessWindowEvent(event);
    }
    else
    {
        std::cerr << "horizontal scroll" << std::endl;
        horizontalScroll->ProcessWindowEvent(event);
    }
}
MainWindow::MainWindow(wxWindow*父对象,wxWindowID)
{
//...
GlCanvas->Connect(ID_GLCANVAS1,wxEVT_mouseweel,(wxObjectEventFunction)&主窗口::onmouseweel,0L,this);
}
void主窗口::onMouseWheel(wxMouseEvent和事件)
{
if(event.GetWheelAxis()==wxMOUSE_WHEEL_VERTICAL)
{
std::cerr您需要
conect()
,或者更好的
bind()
,如果您的wx版本允许的话

如果选择使用wxEVT_命令\u scrollwxEVT_scroll处理所有滚动事件,则可以从处理程序函数中的事件参数获取事件类型

更正:
目前(wx 3.1)仍然没有wxEVT_命令滚动或wxEVT_滚动。只有部分定义(翻页、thumtrack等)。这似乎是一个错误。但您可以使用旧的开始事件表/结束事件表方式使用EVT\u滚动。

您不能将wx事件转发到本机控件,如果您仔细想想,当本机控件对wx没有任何概念时,这怎么可能工作?本机控件生成本机事件,然后将其转换为wx事件我给了你的应用程序,但在另一个方向上,什么也没有发生,甚至根本做不到

在这种特殊情况下,您可以(相对)轻松地将滚动事件转换为调用
ScrollLines()
ScrollPages()
或只调用
SetScrollPos()
。这将允许您使用相同的滚动条控制另一个窗口滚动


不要忘记调用
Skip()
在原始处理程序中,让正在滚动的窗口实际上也可以滚动。

wxEVT_命令滚动和wxEVT_滚动都会得到一个
未声明的
错误。这是wx 3.0 btw,wxEVT声明中的注释清楚地说明应该使用wxEVT_滚动条,而不是wxEVT_滚动条。@PatrickJeeves,您需要跳过()事件,即添加“event.Skip()在处理程序的末尾。@igor它没有改变任何东西。这可能与KDE有关吗?@PatrickJeeves,你确实是根据GTK+编译的,对吗?是GTK+2还是3?但不是所有的wx类都能转换wxEvents并将它们转发给本机控件吗?这是另一种方式。本机控件发送事件,wx允许(例如通过
conect()
)在函数中处理它们。@Ripi2是正确的,但我已更新了答案以使其更清楚。
void MainWindow::onMouseWheel(wxMouseEvent & event)
{
    event.Skip();
    double rotation = ((double) event.GetWheelRotation()) / event.GetWheelDelta();

    wxScrollBar * scrollBar;
    double * delta;

    if(event.GetWheelAxis() == wxMOUSE_WHEEL_VERTICAL)
    {
        scrollBar = verticalScroll; 
        delta     = &verticalDelta;
        rotation *= -1;
    }
    else
    {
        scrollBar = horizontalScroll;
        delta     = &horizontalDelta;
    }

    if(event.IsPageScroll())
    {
        rotation *= scrollBar->GetPageSize();
    }
    else
    {
        if(event.GetWheelAxis() == wxMOUSE_WHEEL_VERTICAL)
        {
            rotation *= event.GetLinesPerAction();
        }
        else
        {
            rotation *= event.GetColumnsPerAction();
        }
    }

    *delta += rotation;

    int scroll = scrollBar->GetThumbPosition();
    int ds = (int) *delta;

    *delta -= ds;
    scroll += ds;

    if(scroll < 0)
    {
        *delta = 0;
        scroll = 0;
    }
    else if(scroll > scrollBar->GetRange())
    {
        *delta = 0;
        scroll = scrollBar->GetRange();
    }

    scrollBar->SetThumbPosition(scroll);
}