Как получить доступ к childWidgets в QTreeView, используя QModelIndex?

Я работаю над приложением, использующим библиотеку Qt (версия 4.8).

У меня есть QTreeView с QStandardItemModel. Мой виджет выглядит так:

Элемент1

subitem11

subitem12

Элемент2

subitem21

subitem22

Item3

subitem31

subitem32

Вот как я могу добавить элементы в мой QTreeView:

 model->setItem(0, 0, item1);
item1->setChild(0, 0, subitem12);

Я хочу выполнить действие, только когда пользователь дважды щелкнул элемент (и ничего не сделал, когда щелкнул элемент). Поэтому я использую doubleClicked (const QModelIndex & индекс) сигнал.

Я хочу обработать информацию об элементе / подпункте, который пользователь дважды щелкнул. Итак, я получаю строку моего элемента / подпункта:

index.row();

Но каждый раз, когда я пытаюсь сослаться на элемент / подпункт, чтобы отобразить его имя или проверить, есть ли у него дочерние элементы, я могу получить доступ только к элементам:

index.model()->item(row)->text();

Мой вопрос: как я могу получить доступ к подэлементам (vbetween items abd subitems) в моем слоте? Или как я могу предотвратить их излучение сигнала? Я не могу их отключить — это будет слишком запутанно для пользователя.

Редактировать: Проблема в том, что каждый раз, когда я нажимаю на элемент или подпункт и выполняю:

index.model()->item(row)->hasChildren();

или же:

index.model()->item(row)->parent() == 0;

я получил правда в результате. Так что я могу ссылаться только на предметы.

Мой вопрос: Как правильно ссылаться на подпункты?

2

Решение

Когда вы пытаетесь получить доступ к элементам модели по индексу строки, модель возвращает элемент верхнего уровня в этой строке. использование itemFromIndex вместо:

auto item = index.model()->itemFromIndex(index);
if (item && item->hasChildren()){
// item is not a leaf
}

РЕДАКТИРОВАТЬ index.model() возвращается QAbstractItemModel*Таким образом, приведение также необходимо здесь (или, что лучше, хранить указатель на стандартную модель где-то в коде).

2

Другие решения

Вы не можете отключить сигнал для подпунктов. Однако вы можете проверить, есть ли у элемента родительский элемент. Это не так, это предмет, и если это так, то это подпункт.

if (item->parent() != 0)
.. //subitem
else
.. //item

В качестве альтернативы можно использовать функцию data (), чтобы установить какое-то специальное значение для различия между ними.

item1->setData(QVariant("item"));
subitem1->setData(QVariant("subitem"));

Затем запросите значение в вашем обработчике двойного клика:

QVariant var = item->data();
if (var.toString() == "item")
...
else if (var.toString() == "subitem")
...
0

Я бы сделал это так:

// Define your custom role to store item type.
enum MyRoles
{
ItemTypeRole = Qt::UserRole + 1
};

// Define item types.
enum ItemType
{
Primary,
Secondary
};

Чем установить правильный тип элемента для всех ваших предметов:

QStandardItem* item = new QStandardItem("Item1");
item->setData(Primary, ItemTypeRole);

QStandardItem* subItem = new QStandardItem("SubItem1");
subItem->setData(Secondary, ItemTypeRole);

И в вашем слоте, подключенном к двойной клик Сигнал получает доступ к типу, как это:

ItemType type = static_cast<ItemType>(index.data(ItemTypeRole).toInt());
if (type == Primary)
std::cout << "It's a Primary item!" << std::endl;
else if (type == Secondary)
std::cout << "It's a Secondary item!" << std::endl;
0