Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在鼠标下强制Qt更新小部件?_C++_Qt - Fatal编程技术网

C++ 如何在鼠标下强制Qt更新小部件?

C++ 如何在鼠标下强制Qt更新小部件?,c++,qt,C++,Qt,具体来说,在Windows7上,我认为这并不重要 我们都在无数的桌面应用程序中看到过这个问题,尤其是那些不使用操作系统提供的控件的游戏:当屏幕在不动的鼠标光标下以编程方式改变时(与用户将光标移动到新的小部件相反),它们就不同步了。光标没有改变,或者小部件没有按应有的方式绘制,光标在小部件内部-很明显,小部件的鼠标输入事件没有触发。如果你在不离开小部件的情况下轻轻摇动鼠标,小部件就会自行修复 不幸的是,Qt5.7也有这个普遍存在的问题。首先想到的解决方案是通过编程将鼠标移动到(0,0),然后通过W

具体来说,在Windows7上,我认为这并不重要

我们都在无数的桌面应用程序中看到过这个问题,尤其是那些不使用操作系统提供的控件的游戏:当屏幕在不动的鼠标光标下以编程方式改变时(与用户将光标移动到新的小部件相反),它们就不同步了。光标没有改变,或者小部件没有按应有的方式绘制,光标在小部件内部-很明显,小部件的
鼠标输入
事件没有触发。如果你在不离开小部件的情况下轻轻摇动鼠标,小部件就会自行修复


不幸的是,Qt5.7也有这个普遍存在的问题。首先想到的解决方案是通过编程将鼠标移动到
(0,0)
,然后通过Windows方式返回。然而,它不是跨平台(ish)。有更好的主意吗?

我不知道你的问题是否仍然是真实的

您可以使用以下代码覆盖鼠标下的方法
underMouse()

bool MyWidget::underMouse()
{
    return rect().contains(mapFromGlobal(QCursor::pos()));
}
拆分器调整面板大小时,肯定会触发rest面板中的事件
moveEvent
resizeEvent
。您只需检查小部件是否在鼠标下,然后手动调用
enterEvent()

我找到了两种解决方案

第一个是简单的破解:调用
widget->hide()
,然后立即调用
widget->show()
。这将重新评估和更新小部件的视觉状态,这取决于它是否在鼠标光标下,即使光标没有移动。但我不推荐这种解决方案,因为它可能会有一些不必要的副作用。虽然我还没有遇到过

第二种解决方案更好,因为它看起来不像黑客,而且可能没有任何副作用:

widget->setAttribute(Qt::WA_UnderCursor, qApp->widgetAt(QCursor::pos()) == widget);
widget->update();

假定该代码是从小部件的父级调用的。但是你可以调整它,从任何其他地方调用它。注意:使用
QApplication::widgetAt()
比使用
widget->rect().contains()
更好,这是在另一个答案中建议的,因为在后一种情况下,我们会得到被其他小部件覆盖的小部件的误报

实际上很复杂的是,在代码中找到一个地方,从那里你可以调用它。因为小部件的运动可能有很多来源——与父部件一起移动、父部件的移动、调整大小、父部件的大小、滚动等。这可能就是为什么在标准Qt小部件库中实现这一点太复杂的原因。在某些情况下,它可能是性能杀手。(我猜)

只是为了展示我的用法:我正在移动一个包含许多子小部件的整个容器小部件。随后,移动容器后,其中一个子窗口小部件可能会进入光标下。因此,我呼吁:

containerWidget->move(dx, dy); // this moves the container
for (QWidget *child : containerWidget->findChildren<QWidget*>())
{
    child->setAttribute(Qt::WA_UnderMouse, qApp->widgetAt(QCursor::pos()) == child);
    child->update();
}
containerWidget->move(dx,dy);//这会移动容器
对于(QWidget*child:containerWidget->findChildren())
{
child->setAttribute(Qt::WA_鼠标下,qApp->widgetAt(QCursor::pos())==child);
子->更新();
}

屏幕以编程方式更改到底是什么意思?Qt中的问题在哪里?@Kamajii我从
qspliter
继承了一个拆分器,其中包含一系列从
QPanel
继承的面板。每个面板都有一个关闭按钮。当用户单击此按钮时,面板将关闭,拆分器将调整其他面板的大小,以便新面板占用其空间。但是,对于现在位于鼠标光标下的新面板,不会调用
enterEvent()
,并且面板绘制错误。摇动鼠标有帮助。在鼠标下的小部件上调用
QWidget::update
可以解决您的问题吗?@m7913d是我尝试的第一件事。它不是。您能在尽可能小的代码示例中复制并添加它吗?准确地说,您不能重写此方法,因为它不是虚拟的。使用
QApplication::widgetAt()
比使用
widget->rect().contains()更好,因为在后一种情况下,我们会得到由其他小部件覆盖的小部件的误报