Qt/Qml应用中触发键鼠事件及QTimer待机功能实现咨询
Absolutely! Both triggering input events (keyboard and mouse included) and building a standby system with QTimer are totally doable in Qt/QML apps—let’s walk through how to pull this off, with practical examples for both C++ and QML workflows.
You’ve got two main approaches here, depending on whether you’re working in Qt C++ or directly in QML.
Qt C++ Approach
For low-level control, you can create QMouseEvent/QKeyEvent instances and post them to your target widgets using QCoreApplication::postEvent(). This works across the entire app, even for widgets that aren’t QML-based.
Simulate a Mouse Click
// Simulate a full left-click on a target widget QPoint clickPos = targetWidget->mapFromGlobal(QCursor::pos()); // Use widget-local position // Send MouseButtonPress event QMouseEvent* pressEvent = new QMouseEvent( QEvent::MouseButtonPress, clickPos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier ); QCoreApplication::postEvent(targetWidget, pressEvent); // Send MouseButtonRelease to complete the click QMouseEvent* releaseEvent = new QMouseEvent( QEvent::MouseButtonRelease, clickPos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier ); QCoreApplication::postEvent(targetWidget, releaseEvent);
Simulate a Keyboard Press
// Simulate pressing and releasing the 'A' key on the focused widget QKeyEvent* keyPress = new QKeyEvent( QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, QString("A") ); QCoreApplication::postEvent(qApp->focusWidget(), keyPress); // Don't forget the release event! QKeyEvent* keyRelease = new QKeyEvent( QEvent::KeyRelease, Qt::Key_A, Qt::NoModifier, QString("A") ); QCoreApplication::postEvent(qApp->focusWidget(), keyRelease);
QML Approach
If you’re working entirely within QML, you can either use built-in component methods or create custom events.
Simulate Mouse Interaction
Most interactive QML components (like MouseArea) expose methods to manually trigger events:
MouseArea { id: interactiveArea onClicked: console.log("User clicked (or simulated click!)") // Custom function to simulate a full click function simulateClick() { press() // Trigger press state release() // Trigger release to fire onClicked } } // Trigger the simulated click from a button Button { text: "Simulate Click" onClicked: interactiveArea.simulateClick() }
Simulate Keyboard Events
For keyboard input, you can create KeyEvent objects and send them to focused items:
Item { id: keyReceiver focus: true Keys.onPressed: console.log("Key pressed:", Qt.Key(event.key)) function simulateKeyPress(keyCode) { // Create a KeyEvent instance let keyEvent = Qt.createQmlObject('import QtQuick 2.0; KeyEvent {}', this) // Trigger press event keyEvent.key = keyCode keyEvent.type = KeyEvent.Pressed sendEvent(keyEvent) // Trigger release event keyEvent.type = KeyEvent.Released sendEvent(keyEvent) } } // Example: Simulate pressing the Enter key Button { text: "Press Enter" onClicked: keyReceiver.simulateKeyPress(Qt.Key_Return) }
This is straightforward—set up a timer that triggers your standby logic, and reset it every time a user event (mouse/keyboard) is detected.
Qt C++ Implementation
Use an event filter to catch all app-wide input events and reset the timer:
#include <QApplication> #include <QTimer> #include <QEvent> class StandbyController : public QObject { Q_OBJECT public: StandbyController(QObject* parent = nullptr) : QObject(parent) { // Initialize timer (30-second timeout for example) standbyTimer = new QTimer(this); standbyTimer->setInterval(30000); standbyTimer->setSingleShot(true); connect(standbyTimer, &QTimer::timeout, this, &StandbyController::onStandbyTriggered); // Install event filter to monitor all app events qApp->installEventFilter(this); standbyTimer->start(); } bool eventFilter(QObject* obj, QEvent* event) override { // Reset timer on any mouse or keyboard activity if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseMove || event->type() == QEvent::KeyPress) { standbyTimer->start(); } return QObject::eventFilter(obj, event); } signals: void standbyActivated(); private slots: void onStandbyTriggered() { emit standbyActivated(); // Or directly execute standby logic here (e.g., hide main window) } private: QTimer* standbyTimer; }; // Usage in main() int main(int argc, char* argv[]) { QApplication app(argc, argv); StandbyController standbyCtrl; QObject::connect(&standbyCtrl, &StandbyController::standbyActivated, [](){ qDebug() << "Entering standby mode..."; // Add your standby logic here }); // Initialize and show your main window // ... return app.exec(); }
QML Implementation
Use a Timer component and listen to window-level mouse/keyboard events:
import QtQuick 2.15 import QtQuick.Window 2.15 Window { id: mainWindow width: 640 height: 480 visible: true focus: true // Ensure window captures keyboard events Timer { id: standbyTimer interval: 30000 // 30 seconds running: true singleShot: true onTriggered: enterStandby() } function enterStandby() { console.log("Entering standby mode from QML") // Add your standby logic here (e.g., switch to a standby UI, hide window) // mainWindow.visible = false; } // Reset timer on mouse activity onMousePress: standbyTimer.restart() onMouseMove: standbyTimer.restart() // Reset timer on keyboard activity Keys.onPressed: standbyTimer.restart() }
You can mix and match C++ and QML approaches depending on your app’s architecture. For example, you might handle event triggering in C++ for low-level control, while implementing the standby UI in QML.
内容的提问来源于stack exchange,提问作者daniele86

