如何在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
相关产品推荐
相关产品推荐

