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

    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

    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

    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

    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

    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.

Log in to reply

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.