Unsolved Pressing Child Widgets
-
Ok i have the following:
A Class
Minefield
which hasCells
as Childs.class Minefield : public QWidget { Q_OBJECT //.... private: QVector<Cell *> mCells; CellInputHandler *mCellInputHandler;
All Clicks etc get handled from
CellInputHandler
which is a child as well:// In Minefield Constructor: for(auto &cell : mCells) { cell->installEventFilter(mCellInputHandler); }
Now i want to click on a Cell to test if a signal gets emitted. I have a test like this:
QVector<Cell *> cells; cells << new Cell{ Cell::State::empty }; cells << new Cell{ Cell::State::mine }; cells << new Cell{ Cell::State::mine }; cells << new Cell{ Cell::State::empty }; constexpr auto height = 2; constexpr auto width = 2; auto cellWidth = cells[0]->width(); auto cellHeight = cells[0]->height(); Minefield obj{ cells, width, height }; QSignalSpy spy(&obj, &Minefield::uncoveredFirstCell); QPoint pos = {obj.pos().x() + cellWidth/2, obj.pos().y() + cellHeight/2}; auto child = obj.childAt(pos); // I checked here that theres actually a child QTest::mousePress(&obj, Qt::LeftButton, Qt::NoModifier, pos); QTest::qWait(delayClickRightAndLeftTogether); QTest::mouseRelease(&obj, Qt::LeftButton, Qt::NoModifier, pos); QCOMPARE(spy.count(), 1);
So theres a
Cell
atpos
. But why i cannot click from the Parent like this:QTest::mousePress(&obj, Qt::LeftButton, Qt::NoModifier, pos); QTest::qWait(delayClickRightAndLeftTogether); QTest::mouseRelease(&obj, Qt::LeftButton, Qt::NoModifier, pos);
I checked with the debugger any event code from the
CellInputHandler
is never hit.I already tested the
Cell
class alone together with itsCellInputHandler
and could always click on aCell
like this. -
I override for test
mousePressEvent
ofMinefield
:void Minefield::mousePressEvent(QMouseEvent *event) { QWidget::mousePressEvent(event); }
I can see in the Debugger that it jumps into the
mousePressEvent
when I do the press the test.Then I would expect it would hit the installed Event filter
CellInputHandler
but it never happens:bool CellInputHandler::eventFilter(QObject *watched, QEvent *event) { if(event->type() == QEvent::MouseButtonPress){ handleMouseButtonPressEvents(watched, event); return true; } if(event->type() == QEvent::MouseButtonRelease){ handleMouseButtonReleaseEvents(watched, event); return true; } if(event->type() == QEvent::MouseMove) { handleMouseMoveEvents(event); return true; } return false; }
So in short I expect the following:
Clicking on
Minefield
at thepos
were is aCell
.
Minefield
forwards the event toCell
. SinceCell
has a event filter installed it should forward to it.But it does not happen. Why?
-
@sandro4912 said in Pressing Child Widgets:
QTest::mousePress
hi
It's only when using the QTest function the event filter is not triggered ?
Meaning, actual real clicking on it work as expected ?My guess would be that QTest::mouseXXX synthesizes the corresponding Qt event directly and also send it directly to the widget you give as the parameter. However, i didnt check the source code if that is indeed the case.
-
yes the application works if i run it as expected. i just wanted to add tests to verify. Maybe its a good idea to investigate the source code of the test framework for mouse press.
-
The Code for the mousepress can be found here:
https://code.woboq.org/qt5/qtbase/src/testlib/qtestmouse.h.html
It looks like they use a class
QWindowSystemInterface
to handle all the mouse events.Is there annother way to simulate a click on the widget?