更新:
我认为不使用操作系统库或每隔 X 毫秒获取一次鼠标位置就无法做到这一点。它看起来像是 Qt 框架没有考虑的一个非常具体的问题。您需要编写自己的类来控制它,使用 windows 的 win32、linux 的 x11 和 Mac 的等价物。
如果您想在窗口处于活动状态并且正在拖动某些东西时获取鼠标位置,请检查:
搜索了一下,我找到了一个解决方案,可以在您的窗口使用 QObject::eventFilter 获得焦点时获取它。
创建一个继承自 QObject 并覆盖 eventFilter 的类(例如 EventListener),以及使用 installEventFilter 将其设置为您的 qml 窗口(继承自 QObject)事件过滤器的方法。
eventslistener.h:
#include <QEvent>
#include <QObject>
#include <QDebug>
#include <QDropEvent>
class EventsListener : public QObject
{
Q_OBJECT
public:
EventsListener(QObject * ptr) : QObject (ptr) {
}
Q_INVOKABLE void handleEventsOf(QObject *object) {
if (object)
object->installEventFilter(this);
}
bool eventFilter(QObject *object, QEvent *event) override {
if(event->type() == QEvent::DragMove) {
QDragMoveEvent *mouseEvent = static_cast<QDragMoveEvent*>(event);
qDebug() << "Mouse position dragging (x, y): (" << mouseEvent->pos().x() << ", " << mouseEvent->pos().y() << ")";
return false; //this is must return false or drop event will be handled by this method and drag&drop won't work correctly
}
return false;
}
};
现在我们需要使用qmlRegisterSingletonType 访问该类的一个实例(在本例中为单例)。您可能希望使用qmlRegisterType 来将此事件监听器注册为一个类型(而不是单例),并使用信号直接通知 qml 鼠标位置。
main.cpp:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "eventlistener.h"
static QObject *eventsListenerInstance(QQmlEngine *qmlEngine, QJSEngine *engine)
{
return new EventsListener(engine);
}
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
qmlRegisterSingletonType<EventsListener>("AppEventListener", 1, 0, "EventsListener", eventsListenerInstance);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
main.qml:
import ...
import AppEventListener 1.0
ApplicationWindow {
visible: true
width: 640
height: 480
id: item
property string display
property alias dropEnabled: acceptDropCB.checked
color: dropArea.containsDrag ? "#CFC" : "#EEE"
Component.onCompleted: EventsListener.handleEventsOf(item)
...
}