You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Mac上使wxUIActionSimulator正常工作?

wxUIActionSimulator在macOS上无法触发wxEVT_ENTER_WINDOW事件的问题及替代方案咨询

问题场景

在macOS Sequoia v15.6(M3芯片)、wxWidgets 3.3.2环境下,编写测试代码验证wxUIActionSimulator模拟鼠标移动是否能触发主框架的wxEVT_ENTER_WINDOW事件,结果发现程序输出仅由真实鼠标位置决定:若真实鼠标及时移出窗口输出0,否则输出1,模拟器操作完全无效。

核心测试代码(App::OnRun())

int App::OnRun()
{
    App& app = wxGetApp();

    while (!app.m_painted) wxYield();
    
    wxUIActionSimulator uiSim;
    uiSim.MouseMove(app.getFrameScreenPos() + wxPoint(50, 50));
    uiSim.MouseClick();
    wxYield();

    std::cout << app.m_enteredFrame << std::endl;
    return 0;
}

主框架事件绑定逻辑

m_enteredFrame初始值为false,在主框架构造函数中绑定事件处理器,触发时将其设为true:

MainFrame::MainFrame(wxString title, wxPoint pos, wxSize size)
    : wxFrame(nullptr, wxID_ANY, title, pos, size)
{
    this->Bind(wxEVT_PAINT, &MainFrame::onPaint, this); // 触发后设置wxGetApp().m_painted为true
    this->Bind(wxEVT_ENTER_WINDOW, [](wxMouseEvent& e){
        wxGetApp().m_enteredFrame = true;
    });
}

完整程序代码

class App : public wxApp
{
public:
    bool OnInit() override;
    int OnRun() override;
    wxPoint getFrameScreenPos();
    
    wxFrame* mainFrame;
    
    bool m_painted;
    bool m_enteredFrame;
};
wxDECLARE_APP(App);

class MainFrame : public wxFrame
{
public:
    MainFrame(wxString title, wxPoint pos, wxSize size);
    void onPaint(wxPaintEvent& e);
};
wxIMPLEMENT_APP(App);

bool App::OnInit()
{
    this->m_enteredFrame = false;
    this->mainFrame = new MainFrame("Catch2 experiment", wxPoint(100, 100), wxSize(1280, 720));
    mainFrame->Show();
    return true;
}

int App::OnRun()
{
    App& app = wxGetApp();

    while (!app.m_painted) wxYield();
    
    wxUIActionSimulator uiSim;
    uiSim.MouseMove(app.getFrameScreenPos() + wxPoint(50, 50));
    uiSim.MouseClick();
    wxYield();

    std::cout << app.m_enteredFrame << std::endl;
    return 0;
}

wxPoint App::getFrameScreenPos()
{
    return this->mainFrame->GetScreenPosition();
}

MainFrame::MainFrame(wxString title, wxPoint pos, wxSize size)
    : wxFrame(nullptr, wxID_ANY, title, pos, size)
{
    this->Bind(wxEVT_PAINT, &MainFrame::onPaint, this);
    this->Bind(wxEVT_ENTER_WINDOW, [](wxMouseEvent& e){
        wxGetApp().m_enteredFrame = true;
    });
}

void MainFrame::onPaint(wxPaintEvent& e)
{
    wxGetApp().m_painted = true;
}

已尝试的解决步骤

  • 在「设置>隐私与安全性>辅助功能」中为可执行文件开启了权限
  • 使用wxWidgets源码tests/waitfor.h中的YieldForAWhile()函数等待事件处理,无效果:
void YieldForAWhile()
{
    std::chrono::time_point<std::chrono::steady_clock> t = std::chrono::steady_clock::now();
    while ((std::chrono::steady_clock::now() - t).count() < 5 * std::round(std::pow(10, 8)))
        wxYield();
}

咨询问题

已知GitHub上有旧Issue提到wxUIActionSimulator在Mac上运行不稳定,若当前问题无法通过wx自身解决,是否有可靠的替代方案?

内容的提问来源于stack exchange,提问作者tuanorn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.02 07:34:54