QTreeView с QCheckBox

169
22 августа 2021, 20:30

Не понимаю как реализовать QTreeView с checkbox. Как обработать событие установки и снятия "галочки". Есть группированный неизменяемый список, в котором можно только устанавливать и снимать "галочки". Если есть предложения по улучшении, буду признателен.

Пример проекта:

#include <QApplication>
#include <QtWidgets>
struct Groups {
    QString nameType;
    int beginType;
    int endType;
};

QList<Groups> getGroups()
{
    return QList<Groups> {
        Groups{"Groups 1", 0, 3},
        Groups{"Groups 2", 3, 5},
        Groups{"Groups 3", 5, 9},
        Groups{"Groups 4", 9, 11},
        Groups{"Groups 5", 11, 12},
    };
}
class TestsModel : public QStandardItemModel
{
public:
    TestsModel(QObject *parent = nullptr);
private:
    int rowCount(const QModelIndex & = QModelIndex()) const override { return groups.size(); }
    int columnCount(const QModelIndex &) const override { return 1; }
    Qt::ItemFlags flags(const QModelIndex &index) const override;
    QVariant data(const QModelIndex &index, int role) const override;
    const QList<Groups> groups;
};
TestsModel::TestsModel(QObject *parent)
    : QStandardItemModel(parent), groups(getGroups())
{
    insertRows(0, groups.size());
    insertColumns(0, 1);
    for (int i = 0; i < groups.size(); ++i) {
        const auto &g = groups.at(i);
        QModelIndex ind = index(i, 0);
        setData(ind, "Type: " + g.nameType);
        insertRows(0, g.endType - g.beginType, ind);
        insertColumns(0, 1, ind);
        for (int nRow = 0; nRow < g.endType - g.beginType; ++nRow) {
            setData(index(nRow, 0, ind), QString("item %1").arg(g.beginType + nRow));
        }
    }
}
Qt::ItemFlags TestsModel::flags(const QModelIndex &index) const
{
    Qt::ItemFlags flags = QAbstractItemModel::flags(index);
    if (index.isValid())
        flags = Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsAutoTristate;
    return flags;
}
QVariant TestsModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid()) {
        return QVariant();
    }
    if (role == Qt::CheckStateRole) {
        return Qt::CheckState::Unchecked;
    }
    return QStandardItemModel::data(index, role);
}
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    TestsModel model;
    QTreeView tv;
    tv.setModel(&model);
    tv.show();
    return a.exec();
}
Answer 1

Вам надо добавить состояние в структуру Groups:

struct Groups {
   ...
   bool checked;
}

Далее, в модель добавить метод setData, в котором менять это состояние:

bool TestsModel::setData(const QModelIndex &index, const QVariant &value, int role) {
    ...
    if( /*Мы на уровне групп?*/ && role == Qt::CheckStateRole ) {
        groups[index.row()].check = !groups[index.row()].check;
    }
    ...
}

И, соответственно, в методе data возвращать текущее состояние:

QVariant TestsModel::data(const QModelIndex &index, int role) const
{
    ...
    if( /*Мы на уровне групп?*/ && (role == Qt::CheckStateRole)) {
        return groups.at(index.row()).check;
    }
    return QStandardItemModel::data(index, role);
}
READ ALSO
Как получить сообщение всем потокам?

Как получить сообщение всем потокам?

Например я получаю из очереди сообщение и хочу его разослать всем потокамЯ думал про общую память, но вроде вдруг не все потоки успеют использовать...

139
аналог unix socket в windows

аналог unix socket в windows

Есть ли аналог unix socket в windows? Типа такого как в линукс и unix

126
Как заменить символ в строке?

Как заменить символ в строке?

Задача: Надо написать функцию который находит в строке цифры и заменяет их на десятичные кодыНапример "aaa'6'xxx" на "aaa54xxx"

84
Ошибка подключения клиента к серверу TCP/IP

Ошибка подключения клиента к серверу TCP/IP

не могу создать соединение между сервером и клиентом по tcp/ip на Linux MintКомпилирую через gcc

158