在 KeyPress 中拦截“Q”和公司

Posted

技术标签:

【中文标题】在 KeyPress 中拦截“Q”和公司【英文标题】:Intercept "Q" and company in KeyPress 【发布时间】:2022-01-15 04:01:36 【问题描述】:

我正在尝试找到一种方法来拦截所有键,但显然所有默认命令仍然存在,并且运行正常。我从锥形示例开始,并尝试了 vtkCallbackCommandSetInteractorStyle,如示例中所建议的:

#include <vtkActor.h>
#include <vtkCamera.h>
#include <vtkCylinderSource.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkCallbackCommand.h>
#include <vtkCommand.h>

#include <array>

class KeyPressInteractorStyle : public vtkInteractorStyleTrackballCamera

public:
    static KeyPressInteractorStyle* New();
    vtkTypeMacro(KeyPressInteractorStyle, vtkInteractorStyleTrackballCamera);
    
    virtual void OnKeyPress() override
    
        vtkRenderWindowInteractor* rwi = this->Interactor;
        std::string key = rwi->GetKeySym();

        std::cout << "Pressed " << key << std::endl;
        
        if (key == "Up")
        
            std::cout << "The up arrow was pressed." << std::endl;
        
        
        // Handle a "normal" key
        if (key == "q" || key == "Q")
        
            std::cout << "The q key was pressed." << std::endl;
            return;
        
        
        // DO NOT Forward events
        //vtkInteractorStyleTrackballCamera::OnKeyPress();
    
;
vtkStandardNewMacro(KeyPressInteractorStyle);

void KeypressCallbackFunction(vtkObject* caller, long unsigned int eventId,
                              void* clientData, void* callData)

    std::cout << "Keypress callback" << std::endl;
    
    vtkRenderWindowInteractor* iren = static_cast<vtkRenderWindowInteractor*>(caller);
    
    std::cout << "Pressed: " << iren->GetKeySym() << std::endl;


int main(int, char*[])

    vtkNew<vtkNamedColors> colors;

    std::array<unsigned char, 4> bkg26, 51, 102, 255;
    colors->SetColor("BkgColor", bkg.data());

    vtkNew<vtkCylinderSource> cylinder;
    cylinder->SetResolution(8);

    vtkNew<vtkPolyDataMapper> cylinderMapper;
    cylinderMapper->SetInputConnection(cylinder->GetOutputPort());

    vtkNew<vtkActor> cylinderActor;
    cylinderActor->SetMapper(cylinderMapper);
    cylinderActor->GetProperty()->SetColor(colors->GetColor4d("Tomato").GetData());
    cylinderActor->RotateX(30.0);
    cylinderActor->RotateY(-45.0);

    vtkNew<vtkRenderer> renderer;
    renderer->AddActor(cylinderActor);
    renderer->SetBackground(colors->GetColor3d("BkgColor").GetData());
    // Zoom in a little by accessing the camera and invoking its "Zoom" method.
    renderer->ResetCamera();
    renderer->GetActiveCamera()->Zoom(1.5);

    vtkNew<vtkRenderWindow> renderWindow;
    renderWindow->SetSize(800, 800);
    renderWindow->AddRenderer(renderer);
    renderWindow->SetWindowName("Cylinder");

    vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
    renderWindowInteractor->SetRenderWindow(renderWindow);
    
    // VIA STYLE
//    vtkNew<KeyPressInteractorStyle> style;
//    renderWindowInteractor->SetInteractorStyle(style);
//    style->SetCurrentRenderer(renderer);
    
    // VIA CALLBACK
    vtkNew<vtkCallbackCommand> keypressCallback;
    keypressCallback->SetCallback(KeypressCallbackFunction);
    renderWindowInteractor->AddObserver(vtkCommand::KeyPressEvent, keypressCallback);
    
    renderWindow->Render();
    renderWindowInteractor->Start();

    return EXIT_SUCCESS;

在这两种情况下,“Q”仍然退出,“W”仍然进入线框。

有没有办法正确处理所有关键事件,即使是默认事件?

【问题讨论】:

【参考方案1】:

对于那些快捷方式(即字母),还有一个发送的CharEvent,链接到实现quitwireframevtkInteractorStyle::OnChar 方法。

所以要么以你的风格覆盖它(除了OnKeyPress),要么用观察者机制处理事件。

【讨论】:

以上是关于在 KeyPress 中拦截“Q”和公司的主要内容,如果未能解决你的问题,请参考以下文章

拦截 Tab 按键以手动管理焦点切换

在 angularjs 拦截器中停止请求

angularjs之手机输入法回车变搜索,并触发事件,兼容pc回车事件

KeyPress 和KeyDown KeyPress之间的区别

KeyPress 和KeyDown KeyPress之间的区别

如何在 C# 中使用 KeyPress 事件按下 Alt 时显示消息?