QGroupBox: Send unhandled mouse events to parent widget
Every other subclass of QWidget calls event->ignore() on unhandled events, and QGroupBox's failure to follow this convention prevented it from being used in some specialized applications. Instances of QGroupBox now only absorb mouse press events to their checkboxes (if they have checkboxes) and ignore all other mouse events. Task-number: QTBUG-15519 Change-Id: I6b0c89c92868feddbe3888088703b32cb95d9903 Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
This commit is contained in:
parent
9129d2714a
commit
4ac94480c3
@ -707,6 +707,8 @@ void QGroupBox::mousePressEvent(QMouseEvent *event)
|
||||
if (d->checkable && (d->pressedControl & (QStyle::SC_GroupBoxCheckBox | QStyle::SC_GroupBoxLabel))) {
|
||||
d->overCheckBox = true;
|
||||
update(style()->subControlRect(QStyle::CC_GroupBox, &box, QStyle::SC_GroupBoxCheckBox, this));
|
||||
} else {
|
||||
event->ignore();
|
||||
}
|
||||
}
|
||||
|
||||
@ -723,6 +725,8 @@ void QGroupBox::mouseMoveEvent(QMouseEvent *event)
|
||||
if (d->checkable && (d->pressedControl == QStyle::SC_GroupBoxCheckBox || d->pressedControl == QStyle::SC_GroupBoxLabel)
|
||||
&& (d->overCheckBox != oldOverCheckBox))
|
||||
update(style()->subControlRect(QStyle::CC_GroupBox, &box, QStyle::SC_GroupBoxCheckBox, this));
|
||||
|
||||
event->ignore();
|
||||
}
|
||||
|
||||
/*! \reimp */
|
||||
|
@ -73,6 +73,7 @@ private slots:
|
||||
void childrenAreDisabled();
|
||||
void propagateFocus();
|
||||
void task_QTBUG_19170_ignoreMouseReleseEvent();
|
||||
void task_QTBUG_15519_propagateMouseEvents();
|
||||
|
||||
private:
|
||||
bool checked;
|
||||
@ -80,6 +81,7 @@ private:
|
||||
qint64 clickTimeStamp;
|
||||
qint64 toggleTimeStamp;
|
||||
|
||||
static void sendMouseMoveEvent(QWidget *widget, const QPoint &localPos);
|
||||
};
|
||||
|
||||
tst_QGroupBox::tst_QGroupBox()
|
||||
@ -502,5 +504,114 @@ void tst_QGroupBox::task_QTBUG_19170_ignoreMouseReleseEvent()
|
||||
QCOMPARE(box.isChecked(), false);
|
||||
}
|
||||
|
||||
class MouseEventTestWidget : public QWidget
|
||||
{
|
||||
public:
|
||||
bool mousePressed;
|
||||
bool mouseReleased;
|
||||
bool mouseMoved;
|
||||
|
||||
void reset()
|
||||
{
|
||||
mousePressed = false;
|
||||
mouseReleased = false;
|
||||
mouseMoved = false;
|
||||
}
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent*)
|
||||
{
|
||||
mousePressed = true;
|
||||
}
|
||||
|
||||
void mouseReleaseEvent(QMouseEvent*)
|
||||
{
|
||||
mouseReleased = true;
|
||||
}
|
||||
|
||||
void mouseMoveEvent(QMouseEvent*)
|
||||
{
|
||||
mouseMoved = true;
|
||||
}
|
||||
};
|
||||
|
||||
void tst_QGroupBox::task_QTBUG_15519_propagateMouseEvents()
|
||||
{
|
||||
MouseEventTestWidget parent;
|
||||
QGroupBox box(&parent);
|
||||
parent.setMouseTracking(true);
|
||||
box.setMouseTracking(true);
|
||||
box.resize(100, 100);
|
||||
box.setTitle("This is a test for QTBUG-15519");
|
||||
box.show();
|
||||
|
||||
QStyleOptionGroupBox option;
|
||||
option.initFrom(&box);
|
||||
option.subControls = QStyle::SubControls(QStyle::SC_All);
|
||||
QRect checkBoxRect = box.style()->subControlRect(QStyle::CC_GroupBox, &option,
|
||||
QStyle::SC_GroupBoxCheckBox, &box);
|
||||
|
||||
// Without a checkbox, all mouse events should propagate
|
||||
|
||||
parent.reset();
|
||||
QTest::mousePress(&box, Qt::LeftButton, 0, checkBoxRect.center());
|
||||
QCOMPARE(parent.mousePressed, true);
|
||||
|
||||
parent.reset();
|
||||
QTest::mousePress(&box, Qt::LeftButton, 0, box.rect().center());
|
||||
QCOMPARE(parent.mousePressed, true);
|
||||
|
||||
parent.reset();
|
||||
QTest::mouseRelease(&box, Qt::LeftButton, 0, checkBoxRect.center());
|
||||
QCOMPARE(parent.mouseReleased, true);
|
||||
|
||||
parent.reset();
|
||||
QTest::mouseRelease(&box, Qt::LeftButton, 0, box.rect().center());
|
||||
QCOMPARE(parent.mouseReleased, true);
|
||||
|
||||
parent.reset();
|
||||
sendMouseMoveEvent(&box, checkBoxRect.center());
|
||||
QCOMPARE(parent.mouseMoved, true);
|
||||
|
||||
parent.reset();
|
||||
sendMouseMoveEvent(&box, box.rect().center());
|
||||
QCOMPARE(parent.mouseMoved, true);
|
||||
|
||||
// With a checkbox, presses and releases to the checkbox should not propagate
|
||||
|
||||
box.setCheckable(true);
|
||||
|
||||
parent.reset();
|
||||
QTest::mousePress(&box, Qt::LeftButton, 0, checkBoxRect.center());
|
||||
QCOMPARE(parent.mousePressed, false);
|
||||
|
||||
parent.reset();
|
||||
QTest::mousePress(&box, Qt::LeftButton, 0, box.rect().center());
|
||||
QCOMPARE(parent.mousePressed, true);
|
||||
|
||||
parent.reset();
|
||||
QTest::mouseRelease(&box, Qt::LeftButton, 0, checkBoxRect.center());
|
||||
QCOMPARE(parent.mouseReleased, false);
|
||||
|
||||
parent.reset();
|
||||
QTest::mouseRelease(&box, Qt::LeftButton, 0, box.rect().center());
|
||||
QCOMPARE(parent.mouseReleased, true);
|
||||
|
||||
parent.reset();
|
||||
sendMouseMoveEvent(&box, checkBoxRect.center());
|
||||
QCOMPARE(parent.mouseMoved, true);
|
||||
|
||||
parent.reset();
|
||||
sendMouseMoveEvent(&box, box.rect().center());
|
||||
QCOMPARE(parent.mouseMoved, true);
|
||||
}
|
||||
|
||||
void tst_QGroupBox::sendMouseMoveEvent(QWidget *widget, const QPoint &localPos)
|
||||
{
|
||||
// Send a MouseMove event without actually moving the pointer
|
||||
QMouseEvent event(QEvent::MouseMove, localPos, Qt::NoButton, Qt::NoButton, Qt::NoModifier);
|
||||
QApplication::sendEvent(widget, &event);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QGroupBox)
|
||||
#include "tst_qgroupbox.moc"
|
||||
|
Loading…
Reference in New Issue
Block a user