当光标不在QSpinBox上时,使其对鼠标滚轮事件作出反应
Make QSpinBox react to mouse wheel events when cursor is not over it
我在Windows 7
上使用Qt 5.3.2
和Qt Creator 3.2.1
以及MinGW 4.8.2
。我有一个QSpinBox
,只有当鼠标位于QSpinBox
上方时,才能使用鼠标滚轮更改其值。如果鼠标没有在QSpinBox
上,即使QSpinBox
仍然有焦点,滚动鼠标滚轮也没有效果。即使鼠标没有悬停在QSpinBox
上,我也需要做些什么才能更改它的值?将mouseTracking
设置为true
并没有这种效果。
使用eventFilter
执行此操作。将其安装在mainWindow
:上
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
if (obj == this && event->type() == QEvent::Wheel)
{
QWheelEvent *wheelEvent = static_cast<QWheelEvent *>(event);
if(wheelEvent->delta() > 0)
ui->spinBox->setValue(ui->spinBox->value() + 1);
else
ui->spinBox->setValue(ui->spinBox->value() - 1);
}
}
这只是一个例子,所以你可以随心所欲地改进它。
或者使用这个:
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
if (obj == this && event->type() == QEvent::Wheel)
{
QApplication::sendEvent(ui->spinBox,event);
}
}
在本例中,当检测到轮子事件时,将其发送到旋转框。
但别忘了
protected:
bool eventFilter(QObject *obj, QEvent *event);//in header
和
qApp->installEventFilter(this);//in constructor
按照DmitrySazonov
的建议。当spinBox聚焦时,我们将检测wheelEvents,当spinBox失去焦点时,我们不会对wheel做出反应(其他小部件反应正常)。我们在一个eventFilter中完成此操作。为此,请提供新的bool变量。例如:
private:
bool spin;//in header
在构造函数中初始化它:
spin = false;
你的eventFilter应该是.
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
if(obj == ui->spinBox && event->type() == QEvent::FocusIn)
spin = true;
if(spin)
{
if (obj == this && event->type() == QEvent::Wheel)
{
QApplication::sendEvent(ui->spinBox,event);
}
}
if(obj == ui->spinBox && event->type() == QEvent::FocusOut)
spin = false;
}
或者只这样做,不需要额外的变量:
if (obj == this && event->type() == QEvent::Wheel)
{
if(ui->spinBox->hasFocus())
QApplication::sendEvent(ui->spinBox,event);
}
我在问题中没有提到它,但我有不止一个QSpinBox
,测试它们似乎都是次优的,所以我需要一个通用的消息转发器。根据切尔诺贝利的代码,我制作了自己版本的消息过滤器:
bool MainWindow::eventFilter(QObject *obj, QEvent *event){
if (obj == this && event->type() == QEvent::Wheel)
{
auto focusWidget = QApplication::focusWidget();
if (focusWidget){
qApp->removeEventFilter(this);
QApplication::sendEvent(focusWidget, event);
qApp->installEventFilter(this);
return true;
}
}
return false;
}
这将所有QWheelEvent
转发到具有焦点的QWidget
。还可以添加其他需要转发的事件。
事件过滤器内的qApp->removeEventFilter
和qApp->installEventFilter
是我发现的唯一方法,可以防止事件过滤器在主窗口上滚动时调用自己,导致堆栈溢出(条件focusWidget != this
没有帮助)。可能有一种方法可以防止无限递归,而无需在每个QWheelEvent
上重新安装事件过滤器。
- 跟踪滚动条上的鼠标事件
- Qt-如何在Qt3DWindow上获取鼠标事件
- Qt:如何防止为平板电脑事件生成鼠标事件
- 如何使用 c++ mfc 在屏幕上获取鼠标事件
- WM_PAINT和鼠标事件.MFC/WIN32 API.
- 通过鼠标事件传递数据
- 鼠标区域窃取QQuickItem的鼠标事件
- Windows Console API鼠标事件只是进入选择模式
- 无法跟踪鼠标事件 OpenCV
- Qt. 忽略小部件中的任何鼠标事件,而不是另一个小部件
- WXWIDGETS将鼠标事件连接到WXPAINTDC上的形状对象以删除
- Qt/Qml - 触发 QApplication/QQmlApplicationEngine 事件(键和鼠标事件)
- Juce 鼠标事件不起作用
- 是否可以捕获全局鼠标事件
- 单击QCHART图的轴时捕获鼠标事件
- OpenCV 鼠标事件始终在鼠标滚动时接收事件 10 和 *flag* 0
- 鼠标事件选取器打开场景图
- 将鼠标事件发送到虚拟现实OpenGL场景中的QtQuick窗口
- 处理鼠标事件SFML
- 是否可以在 wxFrame 中捕获鼠标事件