Я работаю над приложением, использующим библиотеку 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;
я получил правда в результате. Так что я могу ссылаться только на предметы.
Мой вопрос: Как правильно ссылаться на подпункты?
Когда вы пытаетесь получить доступ к элементам модели по индексу строки, модель возвращает элемент верхнего уровня в этой строке. использование itemFromIndex
вместо:
auto item = index.model()->itemFromIndex(index);
if (item && item->hasChildren()){
// item is not a leaf
}
РЕДАКТИРОВАТЬ index.model()
возвращается QAbstractItemModel*
Таким образом, приведение также необходимо здесь (или, что лучше, хранить указатель на стандартную модель где-то в коде).
Вы не можете отключить сигнал для подпунктов. Однако вы можете проверить, есть ли у элемента родительский элемент. Это не так, это предмет, и если это так, то это подпункт.
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")
...
Я бы сделал это так:
// 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;