- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我目前正在尝试在 QML 中实现一个拖动创建机制,但是我遇到了一个问题,我需要新创建的 MouseArea
来成为鼠标事件的目标,即使原始 MouseArea
还没有鼠标按钮释放事件。
Window {
id: window
width: 300
height: 300
Rectangle {
id: base
width: 20
height: 20
color: "red"
MouseArea {
anchors.fill: parent
property var lastPoint
property var draggedObj: null
function vecLength( vec ) {
return Math.abs( Math.sqrt( Math.pow( vec.x, 2 ) +
Math.pow( vec.y, 2 ) ) );
}
onPressed: lastPoint = Qt.point( mouse.x, mouse.y )
onPositionChanged: {
if ( !draggedObj ) {
var diff = Qt.point( mouse.x - lastPoint.x,
mouse.y - lastPoint.y );
if ( vecLength( diff ) > 4 ) {
draggedObj = dragObj.createObject( window );
}
}
mouse.accepted = !draggedObj;
}
}
}
Component {
id: dragObj
Rectangle {
width: 20
height: 20
color: "blue"
Drag.active: dragArea.drag.active
Drag.hotSpot.x: 10
Drag.hotSpot.y: 10
MouseArea {
id: dragArea
anchors.fill: parent
drag.target: parent
}
}
}
}
如果您运行此代码并进行尝试,您将看到在红色 Rectangle
中拖动会导致创建可拖动的蓝色 Rectangle
,但它不会跟随鼠标,因为红色 MouseArea
仍在接收鼠标事件,尽管蓝色 MouseArea
位于其上方。
有什么方法可以强制蓝色的 MouseArea
接收鼠标事件吗?
最佳答案
我以前遇到过这种情况,并在我的阁楼上开始了解决方案。
这里的技巧是调用 QQuickItem::grabMouse()
并向新创建的对象发送鼠标按下事件。不幸的是,我认为这只能通过 C++ 完成。
然后我创建了一个辅助类来向 qml 公开此功能:
鼠标抓取器.h
#ifndef MOUSEGRABBER
#define MOUSEGRABBER
#include <QObject>
#include <QQuickItem>
#include <QGuiApplication>
#include <QMouseEvent>
class MouseGrabber : public QObject
{
Q_OBJECT
Q_PROPERTY(QQuickItem* target READ target WRITE setTarget NOTIFY targetChanged)
Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged)
public:
explicit MouseGrabber(QObject *parent = 0) : QObject(parent), m_target(nullptr), m_active(true) { }
QQuickItem* target() const { return m_target; }
bool active() const { return m_active;}
signals:
void targetChanged();
void activeChanged();
public slots:
void setTarget(QQuickItem* target)
{
if (m_target == target)
return;
ungrabMouse(m_target);
if (m_active)
grabMouse(target);
m_target = target;
emit targetChanged();
}
void setActive(bool arg)
{
if (m_active == arg)
return;
m_active = arg;
if (m_active)
grabMouse(m_target);
else
ungrabMouse(m_target);
emit activeChanged();
}
private:
static void grabMouse(QQuickItem* target)
{
if (target)
{
target->grabMouse();
QMouseEvent event(QEvent::MouseButtonPress, QPointF(), Qt::LeftButton, QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
QGuiApplication::sendEvent(target, &event);
}
}
static void ungrabMouse(QQuickItem* target)
{
if (target)
target->ungrabMouse();
}
QQuickItem* m_target;
bool m_active;
};
#endif // MOUSEGRABBER
通过直接调用插槽而不是操纵属性可以使这更方便,但这就是我的库存。例如一个名为 grabMouseUntilRelease(QQuickItem* item)
的插槽,它为该项目抓取鼠标,使用 installEventFilter
监听鼠标释放事件并自动取消抓取。
注册该类,以便它可以在代码中的某处使用 qmlRegisterType
在 QML 中实例化:
qmlRegisterType<MouseGrabber>("com.mycompany.qmlcomponents", 1, 0, "MouseGrabber");
之后,您可以在 QML 中实例化 MouseGrabber 并通过修改其属性(target
和 active
)来使用它:
import com.mycompany.qmlcomponents 1.0
Window {
id: window
width: 300
height: 300
Rectangle {
id: base
width: 20
height: 20
color: "red"
MouseArea {
anchors.fill: parent
property var lastPoint
property var draggedObj: null
function vecLength( vec ) {
return Math.abs( Math.sqrt( Math.pow( vec.x, 2 ) +
Math.pow( vec.y, 2 ) ) );
}
onPressed: lastPoint = Qt.point( mouse.x, mouse.y )
onPositionChanged: {
if ( !draggedObj ) {
var diff = Qt.point( mouse.x - lastPoint.x,
mouse.y - lastPoint.y );
if ( vecLength( diff ) > 4 ) {
draggedObj = dragObj.createObject( window );
grabber.target = draggedObj.dragArea; // grab the mouse
}
}
mouse.accepted = !draggedObj;
}
}
}
MouseGrabber {
id: grabber
}
Component {
id: dragObj
Rectangle {
property alias dragArea: dragArea
width: 20
height: 20
color: "blue"
Drag.active: dragArea.drag.active
Drag.hotSpot.x: 10
Drag.hotSpot.y: 10
MouseArea {
id: dragArea
anchors.fill: parent
drag.target: parent
onReleased: {
if (grabber.target === this)
grabber.target = null; // ungrab the mouse
}
}
}
}
}
关于qt - QML:来自动态鼠标区域的 'Steal' 事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29777230/
我试图理解 fork 连接的窃取部分。一个 fork join pool 有工作线程和它自己的 Deque。如果工作线程自己的双端队列为空,则工作线程会从另一个工作线程窃取。 一个线程如何访问其他线程
问题: 我有一个 WebBrowser 并公开了它的 ActiveX 方法。在我的 WebBrowser 所在的表单中,我有一个带有快捷方式的 MainMenuStrip。只有当我在我的表单上的文本框
我一直在研究我正在实现的线程池的不同调度算法。由于我要解决的问题的性质,我可以假设并行运行的任务是独立的,不会产生任何新任务。任务可以有不同的大小。 我立即转向使用本地作业队列的无锁双端队列的最流行的
令我惊讶的是,为类似函数的宏提供带有两个模板参数的类型会导致编译器报错。 这个(概念上相似的)示例代码: template struct foo{}; template struct bar{}
我想做这样的事情: Button btn1 = new Button(); btn1.Click += new EventHandler(btn1_Click); Button btn2 = new
我目前正在尝试在 QML 中实现一个拖动创建机制,但是我遇到了一个问题,我需要新创建的 MouseArea 来成为鼠标事件的目标,即使原始 MouseArea 还没有鼠标按钮释放事件。 Window
例如,工作窃取可在 Java 平台上的 Fork/Join 框架中使用。 (参见 How is the fork/join framework better than a thread pool? )
假设我有一个在加载 DOM 后动态创建的按钮,它是框架代码的一部分,所以我无法更改它,也无法直接访问该代码。 这个按钮有一个带有内部状态的点击事件,我想稍后制作另一个按钮来触发相同的功能。 如果我将与
我试图在非透明 HTML 之上绘制覆盖 Canvas ,但 Canvas “窃取”了上下文菜单。 是否可以通过某种方式忽略 Canvas 的上下文菜单? 制作了一个显示问题的 jsfiddle:htt
我在 TabControl 中有几个多行文本框。 tabcontrol 有一个滚动条,但是一旦多行文本框获得焦点,滚动就会滚动文本框而不是 tabcontrol。有什么方法可以阻止文本框接收事件并更像
我想计算两天之间的日期差异。问题是当我计算天数时,计算中缺少一天(当天)。 假设 date1 是 20-12-2014,date2 是 21-12-2014。DateTime::Diff 使用这两个日
在我的应用中,用户购买存储在 Core Data 中的消耗品,比方说手提箱。当用户首次安装该应用程序时,我会赠送他们一份免费赠品让他们开始使用。如果不设置至少一个手提箱,该应用程序将无法运行。 但是如
为什么我可以找到很多关于“工作窃取”的信息而没有关于“工作耸肩”作为动态负载平衡策略的信息? 通过“工作耸肩”,我的意思是将多余的工作从繁忙的处理器转移到负载较低的邻居上,而不是让空闲的处理器从忙碌的
当光标位于例如在编辑字段中,按下并释放 Alt 键(不按任何其他键)会导致编辑字段失去焦点。对于任何其他集中控制也会发生这种情况。对于任何集中控制,如何在 Delphi 程序中防止这种情况发生? 最佳
当我启动 Chrome 时,新窗口显示为未聚焦并位于其他窗口后面。所以我决定创建一个解决方法;我将使用磁盘中的一个文件更改我的主页 url,其中一个文件包含用于窃取焦点的 javascript,然后重
我有一个自动完成表,当用户在搜索栏按钮项中键入任何内容时,我会为它创建框架。问题是,我希望能够在用户触摸 TableView 外部或表时关闭 TableView ,因此我很自然地在主视图中添加了点击触
From java docs, A ForkJoinPool differs from other kinds of ExecutorService mainly by virtue of emplo
我正在使用 Visual Studio 2015 作为 IDE 开发 gcc 应用程序。调试器是 gdb。 应用程序创建它自己的窗口。当我使用 DEBUG 开关进行编译时,我还需要应用程序生成一个控制
大家! 我编写了一个扩展Thread的类(InAndOut)。该类在构造函数中接收两个 LinkedConcurrentQueue、entrance 和 exit,并且我的 run 方法从 入口到导出
我正在制作一个程序,其中包含一个带有 ChromiumWebBrowser 的表单。导航是自动完成的。当 webbrowser 完成它的任务时,我将处理它,创建一个新的 webbrowser,将它添加
我是一名优秀的程序员,十分优秀!