Getting Windows IME inputs in a QVulkanWindow object
-
wrote on 15 Jul 2024, 11:37 last edited by idontknowhowtouseQt
Hey!
I'm trying to make a Qt app with a graphical context (QVulkanWindowRenderer) within which I have imgui widgets. Got things to work as I want expect for one thing. When I change language in the Windows task bar to one that uses the Windows IME, I'm getting strange behaviour. The language itself does not switch from English to Korean in the Windows taskbar, consequently, when I type in an imgui text box within the QVulkanWindow|Renderer, only English appears. I use an event filter to detect key presses and map them to imgui key press functions.
After some experiments and digging, I've discovered that if I use an override in the QWidget class, void inputMethodEvent(QInputMethodEvent* event), I can get the language to switch to Korean in the Windows task bar if I have the QWidget in focus and get the characters as well, sadly, the QVulkanWindowRenderer class does not have such an override.class MyVulkanRenderer : public QObject, public QVulkanWindowRenderer { public: MyVulkanRenderer(QVulkanWindow* w) : m_window(w) { m_window->installEventFilter(this); } }
In the overridden eventFilter function I have code like this that picks up input events and maps it to imgui context.
case QEvent::KeyPress: case QEvent::KeyRelease: { const bool down = event->type() == QEvent::KeyPress; QKeyEvent* ke = static_cast<QKeyEvent*>(event); if (down) { key_text.append(ke->text()); if (!key_text.isEmpty()) { for (const QChar& c : key_text) { ImWchar u = c.unicode(); if (u) io.AddInputCharacter(u); } key_text.clear(); } } io.AddKeyEvent(qtKeyToImguiKey(Qt::Key(ke->key())), down);
To any veterans out there, is there anyway to get IME inputs in the QVulkanWindowRenderer class?
Any help or tips are much appreciated.
Thanks! -
Lifetime Qt Championwrote on 15 Jul 2024, 11:45 last edited by Christian Ehrlicher
Simply catching the inputmethod event in your event filter should work.
-
Simply catching the inputmethod event in your event filter should work.
wrote on 15 Jul 2024, 13:57 last edited by idontknowhowtouseQt@Christian-Ehrlicher said in Getting Windows IME inputs in a QVulkanWindow object:
Simply catching the inputmethod event in your event filter should work.
Hey thanks for responding, however, I already tried that and it doesn't seem like that event is ever getting passed. Like I described in the description, if the focus is on the renderer, clicking on the Korean button in the Windows task bar is not changing it. Normally when the language is changed, the symbol on the button in the taskbar changes to a Korean symbol, this happens if the focus is on a normal QWidget or QLineEdit object, just not on the renderer.
bool eventFilter(QObject* watched, QEvent* event) override { //QGuiApplication::focusWindow(); //std::cout << "event filter running: "<< event->type() << std::endl; ImGuiIO& io = ImGui::GetIO(); switch (event->type()) { case QEvent::InputMethod: std::cout << "input method changed" << std::endl; break; case QEvent::InputMethodQuery: std::cout << "input method queried:" <<std::endl; //event->accept(); break; case QEvent::FocusIn: { std::cout << "focus in renderer" << std::endl; io.AddFocusEvent(true); } break; case QEvent::FocusOut: { std::cout << "focus out" << std::endl; // If the renderer loses focus then we want to clear any pressed keys io.ClearInputKeys(); } break; case QEvent::MouseButtonPress: { QMouseEvent* me = static_cast<QMouseEvent*>(event); // Get the pressed mouse buttons Qt::MouseButtons mouse_buttons_down = me->buttons();
I do get the "input method queried: " in console everytime the focus is changed to the renderer though, not sure how to use this.
-
wrote on 16 Jul 2024, 04:57 last edited by Marcus Tillmanns
Instead of eventFiltering:
class MyWindow : public QVulkanWindow { public: QVulkanWindowRenderer *createRenderer() override { m_renderer = new MyVulkanRenderer(this); return m_renderer; } // ... void inputMethodEvent(...) override { if(!m_renderer) return; m_renderer->ime(...); } // keyPressEvent, keyReleaseEvent etc ... }; MyVulkanWindow w(); w..... w.showMaximized();
-
Instead of eventFiltering:
class MyWindow : public QVulkanWindow { public: QVulkanWindowRenderer *createRenderer() override { m_renderer = new MyVulkanRenderer(this); return m_renderer; } // ... void inputMethodEvent(...) override { if(!m_renderer) return; m_renderer->ime(...); } // keyPressEvent, keyReleaseEvent etc ... }; MyVulkanWindow w(); w..... w.showMaximized();
@Marcus-Tillmanns apart from the fact that QVulkanWindow has no such virtual function as it does not derive from QWidget.
-
@Marcus-Tillmanns apart from the fact that QVulkanWindow has no such virtual function as it does not derive from QWidget.
wrote on 16 Jul 2024, 08:15 last edited byUps, missed that.
1/6