cisco-open-source / qtwebdriver

WebDriver implementation for Qt
https://github.com/cisco-open-source/qtwebdriver/wiki
197 stars 59 forks source link

Clicking on a QTreeWidgetItem in a QTreeWidget. Possible? #48

Open rdoreopto opened 7 years ago

rdoreopto commented 7 years ago

Qt version: 4.8.7 OS: Ubuntu 16.04 Xenial

Hello,

I'm using QtWebDriver to test a native application (the webdriver attaches to the running application). It has been working great so far, but I've encountered a little problem.

I have have widget which contains a QTreeWidget, here is the XML that QtWebDriver generates:

<MyCustomWidget elementId="5a5b4c697d268f814260408902c33bda" className="MyCustomWidget ">
    <QTreeWidget id="MyTreeWidgetQTreeWidget" elementId="d1719b0bdc33b4c02b69c0a89267ca50" className="QTreeWidget">
        <QWidget id="qt_scrollarea_viewport" elementId="41e05ce2f311319257d2653e128a16af" className="QWidget"/>
        <QWidget id="qt_scrollarea_hcontainer" elementId="e919572cc62b8a0cb3a3e460a30084ec" className="QWidget">
            <QScrollBar elementId="58570ed03634f7c827c720e0b22eda09" className="QScrollBar"/>
        </QWidget>
        <QHeaderView elementId="72b123c782f0c9eb88f0ae6074bef7aa" className="QHeaderView">
            <QWidget id="qt_scrollarea_viewport" elementId="fd49cd33f548e015891c038a685ffa4b" className="QWidget">
                <QLabel elementId="7ee05aee0c0640fc8ce121569754c7b2" className="QLabel"/>
            </QWidget>
            <QWidget id="qt_scrollarea_hcontainer" elementId="7fdcec38953342a4b0fdef4d4d1bc2cc" className="QWidget">
                <QScrollBar elementId="5ccf21cb866a136aa56fc5c49c571bbd" className="QScrollBar"/>
            </QWidget>
            <QWidget id="qt_scrollarea_vcontainer" elementId="c9fa0e923546654fc85655bc5845aa4a" className="QWidget">
                <QScrollBar elementId="63b8b312790f14d78497396b390c7267" className="QScrollBar"/>
            </QWidget>
        </QHeaderView>
        <QWidget id="qt_scrollarea_vcontainer" elementId="c694cb6e70812014b5fdc15db948ef3d" className="QWidget">
            <QScrollBar elementId="92c2797ea839dfce687ce6037ebfe2c1" className="QScrollBar"/>
        </QWidget>
    </QTreeWidget>
    <QPushButton elementId="b0916b08818d038e2c9fc625cf98bf09" className="QPushButton"/>
    <QPushButton elementId="7d07fb888bd170a164f00e2516de3f87" className="QPushButton"/>
</MyCustomWidget >

What I would like to do is click on an item in the QTreeWidget. Is it possible (or could it be made possible)?

Thank you very much!

Raphael

hekra01 commented 7 years ago

Hi,

Yes no support for QTreeWidget at this time. Maybe it could be worked around by combining some click/tab events, bu t still a workaround. Proper support will require a bit of work. (If anyone wants to submit a pull request for this it will be welcome: check how support for QAction was added).

Regards,

hekra01 commented 7 years ago

https://github.com/cisco-open-source/qtwebdriver/pull/50

rdoreopto commented 7 years ago

Indeed, #50 is the best workaround I've found, because QTreeWidgetItem does not contain a real widget, it's all in the data member. I'm not sure how Qt renders the tree item on screen, but we don't have access to that (the only exception here is if a widget was specifically added with http://doc.qt.io/qt-4.8/qtreewidget.html#setItemWidget). It's the same thing with the QListWidget.

rdoreopto commented 7 years ago

But, if a QListWidget or QTreeWidget does indeed contain one or more itemWidgets, then it would be easy to do this:

diff --git a/src/webdriver/extension_qt/widget_view_util.cc b/src/webdriver/extension_qt/widget_view_util.cc
index 7b234f2..5db6ef6 100644
--- a/src/webdriver/extension_qt/widget_view_util.cc
+++ b/src/webdriver/extension_qt/widget_view_util.cc
@@ -25,6 +25,14 @@

 #include <QtCore/QMetaProperty>

+#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
+#include <QtWidgets/QListView>
+#include <QtWidgets/QListWidgetItem>
+#else
+#include <QtGui/QListView>
+#include <QtGui/QListWidgetItem>
+#endif
+
 namespace webdriver {

 const char QWidgetViewUtil::url_protocol[] = "qtwidget://";
@@ -126,6 +134,22 @@ void QWidgetXmlSerializer::addWidget(QObject* widget) {
         writer_.writeEndElement();
     }

+    QListWidget* listView = qobject_cast<QListWidget*>(pWidget);
+    // widget is a QListWidget*
+    if (NULL != listView) {
+        for (int i = 0; i < listView->count(); ++i) {
+            QListWidgetItem* listItem = listView->item(i);
+            QWidget * listItemWidget = listView->itemWidget(listItem);
+
+            if(!listItemWidget) {
+                // The item at this index is not an item widget, thus we skip it.
+                continue;
+            }
+
+            addWidget(listItemWidget);
+        }
+    }
+
     // write child widgets 
     QList<QObject*> childs = pWidget->children();
     foreach(QObject* child, childs) {

This is just an example for the QListWidget. For a QTreeWidget it would be pretty similar (although there would be some sort of tree traversal).