模拟鼠标点击 QSlider 不起作用
Simulate mouse click on QSlider does not work
我正在尝试使用
模拟鼠标在我的小部件上的点击
QCoreApplication::sendEvent();
它适用于 QPushButton 和其他一些组件。
对于 QSlider,(设计器中的水平滑块)我尝试了下面的代码,但它不起作用。
QMouseEvent mousePressEvent(QEvent::MouseButtonPress,QPoint(50, 5), Qt::LeftButton, 0, 0);
QCoreApplication::sendEvent((QObject*)ui->horizontalSlider, &mousePressEvent);
QMouseEvent mouseReleaseEvent(QEvent::MouseButtonRelease, QPoint(50, 5), Qt::LeftButton, 0, 0);
QCoreApplication::sendEvent((QObject*)ui->horizontalSlider, &mouseReleaseEvent);
但使用 QTest 时效果很好。
QTest::mouseClick(ui->horizontalSlider, Qt::LeftButton, Qt::NoModifier, QPoint(50, 5));
任何纠正相同问题的建议都会有很大帮助。提前致谢。
简短的回答如下:
// The following code should be changed
QMouseEvent mousePressEvent(QEvent::MouseButtonPress,QPoint(50, 5), Qt::LeftButton, 0, 0);
QCoreApplication::sendEvent((QObject*)ui->horizontalSlider, &mousePressEvent);
QMouseEvent mouseReleaseEvent(QEvent::MouseButtonRelease, QPoint(50, 5), Qt::LeftButton, 0, 0);
QCoreApplication::sendEvent((QObject*)ui->horizontalSlider, &mouseReleaseEvent);
// To the following one. Also, note that (QObject*) is not necessary, since QSlider is in the hierarchy with QObject, i.e. QObject is ancestor for the QSlider.
QMouseEvent mousePressEvent(QEvent::MouseButtonPress,QPoint(50, 5), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
QCoreApplication::sendEvent(ui->horizontalSlider, &mousePressEvent);
QMouseEvent mouseReleaseEvent(QEvent::MouseButtonRelease, QPoint(50, 5), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
QCoreApplication::sendEvent(ui->horizontalSlider, &mouseReleaseEvent);
这将是简短的回答。任何想要推断需要使用哪些事件来模拟 Qt 元素上的某种行为的人都可以使用它的较长版本。
首先,我们需要调查当按下鼠标按钮时,QSlider 上实际引入了什么类型的事件。然后,我们就可以实际模拟它了。为此,我们可以使用事件过滤器。为了简单起见,我们先用这个:
class QSliderAnalyser
: public QObject
{
public:
QSliderAnalyser()
{
}
virtual ~QSliderAnalyser()
{
}
protected:
bool eventFilter(QObject* object, QEvent* event) override
{
qDebug() << event->type();
return QObject::eventFilter(object, event);
}
};
然后,我们在您的 QSlider 实例上安装此过滤器:
// Just keep in mind that memory is not managed in correct way here, and you should ensure proper cleanup of your elements on destruction.
ui->horizontalSlider->installEventFilter(new QSliderAnalyser());
在运行一个应用程序之后,我们可以看到很多各种各样的事件。示例如下(在与 QSlider 实例进行几次交互之后):
QEvent::Type(HoverMove)
QEvent::Type(HoverMove)
QEvent::Type(HoverMove)
QEvent::Type(HoverMove)
QEvent::Type(MouseButtonPress)
QEvent::Type(Paint)
QEvent::Type(MouseButtonRelease)
QEvent::Type(Paint)
QEvent::Type(HoverMove)
这里最有趣的部分如下:QEvent::Type(MouseButtonPress) 和 QEvent::Type(MouseButtonRelease)。换句话说,QMouseEvent from different type is being simulated. Up to this point, you have probably understood yourself what to send, i.e. you already try to send correct events. However, maybe parameters are wrong? It might be so. So, let's take a look into QMouseEvent class 构造函数参数:
QMouseEvent(QEvent::Type type, const QPointF &localPos, const QPointF &windowPos, const QPointF &screenPos, Qt::MouseButton button, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Qt::MouseEventSource source)
基于参数最多的构造函数,我们可以推断出上面的事件过滤器可以按以下方式稍微重写:
// Change "qDebug() << event->type();" to the following code.
if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease)
{
auto mouseEvent = static_cast<QMouseEvent*>(event);
qDebug() << mouseEvent->type();
qDebug() << mouseEvent->localPos();
qDebug() << mouseEvent->windowPos();
qDebug() << mouseEvent->screenPos();
qDebug() << mouseEvent->button();
qDebug() << mouseEvent->buttons();
qDebug() << mouseEvent->modifiers();
qDebug() << mouseEvent->source();
}
再次 运行 应用程序后,在我的设备上相应地显示鼠标按钮按下和释放事件的以下值:
QEvent::Type(MouseButtonPress)
QPointF(37,8)
QPointF(67,160)
QPointF(2747,550)
1
QFlags<Qt::MouseButtons>(LeftButton)
QFlags<Qt::KeyboardModifiers>(NoModifier)
Qt::MouseEventSource(MouseEventNotSynthesized)
QEvent::Type(MouseButtonRelease)
QPointF(37,8)
QPointF(67,160)
QPointF(2747,550)
1
QFlags<Qt::MouseButtons>(NoButton)
QFlags<Qt::KeyboardModifiers>(NoModifier)
Qt::MouseEventSource(MouseEventNotSynthesized)
那么,这里可以做什么?我认为我们可以尝试尽可能准确地模拟事件,然后一个一个地删除值,以查看将被处理为希望从 Qt 观察到的行为的最小所需事件。因此,最初可能会使用以下代码:
QMouseEvent mousePressEvent(QEvent::MouseButtonPress, QPoint(37, 8), QPoint(67, 160), QPoint(2747, 550), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier, Qt::MouseEventNotSynthesized);
QMouseEvent mouseReleaseEvent(QEvent::MouseButtonPress, QPoint(37, 8), QPoint(67, 160), QPoint(2747, 550), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier, Qt::MouseEventNotSynthesized);
QCoreApplication::sendEvent((QObject*)ui->horizontalSlider, &mousePressEvent);
QCoreApplication::sendEvent((QObject*)ui->horizontalSlider, &mouseReleaseEvent);
经过一些观察,我们可以得出以下结论:
- 不需要屏幕位置。
- Window位置也不需要。
- 也不需要鼠标事件源。
- 您没有义务使用鼠标按钮按下和释放事件。您可以按下或松开鼠标。 Qt 甚至会处理这种类型的行为。
- 基本上,需要的是以下内容:鼠标事件类型(即按下和释放)、本地位置、已按下和释放的按钮以及键盘修饰符。
因此,代码可以通过以下方式重写并且仍然有效:
// Option One
QMouseEvent mousePressEvent(QEvent::MouseButtonPress, QPoint(50, 5), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
QMouseEvent mouseReleaseEvent(QEvent::MouseButtonPress, QPoint(50, 5), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
QCoreApplication::sendEvent(ui->horizontalSlider, &mousePressEvent);
QCoreApplication::sendEvent(ui->horizontalSlider, &mouseReleaseEvent);
// Option Two
QMouseEvent mousePressEvent(QEvent::MouseButtonPress, QPoint(50, 5), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
QCoreApplication::sendEvent(ui->horizontalSlider, &mousePressEvent);
// Option Three
QMouseEvent mousePressEvent(QEvent::MouseButtonPress, QPoint(50, 5), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
QCoreApplication::sendEvent(ui->horizontalSlider, &mousePressEvent);
因此,我展示了如何推断 Qt 在小部件上处理的行为会导致什么类型的事件的可能性。希望我的回答足够清楚和有帮助。
我正在尝试使用
模拟鼠标在我的小部件上的点击QCoreApplication::sendEvent();
它适用于 QPushButton 和其他一些组件。
对于 QSlider,(设计器中的水平滑块)我尝试了下面的代码,但它不起作用。
QMouseEvent mousePressEvent(QEvent::MouseButtonPress,QPoint(50, 5), Qt::LeftButton, 0, 0);
QCoreApplication::sendEvent((QObject*)ui->horizontalSlider, &mousePressEvent);
QMouseEvent mouseReleaseEvent(QEvent::MouseButtonRelease, QPoint(50, 5), Qt::LeftButton, 0, 0);
QCoreApplication::sendEvent((QObject*)ui->horizontalSlider, &mouseReleaseEvent);
但使用 QTest 时效果很好。
QTest::mouseClick(ui->horizontalSlider, Qt::LeftButton, Qt::NoModifier, QPoint(50, 5));
任何纠正相同问题的建议都会有很大帮助。提前致谢。
简短的回答如下:
// The following code should be changed
QMouseEvent mousePressEvent(QEvent::MouseButtonPress,QPoint(50, 5), Qt::LeftButton, 0, 0);
QCoreApplication::sendEvent((QObject*)ui->horizontalSlider, &mousePressEvent);
QMouseEvent mouseReleaseEvent(QEvent::MouseButtonRelease, QPoint(50, 5), Qt::LeftButton, 0, 0);
QCoreApplication::sendEvent((QObject*)ui->horizontalSlider, &mouseReleaseEvent);
// To the following one. Also, note that (QObject*) is not necessary, since QSlider is in the hierarchy with QObject, i.e. QObject is ancestor for the QSlider.
QMouseEvent mousePressEvent(QEvent::MouseButtonPress,QPoint(50, 5), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
QCoreApplication::sendEvent(ui->horizontalSlider, &mousePressEvent);
QMouseEvent mouseReleaseEvent(QEvent::MouseButtonRelease, QPoint(50, 5), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
QCoreApplication::sendEvent(ui->horizontalSlider, &mouseReleaseEvent);
这将是简短的回答。任何想要推断需要使用哪些事件来模拟 Qt 元素上的某种行为的人都可以使用它的较长版本。
首先,我们需要调查当按下鼠标按钮时,QSlider 上实际引入了什么类型的事件。然后,我们就可以实际模拟它了。为此,我们可以使用事件过滤器。为了简单起见,我们先用这个:
class QSliderAnalyser
: public QObject
{
public:
QSliderAnalyser()
{
}
virtual ~QSliderAnalyser()
{
}
protected:
bool eventFilter(QObject* object, QEvent* event) override
{
qDebug() << event->type();
return QObject::eventFilter(object, event);
}
};
然后,我们在您的 QSlider 实例上安装此过滤器:
// Just keep in mind that memory is not managed in correct way here, and you should ensure proper cleanup of your elements on destruction.
ui->horizontalSlider->installEventFilter(new QSliderAnalyser());
在运行一个应用程序之后,我们可以看到很多各种各样的事件。示例如下(在与 QSlider 实例进行几次交互之后):
QEvent::Type(HoverMove)
QEvent::Type(HoverMove)
QEvent::Type(HoverMove)
QEvent::Type(HoverMove)
QEvent::Type(MouseButtonPress)
QEvent::Type(Paint)
QEvent::Type(MouseButtonRelease)
QEvent::Type(Paint)
QEvent::Type(HoverMove)
这里最有趣的部分如下:QEvent::Type(MouseButtonPress) 和 QEvent::Type(MouseButtonRelease)。换句话说,QMouseEvent from different type is being simulated. Up to this point, you have probably understood yourself what to send, i.e. you already try to send correct events. However, maybe parameters are wrong? It might be so. So, let's take a look into QMouseEvent class 构造函数参数:
QMouseEvent(QEvent::Type type, const QPointF &localPos, const QPointF &windowPos, const QPointF &screenPos, Qt::MouseButton button, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Qt::MouseEventSource source)
基于参数最多的构造函数,我们可以推断出上面的事件过滤器可以按以下方式稍微重写:
// Change "qDebug() << event->type();" to the following code.
if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease)
{
auto mouseEvent = static_cast<QMouseEvent*>(event);
qDebug() << mouseEvent->type();
qDebug() << mouseEvent->localPos();
qDebug() << mouseEvent->windowPos();
qDebug() << mouseEvent->screenPos();
qDebug() << mouseEvent->button();
qDebug() << mouseEvent->buttons();
qDebug() << mouseEvent->modifiers();
qDebug() << mouseEvent->source();
}
再次 运行 应用程序后,在我的设备上相应地显示鼠标按钮按下和释放事件的以下值:
QEvent::Type(MouseButtonPress)
QPointF(37,8)
QPointF(67,160)
QPointF(2747,550)
1
QFlags<Qt::MouseButtons>(LeftButton)
QFlags<Qt::KeyboardModifiers>(NoModifier)
Qt::MouseEventSource(MouseEventNotSynthesized)
QEvent::Type(MouseButtonRelease)
QPointF(37,8)
QPointF(67,160)
QPointF(2747,550)
1
QFlags<Qt::MouseButtons>(NoButton)
QFlags<Qt::KeyboardModifiers>(NoModifier)
Qt::MouseEventSource(MouseEventNotSynthesized)
那么,这里可以做什么?我认为我们可以尝试尽可能准确地模拟事件,然后一个一个地删除值,以查看将被处理为希望从 Qt 观察到的行为的最小所需事件。因此,最初可能会使用以下代码:
QMouseEvent mousePressEvent(QEvent::MouseButtonPress, QPoint(37, 8), QPoint(67, 160), QPoint(2747, 550), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier, Qt::MouseEventNotSynthesized);
QMouseEvent mouseReleaseEvent(QEvent::MouseButtonPress, QPoint(37, 8), QPoint(67, 160), QPoint(2747, 550), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier, Qt::MouseEventNotSynthesized);
QCoreApplication::sendEvent((QObject*)ui->horizontalSlider, &mousePressEvent);
QCoreApplication::sendEvent((QObject*)ui->horizontalSlider, &mouseReleaseEvent);
经过一些观察,我们可以得出以下结论:
- 不需要屏幕位置。
- Window位置也不需要。
- 也不需要鼠标事件源。
- 您没有义务使用鼠标按钮按下和释放事件。您可以按下或松开鼠标。 Qt 甚至会处理这种类型的行为。
- 基本上,需要的是以下内容:鼠标事件类型(即按下和释放)、本地位置、已按下和释放的按钮以及键盘修饰符。
因此,代码可以通过以下方式重写并且仍然有效:
// Option One
QMouseEvent mousePressEvent(QEvent::MouseButtonPress, QPoint(50, 5), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
QMouseEvent mouseReleaseEvent(QEvent::MouseButtonPress, QPoint(50, 5), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
QCoreApplication::sendEvent(ui->horizontalSlider, &mousePressEvent);
QCoreApplication::sendEvent(ui->horizontalSlider, &mouseReleaseEvent);
// Option Two
QMouseEvent mousePressEvent(QEvent::MouseButtonPress, QPoint(50, 5), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
QCoreApplication::sendEvent(ui->horizontalSlider, &mousePressEvent);
// Option Three
QMouseEvent mousePressEvent(QEvent::MouseButtonPress, QPoint(50, 5), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
QCoreApplication::sendEvent(ui->horizontalSlider, &mousePressEvent);
因此,我展示了如何推断 Qt 在小部件上处理的行为会导致什么类型的事件的可能性。希望我的回答足够清楚和有帮助。