Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How to send mouse clicks to a `QTreeWidgetItem` in my test?



  • I wish to test the response of my application to mouse clicks on single QTreeWidgetItems which are configured to be user selectable.

    Objects that derive from QWidget have the click()-method, but the QTreeWidgetItem does not derive from QWidget hence doesn't have that method. Similarly, also the QTest::mouseClick() method can only act on a QWidget-derived class. So these two routes don't work.

    What route will work?


  • Qt Champions 2017

    Hello,
    QTreeWidgetItem doesn't derive from QObject at all. If they did you probably could imagine the amount of overhead it would generate for a simple table/tree widget. I think for your case, you could use the QTreeWidget::itemClicked signal.

    Kind regards.



  • @kshegunov Hej, that is a signal, so not useful for me - I want to simulate the click that eventually produces that signal.


  • Qt Champions 2017

    @Jakob
    Oh, sorry, I'm still sleeping I guess. You could invoke the signal through QMetaObject::invokeMethod by passing your widget as sender and the needed arguments. Hope that helps.

    Kind regards.



  • @kshegunov Hm, that still doesn't do it - the main issue is that simply invoking the slot, will not change the checkState of the item, which is what I need


  • Qt Champions 2017

    @Jakob
    You can change the state externally. Something like this:

    void MyClass::clickItem(QTreeWidget * widget, QPoint clickPosition, int checkableColumn)
    {
        QTreeWidgetItem * item = widget->itemAt(clickPosition);
        item->setCheckState(checkableColumn, item->checkState() == Qt::Checked ? Qt::Unchecked : Qt::Checked);
        QMetaObject::invokeMethod(widget, "itemClicked", Q_ARG(QTreeWidgetItem *, item), QARG(int, checkableColumn));
    }
    


  • Hm, I just realized the click() method is only on QAbstractButton, not on a generic QWidget. Nevertheless, I really would want to use QTest::mouseClick() to toggle the state of the checkbox of a QTreeWidgetItem.



  • @kshegunov This is indeed what I turned out doing, except that I directly call the signal - apparently that is possible ...... Still not quite what I want but what I'll stick with for now (my main issue with this approach is that this way I don't have a regression for someone erroneously changing the connect()-call)


  • Qt Champions 2017

    @Jakob
    Hmmm, I always thought that signals' access specifier is protected ... that is strange.



  • @kshegunov As it turns out, line 72 in qobjectdefs.h (Qt 5.4.0) says:

    # define Q_SIGNALS public
    

  • Qt Champions 2017

    @Jakob
    Ah, yes. From Qt4 you get:
    # define Q_SIGNALS protected
    I firmly believe that this change was made to accommodate the new way of connecting signals. I don't find it to be a great improvement, but this is a personal opinion ... In the new framework it seems every object can easily rise another object's signal, which is a bit ... hm ... suspicious ... not that it was impossible before, but you had to go the extra mile, by using the QMetaObject class.