Я хотел иметь древовидное представление, которое показывает имя элемента, описание элемента и два связанных логических значения в соответствующих столбцах. Я начал с изменения примера редактируемого дерева, так что есть TreeModel, который отслеживает группу TreeItems, каждый из которых имеет не только список дочерних TreeItems, но также и список QVariant, в котором хранится набор значений, которые впоследствии могут отображаться в столбцах в QTreeView.
Мне удалось добавить еще два столбца для двух логических значений. Я также искал в сети, как добавить флажки для QTreeView и QAbstractItemModel. Мне удалось установить флажки в двух логических столбцах, а также в остальной части древовидной иерархии. Тем не менее, все элементы в каждом столбце теперь отображают флажок и строку текста.
Вот части, которые я изменил из примера, в основном в TreeModel.
treemodel.cpp:
bool TreeModel::isBooleanColumn( const QModelIndex &index ) const
{
bool bRet = false;
if ( !index.isValid() )
{
}
else
{
bRet = ( index.column() == COLUMN_BOL1 ) || ( index.column() == COLUMN_ BOL2 );
}
return bRet;
}
Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const
{
if (!index.isValid())
return 0;
if ( isBooleanColumn( index ) )
{
return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable;
}
else
{
return Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
}
QVariant TreeModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if (role != Qt::DisplayRole && role != Qt::EditRole && role != Qt::CheckStateRole )
return QVariant();
TreeItem *item = getItem(index);
if ( role == Qt::CheckStateRole && isBooleanColumn( index ) )
{
Qt::CheckState eChkState = ( item->data( index.column() ).toBool() ) ? Qt::Checked : Qt::Unchecked;
return eChkState;
}
return item->data(index.column());
}
bool TreeModel::setData(const QModelIndex &index, const QVariant &value,
int role)
{
if (role != Qt::EditRole && role != Qt::CheckStateRole )
return false;
TreeItem *item = getItem(index);
bool result;
if ( role == Qt::CheckStateRole && isBooleanColumn( index ) )
{
Qt::CheckState eChecked = static_cast< Qt::CheckState >( value.toInt() );
bool bNewValue = eChecked == Qt::Checked;
result = item->setData( index.column(), bNewValue );
}
else
{
result = item->setData(index.column(), value);
}
if (result)
emit dataChanged(index, index);
return result;
}
mainwindow.cpp:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
…
QStringList headers;
headers << tr("Title") << tr("Description") << tr("Hide") << tr("Lock");
QFile file(":/default.txt");
file.open(QIODevice::ReadOnly);
TreeModel *model = new TreeModel(headers, file.readAll());
file.close();
…
}
Флажки под небулевыми столбцами не реагируют на ввод пользователя, а текст под логическими столбцами нельзя редактировать. Так что с точки зрения функциональности в этом нет ничего плохого, но это все еще утомительно с точки зрения пользовательского интерфейса.
Я перехожу к тому, чтобы QTreeWidget делал то же самое. Между тем, я не мог не задаться вопросом, есть ли что-то еще, что мне здесь не хватает. Я слышал, что одним из решений является использование собственного делегата; это единственный вариант?
Если есть кто-нибудь, кто может указать, что еще мне нужно сделать, или предоставить аналогичный пример, я буду очень признателен.